diff options
Diffstat (limited to 'include/clang')
558 files changed, 16451 insertions, 6465 deletions
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h index 30c24f1cdb10..49e94a92cd0b 100644 --- a/include/clang/ARCMigrate/ARCMT.h +++ b/include/clang/ARCMigrate/ARCMT.h @@ -1,9 +1,8 @@ //===-- ARCMT.h - ARC Migration Rewriter ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h index 2571ca75be51..641c259b3867 100644 --- a/include/clang/ARCMigrate/ARCMTActions.h +++ b/include/clang/ARCMigrate/ARCMTActions.h @@ -1,9 +1,8 @@ //===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h index 731307f24e22..76b65b2f6884 100644 --- a/include/clang/ARCMigrate/FileRemapper.h +++ b/include/clang/ARCMigrate/FileRemapper.h @@ -1,9 +1,8 @@ //===-- FileRemapper.h - File Remapping Helper ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index d4057c9da5f3..6943479831ec 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -1,9 +1,8 @@ //===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,6 +13,7 @@ #ifndef LLVM_CLANG_AST_APVALUE_H #define LLVM_CLANG_AST_APVALUE_H +#include "clang/Basic/FixedPoint.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" @@ -24,14 +24,52 @@ namespace clang { class AddrLabelExpr; class ASTContext; class CharUnits; + class CXXRecordDecl; + class Decl; class DiagnosticBuilder; class Expr; class FieldDecl; - class Decl; + struct PrintingPolicy; + class Type; class ValueDecl; - class CXXRecordDecl; - class QualType; +/// Symbolic representation of typeid(T) for some type T. +class TypeInfoLValue { + const Type *T; + +public: + TypeInfoLValue() : T() {} + explicit TypeInfoLValue(const Type *T); + + const Type *getType() const { return T; } + explicit operator bool() const { return T; } + + void *getOpaqueValue() { return const_cast<Type*>(T); } + static TypeInfoLValue getFromOpaqueValue(void *Value) { + TypeInfoLValue V; + V.T = reinterpret_cast<const Type*>(Value); + return V; + } + + void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const; +}; +} + +namespace llvm { +template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> { + static void *getAsVoidPointer(clang::TypeInfoLValue V) { + return V.getOpaqueValue(); + } + static clang::TypeInfoLValue getFromVoidPointer(void *P) { + return clang::TypeInfoLValue::getFromOpaqueValue(P); + } + // Validated by static_assert in APValue.cpp; hardcoded to avoid needing + // to include Type.h. + static constexpr int NumLowBitsAvailable = 3; +}; +} + +namespace clang { /// APValue - This class implements a discriminated union of [uninitialized] /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], /// [Vector: N * APValue], [Array: N * APValue] @@ -40,9 +78,13 @@ class APValue { typedef llvm::APFloat APFloat; public: enum ValueKind { - Uninitialized, + /// There is no such object (it's outside its lifetime). + None, + /// This object has an indeterminate value (C++ [basic.indet]). + Indeterminate, Int, Float, + FixedPoint, ComplexInt, ComplexFloat, LValue, @@ -55,14 +97,14 @@ public: }; class LValueBase { - public: - typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy; + typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue> + PtrTy; - LValueBase() : CallIndex(0), Version(0) {} - - template <class T> - LValueBase(T P, unsigned I = 0, unsigned V = 0) - : Ptr(P), CallIndex(I), Version(V) {} + public: + LValueBase() : Local{} {} + LValueBase(const ValueDecl *P, unsigned I = 0, unsigned V = 0); + LValueBase(const Expr *P, unsigned I = 0, unsigned V = 0); + static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo); template <class T> bool is() const { return Ptr.is<T>(); } @@ -77,45 +119,73 @@ public: bool isNull() const; - explicit operator bool () const; + explicit operator bool() const; - PtrTy getPointer() const { - return Ptr; - } + unsigned getCallIndex() const; + unsigned getVersion() const; + QualType getTypeInfoType() const; - unsigned getCallIndex() const { - return CallIndex; - } - - void setCallIndex(unsigned Index) { - CallIndex = Index; - } - - unsigned getVersion() const { - return Version; - } - - bool operator==(const LValueBase &Other) const { - return Ptr == Other.Ptr && CallIndex == Other.CallIndex && - Version == Other.Version; + friend bool operator==(const LValueBase &LHS, const LValueBase &RHS); + friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) { + return !(LHS == RHS); } + friend llvm::hash_code hash_value(const LValueBase &Base); private: PtrTy Ptr; - unsigned CallIndex, Version; + struct LocalState { + unsigned CallIndex, Version; + }; + union { + LocalState Local; + /// The type std::type_info, if this is a TypeInfoLValue. + void *TypeInfoType; + }; }; + /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we + /// mean a virtual or non-virtual base class subobject. typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType; - union LValuePathEntry { - /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item - /// in the path. An opaque value of type BaseOrMemberType. - void *BaseOrMember; - /// ArrayIndex - The array index of the next item in the path. - uint64_t ArrayIndex; + + /// A non-discriminated union of a base, field, or array index. + class LValuePathEntry { + static_assert(sizeof(uintptr_t) <= sizeof(uint64_t), + "pointer doesn't fit in 64 bits?"); + uint64_t Value; + + public: + LValuePathEntry() : Value() {} + LValuePathEntry(BaseOrMemberType BaseOrMember) + : Value{reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue())} {} + static LValuePathEntry ArrayIndex(uint64_t Index) { + LValuePathEntry Result; + Result.Value = Index; + return Result; + } + + BaseOrMemberType getAsBaseOrMember() const { + return BaseOrMemberType::getFromOpaqueValue( + reinterpret_cast<void *>(Value)); + } + uint64_t getAsArrayIndex() const { return Value; } + + friend bool operator==(LValuePathEntry A, LValuePathEntry B) { + return A.Value == B.Value; + } + friend bool operator!=(LValuePathEntry A, LValuePathEntry B) { + return A.Value != B.Value; + } + friend llvm::hash_code hash_value(LValuePathEntry A) { + return llvm::hash_value(A.Value); + } }; struct NoLValuePath {}; struct UninitArray {}; struct UninitStruct {}; + + friend class ASTReader; + friend class ASTWriter; + private: ValueKind Kind; @@ -168,55 +238,64 @@ private: DataType Data; public: - APValue() : Kind(Uninitialized) {} - explicit APValue(APSInt I) : Kind(Uninitialized) { + APValue() : Kind(None) {} + explicit APValue(APSInt I) : Kind(None) { MakeInt(); setInt(std::move(I)); } - explicit APValue(APFloat F) : Kind(Uninitialized) { + explicit APValue(APFloat F) : Kind(None) { MakeFloat(); setFloat(std::move(F)); } - explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) { + explicit APValue(APFixedPoint FX) : Kind(None) { + MakeFixedPoint(std::move(FX)); + } + explicit APValue(const APValue *E, unsigned N) : Kind(None) { MakeVector(); setVector(E, N); } - APValue(APSInt R, APSInt I) : Kind(Uninitialized) { + APValue(APSInt R, APSInt I) : Kind(None) { MakeComplexInt(); setComplexInt(std::move(R), std::move(I)); } - APValue(APFloat R, APFloat I) : Kind(Uninitialized) { + APValue(APFloat R, APFloat I) : Kind(None) { MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); } APValue(const APValue &RHS); - APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); } + APValue(APValue &&RHS) : Kind(None) { swap(RHS); } APValue(LValueBase B, const CharUnits &O, NoLValuePath N, bool IsNullPtr = false) - : Kind(Uninitialized) { + : Kind(None) { MakeLValue(); setLValue(B, O, N, IsNullPtr); } APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, bool IsNullPtr = false) - : Kind(Uninitialized) { + : Kind(None) { MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr); } - APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) { + APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) { MakeArray(InitElts, Size); } - APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) { + APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) { MakeStruct(B, M); } explicit APValue(const FieldDecl *D, const APValue &V = APValue()) - : Kind(Uninitialized) { + : Kind(None) { MakeUnion(); setUnion(D, V); } APValue(const ValueDecl *Member, bool IsDerivedMember, - ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) { + ArrayRef<const CXXRecordDecl*> Path) : Kind(None) { MakeMemberPointer(Member, IsDerivedMember, Path); } APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) - : Kind(Uninitialized) { + : Kind(None) { MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); } + static APValue IndeterminateValue() { + APValue Result; + Result.Kind = Indeterminate; + return Result; + } ~APValue() { - MakeUninit(); + if (Kind != None && Kind != Indeterminate) + DestroyDataAndMakeUninit(); } /// Returns whether the object performed allocations. @@ -230,9 +309,14 @@ public: void swap(APValue &RHS); ValueKind getKind() const { return Kind; } - bool isUninit() const { return Kind == Uninitialized; } + + bool isAbsent() const { return Kind == None; } + bool isIndeterminate() const { return Kind == Indeterminate; } + bool hasValue() const { return Kind != None && Kind != Indeterminate; } + bool isInt() const { return Kind == Int; } bool isFloat() const { return Kind == Float; } + bool isFixedPoint() const { return Kind == FixedPoint; } bool isComplexInt() const { return Kind == ComplexInt; } bool isComplexFloat() const { return Kind == ComplexFloat; } bool isLValue() const { return Kind == LValue; } @@ -246,8 +330,8 @@ public: void dump() const; void dump(raw_ostream &OS) const; - void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const; - std::string getAsString(ASTContext &Ctx, QualType Ty) const; + void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const; + std::string getAsString(const ASTContext &Ctx, QualType Ty) const; APSInt &getInt() { assert(isInt() && "Invalid accessor"); @@ -257,6 +341,12 @@ public: return const_cast<APValue*>(this)->getInt(); } + /// Try to convert this value to an integral constant. This works if it's an + /// integer, null pointer, or offset from a null pointer. Returns true on + /// success. + bool toIntegralConstant(APSInt &Result, QualType SrcTy, + const ASTContext &Ctx) const; + APFloat &getFloat() { assert(isFloat() && "Invalid accessor"); return *(APFloat*)(char*)Data.buffer; @@ -265,6 +355,14 @@ public: return const_cast<APValue*>(this)->getFloat(); } + APFixedPoint &getFixedPoint() { + assert(isFixedPoint() && "Invalid accessor"); + return *(APFixedPoint *)(char *)Data.buffer; + } + const APFixedPoint &getFixedPoint() const { + return const_cast<APValue *>(this)->getFixedPoint(); + } + APSInt &getComplexIntReal() { assert(isComplexInt() && "Invalid accessor"); return ((ComplexAPSInt*)(char*)Data.buffer)->Real; @@ -406,6 +504,10 @@ public: assert(isFloat() && "Invalid accessor"); *(APFloat *)(char *)Data.buffer = std::move(F); } + void setFixedPoint(APFixedPoint FX) { + assert(isFixedPoint() && "Invalid accessor"); + *(APFixedPoint *)(char *)Data.buffer = std::move(FX); + } void setVector(const APValue *E, unsigned N) { assert(isVector() && "Invalid accessor"); ((Vec*)(char*)Data.buffer)->Elts = new APValue[N]; @@ -451,51 +553,52 @@ public: private: void DestroyDataAndMakeUninit(); - void MakeUninit() { - if (Kind != Uninitialized) - DestroyDataAndMakeUninit(); - } void MakeInt() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)Data.buffer) APSInt(1); Kind = Int; } void MakeFloat() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) APFloat(0.0); Kind = Float; } + void MakeFixedPoint(APFixedPoint &&FX) { + assert(isAbsent() && "Bad state change"); + new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX)); + Kind = FixedPoint; + } void MakeVector() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) Vec(); Kind = Vector; } void MakeComplexInt() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) ComplexAPSInt(); Kind = ComplexInt; } void MakeComplexFloat() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) ComplexAPFloat(); Kind = ComplexFloat; } void MakeLValue(); void MakeArray(unsigned InitElts, unsigned Size); void MakeStruct(unsigned B, unsigned M) { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) StructData(B, M); Kind = Struct; } void MakeUnion() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) UnionData(); Kind = Union; } void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, ArrayRef<const CXXRecordDecl*> Path); void MakeAddrLabelDiff() { - assert(isUninit() && "Bad state change"); + assert(isAbsent() && "Bad state change"); new ((void*)(char*)Data.buffer) AddrLabelDiffData(); Kind = AddrLabelDiff; } diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h index 6db351d1064b..6d0f274121b2 100644 --- a/include/clang/AST/AST.h +++ b/include/clang/AST/AST.h @@ -1,9 +1,8 @@ //===--- AST.h - "Umbrella" header for AST library --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 1167c566a35f..dc216a89c205 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -1,9 +1,8 @@ //===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 13870116c7fd..1d1aaf4fb115 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -1,9 +1,8 @@ //===- ASTContext.h - Context to hold long-lived AST nodes ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -266,17 +265,21 @@ private: /// Mapping from __block VarDecls to BlockVarCopyInit. llvm::DenseMap<const VarDecl *, BlockVarCopyInit> BlockVarCopyInits; - /// Mapping from class scope functions specialization to their - /// template patterns. - llvm::DenseMap<const FunctionDecl*, FunctionDecl*> - ClassScopeSpecializationPattern; - /// Mapping from materialized temporaries with static storage duration /// that appear in constant initializers to their evaluated values. These are /// allocated in a std::map because their address must be stable. llvm::DenseMap<const MaterializeTemporaryExpr *, APValue *> MaterializedTemporaryValues; + /// Used to cleanups APValues stored in the AST. + mutable llvm::SmallVector<APValue *, 0> APValueCleanups; + + /// A cache mapping a string value to a StringLiteral object with the same + /// value. + /// + /// This is lazily created. This is intentionally not serialized. + mutable llvm::StringMap<StringLiteral *> StringLiteralCache; + /// Representation of a "canonical" template template parameter that /// is used in canonical template names. class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode { @@ -892,11 +895,6 @@ public: TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var); - FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD); - - void setClassScopeSpecializationPattern(FunctionDecl *FD, - FunctionDecl *Pattern); - /// Note that the static data member \p Inst is an instantiation of /// the static data member template \p Tmpl of a class template. void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, @@ -1334,6 +1332,10 @@ public: ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; + /// Return a type for a constant array for a string literal of the + /// specified element type and length. + QualType getStringLiteralArrayType(QualType EltTy, unsigned Length) const; + /// Returns a vla type where known sizes are replaced with [*]. QualType getVariableArrayDecayedType(QualType Ty) const; @@ -1452,6 +1454,9 @@ public: QualType getParenType(QualType NamedType) const; + QualType getMacroQualifiedType(QualType UnderlyingTy, + const IdentifierInfo *MacroII) const; + QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, TagDecl *OwnedTagDecl = nullptr) const; @@ -1520,7 +1525,7 @@ public: /// C++11 deduced auto type. QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, - bool IsDependent) const; + bool IsDependent, bool IsPack = false) const; /// C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; @@ -1985,6 +1990,7 @@ public: TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin, UnresolvedSetIterator End) const; + TemplateName getAssumedTemplateName(DeclarationName Name) const; TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, @@ -2003,6 +2009,9 @@ public: /// No error GE_None, + /// Missing a type + GE_Missing_type, + /// Missing a type from <stdio.h> GE_Missing_stdio, @@ -2086,6 +2095,16 @@ public: CharUnits getTypeSizeInChars(QualType T) const; CharUnits getTypeSizeInChars(const Type *T) const; + Optional<CharUnits> getTypeSizeInCharsIfKnown(QualType Ty) const { + if (Ty->isIncompleteType() || Ty->isDependentType()) + return None; + return getTypeSizeInChars(Ty); + } + + Optional<CharUnits> getTypeSizeInCharsIfKnown(const Type *Ty) const { + return getTypeSizeInCharsIfKnown(QualType(Ty, 0)); + } + /// Return the ABI-specified alignment of a (complete) type \p T, in /// bits. unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; } @@ -2160,6 +2179,13 @@ public: /// pointers and large arrays get extra alignment. CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const; + /// Return the alignment (in bytes) of the thrown exception object. This is + /// only meaningful for targets that allocate C++ exceptions in a system + /// runtime, such as those using the Itanium C++ ABI. + CharUnits getExnObjectAlignment() const { + return toCharUnitsFromBits(Target->getExnObjectAlignment()); + } + /// Get or compute information about the layout of the specified /// record (struct/union/class) \p D, which indicates its size and field /// position information. @@ -2225,7 +2251,8 @@ public: VTableContextBase *getVTableContext(); - MangleContext *createMangleContext(); + /// If \p T is null pointer, assume the target in ASTContext. + MangleContext *createMangleContext(const TargetInfo *T = nullptr); void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass, SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const; @@ -2371,7 +2398,8 @@ public: /// Retrieves the default calling convention for the current target. CallingConv getDefaultCallingConvention(bool IsVariadic, - bool IsCXXMethod) const; + bool IsCXXMethod, + bool IsBuiltin = false) const; /// Retrieves the "canonical" template name that refers to a /// given template. @@ -2488,6 +2516,11 @@ public: /// \p LHS < \p RHS, return -1. int getFloatingTypeOrder(QualType LHS, QualType RHS) const; + /// Compare the rank of two floating point types as above, but compare equal + /// if both types have the same floating-point semantics on the target (i.e. + /// long double and double on AArch64 will return 0). + int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const; + /// Return a real floating point or a complex type (based on /// \p typeDomain/\p typeSize). /// @@ -2624,6 +2657,12 @@ public: // corresponding saturated type for a given fixed point type. QualType getCorrespondingSaturatedType(QualType Ty) const; + // This method accepts fixed point types and returns the corresponding signed + // type. Unlike getCorrespondingUnsignedType(), this only accepts unsigned + // fixed point types because there are unsigned integer types like bool and + // char8_t that don't have signed equivalents. + QualType getCorrespondingSignedFixedPointType(QualType Ty) const; + //===--------------------------------------------------------------------===// // Integer Values //===--------------------------------------------------------------------===// @@ -2677,7 +2716,7 @@ public: /// otherwise returns null. const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const; - /// Set the copy inialization expression of a block var decl. \p CanThrow + /// Set the copy initialization expression of a block var decl. \p CanThrow /// indicates whether the copy expression can throw or not. void setBlockVarCopyInit(const VarDecl* VD, Expr *CopyExpr, bool CanThrow); @@ -2712,12 +2751,11 @@ public: /// /// \param Data Pointer data that will be provided to the callback function /// when it is called. - void AddDeallocation(void (*Callback)(void*), void *Data); + void AddDeallocation(void (*Callback)(void *), void *Data) const; /// If T isn't trivially destructible, calls AddDeallocation to register it /// for destruction. - template <typename T> - void addDestruction(T *Ptr) { + template <typename T> void addDestruction(T *Ptr) const { if (!std::is_trivially_destructible<T>::value) { auto DestroyPtr = [](void *V) { static_cast<T *>(V)->~T(); }; AddDeallocation(DestroyPtr, Ptr); @@ -2780,51 +2818,56 @@ public: APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E, bool MayCreate); + /// Return a string representing the human readable name for the specified + /// function declaration or file name. Used by SourceLocExpr and + /// PredefinedExpr to cache evaluated results. + StringLiteral *getPredefinedStringLiteralFromCache(StringRef Key) const; + //===--------------------------------------------------------------------===// // Statistics //===--------------------------------------------------------------------===// /// The number of implicitly-declared default constructors. - static unsigned NumImplicitDefaultConstructors; + unsigned NumImplicitDefaultConstructors = 0; /// The number of implicitly-declared default constructors for /// which declarations were built. - static unsigned NumImplicitDefaultConstructorsDeclared; + unsigned NumImplicitDefaultConstructorsDeclared = 0; /// The number of implicitly-declared copy constructors. - static unsigned NumImplicitCopyConstructors; + unsigned NumImplicitCopyConstructors = 0; /// The number of implicitly-declared copy constructors for /// which declarations were built. - static unsigned NumImplicitCopyConstructorsDeclared; + unsigned NumImplicitCopyConstructorsDeclared = 0; /// The number of implicitly-declared move constructors. - static unsigned NumImplicitMoveConstructors; + unsigned NumImplicitMoveConstructors = 0; /// The number of implicitly-declared move constructors for /// which declarations were built. - static unsigned NumImplicitMoveConstructorsDeclared; + unsigned NumImplicitMoveConstructorsDeclared = 0; /// The number of implicitly-declared copy assignment operators. - static unsigned NumImplicitCopyAssignmentOperators; + unsigned NumImplicitCopyAssignmentOperators = 0; /// The number of implicitly-declared copy assignment operators for /// which declarations were built. - static unsigned NumImplicitCopyAssignmentOperatorsDeclared; + unsigned NumImplicitCopyAssignmentOperatorsDeclared = 0; /// The number of implicitly-declared move assignment operators. - static unsigned NumImplicitMoveAssignmentOperators; + unsigned NumImplicitMoveAssignmentOperators = 0; /// The number of implicitly-declared move assignment operators for /// which declarations were built. - static unsigned NumImplicitMoveAssignmentOperatorsDeclared; + unsigned NumImplicitMoveAssignmentOperatorsDeclared = 0; /// The number of implicitly-declared destructors. - static unsigned NumImplicitDestructors; + unsigned NumImplicitDestructors = 0; /// The number of implicitly-declared destructors for which /// declarations were built. - static unsigned NumImplicitDestructorsDeclared; + unsigned NumImplicitDestructorsDeclared = 0; public: /// Initialize built-in types. @@ -2839,18 +2882,51 @@ public: private: void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); + class ObjCEncOptions { + unsigned Bits; + + ObjCEncOptions(unsigned Bits) : Bits(Bits) {} + + public: + ObjCEncOptions() : Bits(0) {} + ObjCEncOptions(const ObjCEncOptions &RHS) : Bits(RHS.Bits) {} + +#define OPT_LIST(V) \ + V(ExpandPointedToStructures, 0) \ + V(ExpandStructures, 1) \ + V(IsOutermostType, 2) \ + V(EncodingProperty, 3) \ + V(IsStructField, 4) \ + V(EncodeBlockParameters, 5) \ + V(EncodeClassNames, 6) \ + +#define V(N,I) ObjCEncOptions& set##N() { Bits |= 1 << I; return *this; } +OPT_LIST(V) +#undef V + +#define V(N,I) bool N() const { return Bits & 1 << I; } +OPT_LIST(V) +#undef V + +#undef OPT_LIST + + LLVM_NODISCARD ObjCEncOptions keepingOnly(ObjCEncOptions Mask) const { + return Bits & Mask.Bits; + } + + LLVM_NODISCARD ObjCEncOptions forComponentType() const { + ObjCEncOptions Mask = ObjCEncOptions() + .setIsOutermostType() + .setIsStructField(); + return Bits & ~Mask.Bits; + } + }; + // Return the Objective-C type encoding for a given type. void getObjCEncodingForTypeImpl(QualType t, std::string &S, - bool ExpandPointedToStructures, - bool ExpandStructures, + ObjCEncOptions Options, const FieldDecl *Field, - bool OutermostType = false, - bool EncodingProperty = false, - bool StructField = false, - bool EncodeBlockParameters = false, - bool EncodeClassNames = false, - bool EncodePointerToObjCTypedef = false, - QualType *NotEncodedT=nullptr) const; + QualType *NotEncodedT = nullptr) const; // Adds the encoding of the structure's members. void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S, @@ -2908,7 +2984,7 @@ private: // in order to track and run destructors while we're tearing things down. using DeallocationFunctionsAndArguments = llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>; - DeallocationFunctionsAndArguments Deallocations; + mutable DeallocationFunctionsAndArguments Deallocations; // FIXME: This currently contains the set of StoredDeclMaps used // by DeclContext objects. This probably should not be in ASTContext, diff --git a/include/clang/AST/ASTContextAllocate.h b/include/clang/AST/ASTContextAllocate.h index 5b9eed208a4d..70c8e24f9185 100644 --- a/include/clang/AST/ASTContextAllocate.h +++ b/include/clang/AST/ASTContextAllocate.h @@ -1,9 +1,8 @@ //===- ASTContextAllocate.h - ASTContext allocate functions -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h index fe92604587ef..d6549e12d92a 100644 --- a/include/clang/AST/ASTDiagnostic.h +++ b/include/clang/AST/ASTDiagnostic.h @@ -1,9 +1,8 @@ //===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/ASTDumper.h b/include/clang/AST/ASTDumper.h new file mode 100644 index 000000000000..61202f057a80 --- /dev/null +++ b/include/clang/AST/ASTDumper.h @@ -0,0 +1,56 @@ +//===--- ASTDumper.h - Dumping implementation for ASTs --------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ASTDUMPER_H +#define LLVM_CLANG_AST_ASTDUMPER_H + +#include "clang/AST/ASTNodeTraverser.h" +#include "clang/AST/TextNodeDumper.h" + +namespace clang { + +class ASTDumper : public ASTNodeTraverser<ASTDumper, TextNodeDumper> { + + TextNodeDumper NodeDumper; + + raw_ostream &OS; + + const bool ShowColors; + +public: + ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, + const SourceManager *SM) + : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {} + + ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, + const SourceManager *SM, bool ShowColors) + : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {} + ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, + const SourceManager *SM, bool ShowColors, + const PrintingPolicy &PrintPolicy) + : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS), + ShowColors(ShowColors) {} + + TextNodeDumper &doGetNodeDelegate() { return NodeDumper; } + + void dumpLookups(const DeclContext *DC, bool DumpDecls); + + template <typename SpecializationDecl> + void dumpTemplateDeclSpecialization(const SpecializationDecl *D, + bool DumpExplicitInst, bool DumpRefOnly); + template <typename TemplateDecl> + void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst); + + void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); + void VisitClassTemplateDecl(const ClassTemplateDecl *D); + void VisitVarTemplateDecl(const VarTemplateDecl *D); +}; + +} // namespace clang + +#endif diff --git a/include/clang/AST/ASTDumperUtils.h b/include/clang/AST/ASTDumperUtils.h index 5e62e902b423..55a085449a9b 100644 --- a/include/clang/AST/ASTDumperUtils.h +++ b/include/clang/AST/ASTDumperUtils.h @@ -1,9 +1,8 @@ //===--- ASTDumperUtils.h - Printing of AST nodes -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -18,6 +17,12 @@ namespace clang { +/// Used to specify the format for printing AST dump information. +enum ASTDumpOutputFormat { + ADOF_Default, + ADOF_JSON +}; + // Colors used for various parts of the AST dump // Do not use bold yellow for any text. It is hard to read on white screens. diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h index 038d5c3d3611..93919bbdd52f 100644 --- a/include/clang/AST/ASTFwd.h +++ b/include/clang/AST/ASTFwd.h @@ -1,9 +1,8 @@ //===--- ASTFwd.h ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===--------------------------------------------------------------===// /// diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h index dbb9cf35ddea..4a55c120a457 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -1,9 +1,8 @@ //===- ASTImporter.h - Importing ASTs from other Contexts -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -15,6 +14,7 @@ #ifndef LLVM_CLANG_AST_ASTIMPORTER_H #define LLVM_CLANG_AST_ASTIMPORTER_H +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" @@ -33,7 +33,8 @@ namespace clang { class ASTContext; -class ASTImporterLookupTable; +class ASTImporterSharedState; +class Attr; class CXXBaseSpecifier; class CXXCtorInitializer; class Decl; @@ -43,8 +44,8 @@ class FileManager; class NamedDecl; class Stmt; class TagDecl; +class TranslationUnitDecl; class TypeSourceInfo; -class Attr; class ImportError : public llvm::ErrorInfo<ImportError> { public: @@ -87,14 +88,140 @@ class Attr; using ImportedCXXBaseSpecifierMap = llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>; - private: + // An ImportPath is the list of the AST nodes which we visit during an + // Import call. + // If node `A` depends on node `B` then the path contains an `A`->`B` edge. + // From the call stack of the import functions we can read the very same + // path. + // + // Now imagine the following AST, where the `->` represents dependency in + // therms of the import. + // ``` + // A->B->C->D + // `->E + // ``` + // We would like to import A. + // The import behaves like a DFS, so we will visit the nodes in this order: + // ABCDE. + // During the visitation we will have the following ImportPaths: + // ``` + // A + // AB + // ABC + // ABCD + // ABC + // AB + // ABE + // AB + // A + // ``` + // If during the visit of E there is an error then we set an error for E, + // then as the call stack shrinks for B, then for A: + // ``` + // A + // AB + // ABC + // ABCD + // ABC + // AB + // ABE // Error! Set an error to E + // AB // Set an error to B + // A // Set an error to A + // ``` + // However, during the import we could import C and D without any error and + // they are independent from A,B and E. + // We must not set up an error for C and D. + // So, at the end of the import we have an entry in `ImportDeclErrors` for + // A,B,E but not for C,D. + // + // Now what happens if there is a cycle in the import path? + // Let's consider this AST: + // ``` + // A->B->C->A + // `->E + // ``` + // During the visitation we will have the below ImportPaths and if during + // the visit of E there is an error then we will set up an error for E,B,A. + // But what's up with C? + // ``` + // A + // AB + // ABC + // ABCA + // ABC + // AB + // ABE // Error! Set an error to E + // AB // Set an error to B + // A // Set an error to A + // ``` + // This time we know that both B and C are dependent on A. + // This means we must set up an error for C too. + // As the call stack reverses back we get to A and we must set up an error + // to all nodes which depend on A (this includes C). + // But C is no longer on the import path, it just had been previously. + // Such situation can happen only if during the visitation we had a cycle. + // If we didn't have any cycle, then the normal way of passing an Error + // object through the call stack could handle the situation. + // This is why we must track cycles during the import process for each + // visited declaration. + class ImportPathTy { + public: + using VecTy = llvm::SmallVector<Decl *, 32>; + + void push(Decl *D) { + Nodes.push_back(D); + ++Aux[D]; + } + + void pop() { + if (Nodes.empty()) + return; + --Aux[Nodes.back()]; + Nodes.pop_back(); + } + + /// Returns true if the last element can be found earlier in the path. + bool hasCycleAtBack() const { + auto Pos = Aux.find(Nodes.back()); + return Pos != Aux.end() && Pos->second > 1; + } + + using Cycle = llvm::iterator_range<VecTy::const_reverse_iterator>; + Cycle getCycleAtBack() const { + assert(Nodes.size() >= 2); + return Cycle(Nodes.rbegin(), + std::find(Nodes.rbegin() + 1, Nodes.rend(), Nodes.back()) + + 1); + } + + /// Returns the copy of the cycle. + VecTy copyCycleAtBack() const { + auto R = getCycleAtBack(); + return VecTy(R.begin(), R.end()); + } + + private: + // All nodes of the path. + VecTy Nodes; + // Auxiliary container to be able to answer "Do we have a cycle ending + // at last element?" as fast as possible. + // We count each Decl's occurrence over the path. + llvm::SmallDenseMap<Decl *, int, 32> Aux; + }; - /// Pointer to the import specific lookup table, which may be shared - /// amongst several ASTImporter objects. - /// This is an externally managed resource (and should exist during the - /// lifetime of the ASTImporter object) - /// If not set then the original C/C++ lookup is used. - ASTImporterLookupTable *LookupTable = nullptr; + private: + std::shared_ptr<ASTImporterSharedState> SharedState = nullptr; + + /// The path which we go through during the import of a given AST node. + ImportPathTy ImportPath; + /// Sometimes we have to save some part of an import path, so later we can + /// set up properties to the saved nodes. + /// We may have several of these import paths associated to one Decl. + using SavedImportPathsForOneDecl = + llvm::SmallVector<ImportPathTy::VecTy, 32>; + using SavedImportPathsTy = + llvm::SmallDenseMap<Decl *, SavedImportPathsForOneDecl, 32>; + SavedImportPathsTy SavedImportPaths; /// The contexts we're importing to and from. ASTContext &ToContext, &FromContext; @@ -116,6 +243,18 @@ class Attr; /// context to the corresponding declarations in the "to" context. llvm::DenseMap<Decl *, Decl *> ImportedDecls; + /// Mapping from the already-imported declarations in the "from" + /// context to the error status of the import of that declaration. + /// This map contains only the declarations that were not correctly + /// imported. The same declaration may or may not be included in + /// ImportedDecls. This map is updated continuously during imports and never + /// cleared (like ImportedDecls). + llvm::DenseMap<Decl *, ImportError> ImportDeclErrors; + + /// Mapping from the already-imported declarations in the "to" + /// context to the corresponding declarations in the "from" context. + llvm::DenseMap<Decl *, Decl *> ImportedFromDecls; + /// Mapping from the already-imported statements in the "from" /// context to the corresponding statements in the "to" context. llvm::DenseMap<Stmt *, Stmt *> ImportedStmts; @@ -138,6 +277,15 @@ class Attr; void AddToLookupTable(Decl *ToD); + protected: + /// Can be overwritten by subclasses to implement their own import logic. + /// The overwritten method should call this method if it didn't import the + /// decl on its own. + virtual Expected<Decl *> ImportImpl(Decl *From); + + /// Used only in unittests to verify the behaviour of the error handling. + virtual bool returnWithErrorInTest() { return false; }; + public: /// \param ToContext The context we'll be importing into. @@ -152,13 +300,13 @@ class Attr; /// as little as it can, e.g., by importing declarations as forward /// declarations that can be completed at a later point. /// - /// \param LookupTable The importer specific lookup table which may be + /// \param SharedState The importer specific lookup table which may be /// shared amongst several ASTImporter objects. /// If not set then the original C/C++ lookup is used. ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, ASTContext &FromContext, FileManager &FromFileManager, bool MinimalImport, - ASTImporterLookupTable *LookupTable = nullptr); + std::shared_ptr<ASTImporterSharedState> SharedState = nullptr); virtual ~ASTImporter(); @@ -173,63 +321,51 @@ class Attr; /// \return Error information (success or error). template <typename ImportT> LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) { - To = Import(From); - if (From && !To) - return llvm::make_error<ImportError>(); - return llvm::Error::success(); - // FIXME: this should be the final code - //auto ToOrErr = Import(From); - //if (ToOrErr) - // To = *ToOrErr; - //return ToOrErr.takeError(); + auto ToOrErr = Import(From); + if (ToOrErr) + To = *ToOrErr; + return ToOrErr.takeError(); } /// Import the given type from the "from" context into the "to" /// context. A null type is imported as a null type (no error). /// /// \returns The equivalent type in the "to" context, or the import error. - llvm::Expected<QualType> Import_New(QualType FromT); - // FIXME: Remove this version. - QualType Import(QualType FromT); + llvm::Expected<QualType> Import(QualType FromT); /// Import the given type source information from the /// "from" context into the "to" context. /// /// \returns The equivalent type source information in the "to" /// context, or the import error. - llvm::Expected<TypeSourceInfo *> Import_New(TypeSourceInfo *FromTSI); - // FIXME: Remove this version. - TypeSourceInfo *Import(TypeSourceInfo *FromTSI); + llvm::Expected<TypeSourceInfo *> Import(TypeSourceInfo *FromTSI); /// Import the given attribute from the "from" context into the /// "to" context. /// /// \returns The equivalent attribute in the "to" context, or the import /// error. - llvm::Expected<Attr *> Import_New(const Attr *FromAttr); - // FIXME: Remove this version. - Attr *Import(const Attr *FromAttr); + llvm::Expected<Attr *> Import(const Attr *FromAttr); /// Import the given declaration from the "from" context into the /// "to" context. /// /// \returns The equivalent declaration in the "to" context, or the import /// error. - llvm::Expected<Decl *> Import_New(Decl *FromD); - llvm::Expected<Decl *> Import_New(const Decl *FromD) { - return Import_New(const_cast<Decl *>(FromD)); - } - // FIXME: Remove this version. - Decl *Import(Decl *FromD); - Decl *Import(const Decl *FromD) { + llvm::Expected<Decl *> Import(Decl *FromD); + llvm::Expected<const Decl *> Import(const Decl *FromD) { return Import(const_cast<Decl *>(FromD)); } /// Return the copy of the given declaration in the "to" context if /// it has already been imported from the "from" context. Otherwise return - /// NULL. + /// nullptr. Decl *GetAlreadyImportedOrNull(const Decl *FromD) const; + /// Return the translation unit from where the declaration was + /// imported. If it does not exist nullptr is returned. + TranslationUnitDecl *GetFromTU(Decl *ToD); + /// Import the given declaration context from the "from" /// AST context into the "to" AST context. /// @@ -242,28 +378,21 @@ class Attr; /// /// \returns The equivalent expression in the "to" context, or the import /// error. - llvm::Expected<Expr *> Import_New(Expr *FromE); - // FIXME: Remove this version. - Expr *Import(Expr *FromE); + llvm::Expected<Expr *> Import(Expr *FromE); /// Import the given statement from the "from" context into the /// "to" context. /// /// \returns The equivalent statement in the "to" context, or the import /// error. - llvm::Expected<Stmt *> Import_New(Stmt *FromS); - // FIXME: Remove this version. - Stmt *Import(Stmt *FromS); + llvm::Expected<Stmt *> Import(Stmt *FromS); /// Import the given nested-name-specifier from the "from" /// context into the "to" context. /// /// \returns The equivalent nested-name-specifier in the "to" /// context, or the import error. - llvm::Expected<NestedNameSpecifier *> - Import_New(NestedNameSpecifier *FromNNS); - // FIXME: Remove this version. - NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS); + llvm::Expected<NestedNameSpecifier *> Import(NestedNameSpecifier *FromNNS); /// Import the given nested-name-specifier-loc from the "from" /// context into the "to" context. @@ -271,42 +400,32 @@ class Attr; /// \returns The equivalent nested-name-specifier-loc in the "to" /// context, or the import error. llvm::Expected<NestedNameSpecifierLoc> - Import_New(NestedNameSpecifierLoc FromNNS); - // FIXME: Remove this version. - NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS); + Import(NestedNameSpecifierLoc FromNNS); /// Import the given template name from the "from" context into the /// "to" context, or the import error. - llvm::Expected<TemplateName> Import_New(TemplateName From); - // FIXME: Remove this version. - TemplateName Import(TemplateName From); + llvm::Expected<TemplateName> Import(TemplateName From); /// Import the given source location from the "from" context into /// the "to" context. /// /// \returns The equivalent source location in the "to" context, or the /// import error. - llvm::Expected<SourceLocation> Import_New(SourceLocation FromLoc); - // FIXME: Remove this version. - SourceLocation Import(SourceLocation FromLoc); + llvm::Expected<SourceLocation> Import(SourceLocation FromLoc); /// Import the given source range from the "from" context into /// the "to" context. /// /// \returns The equivalent source range in the "to" context, or the import /// error. - llvm::Expected<SourceRange> Import_New(SourceRange FromRange); - // FIXME: Remove this version. - SourceRange Import(SourceRange FromRange); + llvm::Expected<SourceRange> Import(SourceRange FromRange); /// Import the given declaration name from the "from" /// context into the "to" context. /// /// \returns The equivalent declaration name in the "to" context, or the /// import error. - llvm::Expected<DeclarationName> Import_New(DeclarationName FromName); - // FIXME: Remove this version. - DeclarationName Import(DeclarationName FromName); + llvm::Expected<DeclarationName> Import(DeclarationName FromName); /// Import the given identifier from the "from" context /// into the "to" context. @@ -320,46 +439,32 @@ class Attr; /// /// \returns The equivalent selector in the "to" context, or the import /// error. - llvm::Expected<Selector> Import_New(Selector FromSel); - // FIXME: Remove this version. - Selector Import(Selector FromSel); + llvm::Expected<Selector> Import(Selector FromSel); /// Import the given file ID from the "from" context into the /// "to" context. /// /// \returns The equivalent file ID in the source manager of the "to" /// context, or the import error. - llvm::Expected<FileID> Import_New(FileID); - // FIXME: Remove this version. - FileID Import(FileID); + llvm::Expected<FileID> Import(FileID, bool IsBuiltin = false); /// Import the given C++ constructor initializer from the "from" /// context into the "to" context. /// /// \returns The equivalent initializer in the "to" context, or the import /// error. - llvm::Expected<CXXCtorInitializer *> - Import_New(CXXCtorInitializer *FromInit); - // FIXME: Remove this version. - CXXCtorInitializer *Import(CXXCtorInitializer *FromInit); + llvm::Expected<CXXCtorInitializer *> Import(CXXCtorInitializer *FromInit); /// Import the given CXXBaseSpecifier from the "from" context into /// the "to" context. /// /// \returns The equivalent CXXBaseSpecifier in the source manager of the /// "to" context, or the import error. - llvm::Expected<CXXBaseSpecifier *> - Import_New(const CXXBaseSpecifier *FromSpec); - // FIXME: Remove this version. - CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec); + llvm::Expected<CXXBaseSpecifier *> Import(const CXXBaseSpecifier *FromSpec); /// Import the definition of the given declaration, including all of /// the declarations it contains. - LLVM_NODISCARD llvm::Error ImportDefinition_New(Decl *From); - - // FIXME: Compatibility function. - // Usages of this should be changed to ImportDefinition_New. - void ImportDefinition(Decl *From); + LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From); /// Cope with a name conflict when importing a declaration into the /// given context. @@ -422,9 +527,13 @@ class Attr; /// Subclasses can override this function to observe all of the \c From -> /// \c To declaration mappings as they are imported. - virtual Decl *Imported(Decl *From, Decl *To) { return To; } + virtual void Imported(Decl *From, Decl *To) {} + + void RegisterImportedDecl(Decl *FromD, Decl *ToD); /// Store and assign the imported declaration to its counterpart. + /// It may happen that several decls from the 'from' context are mapped to + /// the same decl in the 'to' context. Decl *MapImported(Decl *From, Decl *To); /// Called by StructuralEquivalenceContext. If a RecordDecl is @@ -435,6 +544,14 @@ class Attr; /// importation, eliminating this loop. virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; } + /// Return if import of the given declaration has failed and if yes + /// the kind of the problem. This gives the first error encountered with + /// the node. + llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *FromD) const; + + /// Mark (newly) imported declaration with error. + void setImportDeclError(Decl *From, ImportError Error); + /// Determine whether the given types are structurally /// equivalent. bool IsStructurallyEquivalent(QualType From, QualType To, @@ -445,7 +562,6 @@ class Attr; /// \returns The index of the field in its parent context (starting from 0). /// On error `None` is returned (parent context is non-record). static llvm::Optional<unsigned> getFieldIndex(Decl *F); - }; } // namespace clang diff --git a/include/clang/AST/ASTImporterLookupTable.h b/include/clang/AST/ASTImporterLookupTable.h index 14cafe817ddc..407478a51058 100644 --- a/include/clang/AST/ASTImporterLookupTable.h +++ b/include/clang/AST/ASTImporterLookupTable.h @@ -1,9 +1,8 @@ //===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- C++ -*---===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTImporterSharedState.h b/include/clang/AST/ASTImporterSharedState.h new file mode 100644 index 000000000000..3635a62deef0 --- /dev/null +++ b/include/clang/AST/ASTImporterSharedState.h @@ -0,0 +1,81 @@ +//===- ASTImporterSharedState.h - ASTImporter specific state --*- C++ -*---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ASTImporter specific state, which may be shared +// amongst several ASTImporter objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H +#define LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H + +#include "clang/AST/ASTImporterLookupTable.h" +#include "clang/AST/Decl.h" +#include "llvm/ADT/DenseMap.h" +// FIXME We need this because of ImportError. +#include "clang/AST/ASTImporter.h" + +namespace clang { + +class TranslationUnitDecl; + +/// Importer specific state, which may be shared amongst several ASTImporter +/// objects. +class ASTImporterSharedState { + + /// Pointer to the import specific lookup table. + std::unique_ptr<ASTImporterLookupTable> LookupTable; + + /// Mapping from the already-imported declarations in the "to" + /// context to the error status of the import of that declaration. + /// This map contains only the declarations that were not correctly + /// imported. The same declaration may or may not be included in + /// ImportedFromDecls. This map is updated continuously during imports and + /// never cleared (like ImportedFromDecls). + llvm::DenseMap<Decl *, ImportError> ImportErrors; + + // FIXME put ImportedFromDecls here! + // And from that point we can better encapsulate the lookup table. + +public: + ASTImporterSharedState() = default; + + ASTImporterSharedState(TranslationUnitDecl &ToTU) { + LookupTable = llvm::make_unique<ASTImporterLookupTable>(ToTU); + } + + ASTImporterLookupTable *getLookupTable() { return LookupTable.get(); } + + void addDeclToLookup(Decl *D) { + if (LookupTable) + if (auto *ND = dyn_cast<NamedDecl>(D)) + LookupTable->add(ND); + } + + void removeDeclFromLookup(Decl *D) { + if (LookupTable) + if (auto *ND = dyn_cast<NamedDecl>(D)) + LookupTable->remove(ND); + } + + llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *ToD) const { + auto Pos = ImportErrors.find(ToD); + if (Pos != ImportErrors.end()) + return Pos->second; + else + return Optional<ImportError>(); + } + + void setImportDeclError(Decl *To, ImportError Error) { + ImportErrors[To] = Error; + } +}; + +} // namespace clang +#endif // LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h index 6fedcb8d3801..c1153168e41b 100644 --- a/include/clang/AST/ASTLambda.h +++ b/include/clang/AST/ASTLambda.h @@ -1,9 +1,8 @@ //===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index 80184e1cc740..8879f9f3229f 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -1,9 +1,8 @@ //===--- ASTMutationListener.h - AST Mutation Interface --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -128,6 +127,11 @@ public: virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, const Attr *Attr) {} + /// A declaration is marked as a variable with OpenMP allocator. + /// + /// \param D the declaration marked as a variable with OpenMP allocator. + virtual void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {} + /// A definition has been made visible by being redefined locally. /// /// \param D The definition that was previously not visible. diff --git a/include/clang/AST/ASTNodeTraverser.h b/include/clang/AST/ASTNodeTraverser.h new file mode 100644 index 000000000000..e43eacef86c6 --- /dev/null +++ b/include/clang/AST/ASTNodeTraverser.h @@ -0,0 +1,654 @@ +//===--- ASTNodeTraverser.h - Traversal of AST nodes ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the AST traversal facilities. Other users +// of this class may make use of the same traversal logic by inheriting it, +// similar to RecursiveASTVisitor. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H +#define LLVM_CLANG_AST_ASTNODETRAVERSER_H + +#include "clang/AST/AttrVisitor.h" +#include "clang/AST/CommentVisitor.h" +#include "clang/AST/DeclVisitor.h" +#include "clang/AST/LocInfoType.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/TypeVisitor.h" + +namespace clang { + +/** + +ASTNodeTraverser traverses the Clang AST for dumping purposes. + +The `Derived::doGetNodeDelegate()` method is required to be an accessible member +which returns a reference of type `NodeDelegateType &` which implements the +following interface: + +struct { + template <typename Fn> void AddChild(Fn DoAddChild); + template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild); + + void Visit(const comments::Comment *C, const comments::FullComment *FC); + void Visit(const Attr *A); + void Visit(const TemplateArgument &TA, SourceRange R = {}, + const Decl *From = nullptr, StringRef Label = {}); + void Visit(const Stmt *Node); + void Visit(const Type *T); + void Visit(QualType T); + void Visit(const Decl *D); + void Visit(const CXXCtorInitializer *Init); + void Visit(const OMPClause *C); + void Visit(const BlockDecl::Capture &C); + void Visit(const GenericSelectionExpr::ConstAssociation &A); +}; +*/ +template <typename Derived, typename NodeDelegateType> +class ASTNodeTraverser + : public ConstDeclVisitor<Derived>, + public ConstStmtVisitor<Derived>, + public comments::ConstCommentVisitor<Derived, void, + const comments::FullComment *>, + public TypeVisitor<Derived>, + public ConstAttrVisitor<Derived>, + public ConstTemplateArgumentVisitor<Derived> { + + /// Indicates whether we should trigger deserialization of nodes that had + /// not already been loaded. + bool Deserialize = false; + + NodeDelegateType &getNodeDelegate() { + return getDerived().doGetNodeDelegate(); + } + Derived &getDerived() { return *static_cast<Derived *>(this); } + +public: + void setDeserialize(bool D) { Deserialize = D; } + bool getDeserialize() const { return Deserialize; } + + void Visit(const Decl *D) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(D); + if (!D) + return; + + ConstDeclVisitor<Derived>::Visit(D); + + for (const auto &A : D->attrs()) + Visit(A); + + if (const comments::FullComment *Comment = + D->getASTContext().getLocalCommentForDeclUncached(D)) + Visit(Comment, Comment); + + // Decls within functions are visited by the body. + if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) { + if (const auto *DC = dyn_cast<DeclContext>(D)) + dumpDeclContext(DC); + } + }); + } + + void Visit(const Stmt *S, StringRef Label = {}) { + getNodeDelegate().AddChild(Label, [=] { + getNodeDelegate().Visit(S); + + if (!S) { + return; + } + + ConstStmtVisitor<Derived>::Visit(S); + + // Some statements have custom mechanisms for dumping their children. + if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) { + return; + } + + for (const Stmt *SubStmt : S->children()) + Visit(SubStmt); + }); + } + + void Visit(QualType T) { + SplitQualType SQT = T.split(); + if (!SQT.Quals.hasQualifiers()) + return Visit(SQT.Ty); + + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(T); + Visit(T.split().Ty); + }); + } + + void Visit(const Type *T) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(T); + if (!T) + return; + TypeVisitor<Derived>::Visit(T); + + QualType SingleStepDesugar = + T->getLocallyUnqualifiedSingleStepDesugaredType(); + if (SingleStepDesugar != QualType(T, 0)) + Visit(SingleStepDesugar); + }); + } + + void Visit(const Attr *A) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(A); + ConstAttrVisitor<Derived>::Visit(A); + }); + } + + void Visit(const CXXCtorInitializer *Init) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(Init); + Visit(Init->getInit()); + }); + } + + void Visit(const TemplateArgument &A, SourceRange R = {}, + const Decl *From = nullptr, const char *Label = nullptr) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(A, R, From, Label); + ConstTemplateArgumentVisitor<Derived>::Visit(A); + }); + } + + void Visit(const BlockDecl::Capture &C) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(C); + if (C.hasCopyExpr()) + Visit(C.getCopyExpr()); + }); + } + + void Visit(const OMPClause *C) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(C); + for (const auto *S : C->children()) + Visit(S); + }); + } + + void Visit(const GenericSelectionExpr::ConstAssociation &A) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(A); + if (const TypeSourceInfo *TSI = A.getTypeSourceInfo()) + Visit(TSI->getType()); + Visit(A.getAssociationExpr()); + }); + } + + void Visit(const comments::Comment *C, const comments::FullComment *FC) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(C, FC); + if (!C) { + return; + } + comments::ConstCommentVisitor<Derived, void, + const comments::FullComment *>::visit(C, + FC); + for (comments::Comment::child_iterator I = C->child_begin(), + E = C->child_end(); + I != E; ++I) + Visit(*I, FC); + }); + } + + void Visit(const ast_type_traits::DynTypedNode &N) { + // FIXME: Improve this with a switch or a visitor pattern. + if (const auto *D = N.get<Decl>()) + Visit(D); + else if (const auto *S = N.get<Stmt>()) + Visit(S); + else if (const auto *QT = N.get<QualType>()) + Visit(*QT); + else if (const auto *T = N.get<Type>()) + Visit(T); + else if (const auto *C = N.get<CXXCtorInitializer>()) + Visit(C); + else if (const auto *C = N.get<OMPClause>()) + Visit(C); + else if (const auto *T = N.get<TemplateArgument>()) + Visit(*T); + } + + void dumpDeclContext(const DeclContext *DC) { + if (!DC) + return; + + for (const auto *D : (Deserialize ? DC->decls() : DC->noload_decls())) + Visit(D); + } + + void dumpTemplateParameters(const TemplateParameterList *TPL) { + if (!TPL) + return; + + for (const auto &TP : *TPL) + Visit(TP); + } + + void + dumpASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *TALI) { + if (!TALI) + return; + + for (const auto &TA : TALI->arguments()) + dumpTemplateArgumentLoc(TA); + } + + void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A, + const Decl *From = nullptr, + const char *Label = nullptr) { + Visit(A.getArgument(), A.getSourceRange(), From, Label); + } + + void dumpTemplateArgumentList(const TemplateArgumentList &TAL) { + for (unsigned i = 0, e = TAL.size(); i < e; ++i) + Visit(TAL[i]); + } + + void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) { + if (!typeParams) + return; + + for (const auto &typeParam : *typeParams) { + Visit(typeParam); + } + } + + void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); } + void VisitLocInfoType(const LocInfoType *T) { + Visit(T->getTypeSourceInfo()->getType()); + } + void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); } + void VisitBlockPointerType(const BlockPointerType *T) { + Visit(T->getPointeeType()); + } + void VisitReferenceType(const ReferenceType *T) { + Visit(T->getPointeeType()); + } + void VisitMemberPointerType(const MemberPointerType *T) { + Visit(T->getClass()); + Visit(T->getPointeeType()); + } + void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); } + void VisitVariableArrayType(const VariableArrayType *T) { + VisitArrayType(T); + Visit(T->getSizeExpr()); + } + void VisitDependentSizedArrayType(const DependentSizedArrayType *T) { + Visit(T->getElementType()); + Visit(T->getSizeExpr()); + } + void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) { + Visit(T->getElementType()); + Visit(T->getSizeExpr()); + } + void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); } + void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); } + void VisitFunctionProtoType(const FunctionProtoType *T) { + VisitFunctionType(T); + for (const QualType &PT : T->getParamTypes()) + Visit(PT); + } + void VisitTypeOfExprType(const TypeOfExprType *T) { + Visit(T->getUnderlyingExpr()); + } + void VisitDecltypeType(const DecltypeType *T) { + Visit(T->getUnderlyingExpr()); + } + void VisitUnaryTransformType(const UnaryTransformType *T) { + Visit(T->getBaseType()); + } + void VisitAttributedType(const AttributedType *T) { + // FIXME: AttrKind + Visit(T->getModifiedType()); + } + void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { + Visit(T->getReplacedParameter()); + } + void + VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) { + Visit(T->getReplacedParameter()); + Visit(T->getArgumentPack()); + } + void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { + for (const auto &Arg : *T) + Visit(Arg); + if (T->isTypeAlias()) + Visit(T->getAliasedType()); + } + void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { + Visit(T->getPointeeType()); + } + void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); } + void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); } + void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); } + void VisitPackExpansionType(const PackExpansionType *T) { + if (!T->isSugared()) + Visit(T->getPattern()); + } + // FIXME: ElaboratedType, DependentNameType, + // DependentTemplateSpecializationType, ObjCObjectType + + void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); } + + void VisitEnumConstantDecl(const EnumConstantDecl *D) { + if (const Expr *Init = D->getInitExpr()) + Visit(Init); + } + + void VisitFunctionDecl(const FunctionDecl *D) { + if (const auto *FTSI = D->getTemplateSpecializationInfo()) + dumpTemplateArgumentList(*FTSI->TemplateArguments); + + if (D->param_begin()) + for (const auto *Parameter : D->parameters()) + Visit(Parameter); + + if (const auto *C = dyn_cast<CXXConstructorDecl>(D)) + for (const auto *I : C->inits()) + Visit(I); + + if (D->doesThisDeclarationHaveABody()) + Visit(D->getBody()); + } + + void VisitFieldDecl(const FieldDecl *D) { + if (D->isBitField()) + Visit(D->getBitWidth()); + if (Expr *Init = D->getInClassInitializer()) + Visit(Init); + } + + void VisitVarDecl(const VarDecl *D) { + if (D->hasInit()) + Visit(D->getInit()); + } + + void VisitDecompositionDecl(const DecompositionDecl *D) { + VisitVarDecl(D); + for (const auto *B : D->bindings()) + Visit(B); + } + + void VisitBindingDecl(const BindingDecl *D) { + if (const auto *E = D->getBinding()) + Visit(E); + } + + void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { + Visit(D->getAsmString()); + } + + void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); } + + void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { + for (const auto *E : D->varlists()) + Visit(E); + } + + void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) { + Visit(D->getCombiner()); + if (const auto *Initializer = D->getInitializer()) + Visit(Initializer); + } + + void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) { + for (const auto *C : D->clauselists()) + Visit(C); + } + + void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { + Visit(D->getInit()); + } + + void VisitOMPAllocateDecl(const OMPAllocateDecl *D) { + for (const auto *E : D->varlists()) + Visit(E); + for (const auto *C : D->clauselists()) + Visit(C); + } + + template <typename SpecializationDecl> + void dumpTemplateDeclSpecialization(const SpecializationDecl *D) { + for (const auto *RedeclWithBadType : D->redecls()) { + // FIXME: The redecls() range sometimes has elements of a less-specific + // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives + // us TagDecls, and should give CXXRecordDecls). + auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType); + if (!Redecl) { + // Found the injected-class-name for a class template. This will be + // dumped as part of its surrounding class so we don't need to dump it + // here. + assert(isa<CXXRecordDecl>(RedeclWithBadType) && + "expected an injected-class-name"); + continue; + } + Visit(Redecl); + } + } + + template <typename TemplateDecl> + void dumpTemplateDecl(const TemplateDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + + Visit(D->getTemplatedDecl()); + + for (const auto *Child : D->specializations()) + dumpTemplateDeclSpecialization(Child); + } + + void VisitTypeAliasDecl(const TypeAliasDecl *D) { + Visit(D->getUnderlyingType()); + } + + void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + Visit(D->getTemplatedDecl()); + } + + void VisitStaticAssertDecl(const StaticAssertDecl *D) { + Visit(D->getAssertExpr()); + Visit(D->getMessage()); + } + + void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { + dumpTemplateDecl(D); + } + + void VisitClassTemplateDecl(const ClassTemplateDecl *D) { + dumpTemplateDecl(D); + } + + void VisitClassTemplateSpecializationDecl( + const ClassTemplateSpecializationDecl *D) { + dumpTemplateArgumentList(D->getTemplateArgs()); + } + + void VisitClassTemplatePartialSpecializationDecl( + const ClassTemplatePartialSpecializationDecl *D) { + VisitClassTemplateSpecializationDecl(D); + dumpTemplateParameters(D->getTemplateParameters()); + } + + void VisitClassScopeFunctionSpecializationDecl( + const ClassScopeFunctionSpecializationDecl *D) { + Visit(D->getSpecialization()); + dumpASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten()); + } + void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); } + + void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + } + + void + VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) { + dumpTemplateArgumentList(D->getTemplateArgs()); + VisitVarDecl(D); + } + + void VisitVarTemplatePartialSpecializationDecl( + const VarTemplatePartialSpecializationDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + VisitVarTemplateSpecializationDecl(D); + } + + void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { + if (D->hasDefaultArgument()) + Visit(D->getDefaultArgument(), SourceRange(), + D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" : "previous"); + } + + void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { + if (D->hasDefaultArgument()) + Visit(D->getDefaultArgument(), SourceRange(), + D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" : "previous"); + } + + void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + if (D->hasDefaultArgument()) + dumpTemplateArgumentLoc( + D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" : "previous"); + } + + void VisitConceptDecl(const ConceptDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + Visit(D->getConstraintExpr()); + } + + void VisitUsingShadowDecl(const UsingShadowDecl *D) { + if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl())) + Visit(TD->getTypeForDecl()); + } + + void VisitFriendDecl(const FriendDecl *D) { + if (!D->getFriendType()) + Visit(D->getFriendDecl()); + } + + void VisitObjCMethodDecl(const ObjCMethodDecl *D) { + if (D->isThisDeclarationADefinition()) + dumpDeclContext(D); + else + for (const ParmVarDecl *Parameter : D->parameters()) + Visit(Parameter); + + if (D->hasBody()) + Visit(D->getBody()); + } + + void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { + dumpObjCTypeParamList(D->getTypeParamList()); + } + + void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { + dumpObjCTypeParamList(D->getTypeParamListAsWritten()); + } + + void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { + for (const auto &I : D->inits()) + Visit(I); + } + + void VisitBlockDecl(const BlockDecl *D) { + for (const auto &I : D->parameters()) + Visit(I); + + for (const auto &I : D->captures()) + Visit(I); + Visit(D->getBody()); + } + + void VisitDeclStmt(const DeclStmt *Node) { + for (const auto &D : Node->decls()) + Visit(D); + } + + void VisitAttributedStmt(const AttributedStmt *Node) { + for (const auto *A : Node->getAttrs()) + Visit(A); + } + + void VisitCXXCatchStmt(const CXXCatchStmt *Node) { + Visit(Node->getExceptionDecl()); + } + + void VisitCapturedStmt(const CapturedStmt *Node) { + Visit(Node->getCapturedDecl()); + } + + void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) { + for (const auto *C : Node->clauses()) + Visit(C); + } + + void VisitInitListExpr(const InitListExpr *ILE) { + if (auto *Filler = ILE->getArrayFiller()) { + Visit(Filler, "array_filler"); + } + } + + void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); } + + void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { + if (Expr *Source = Node->getSourceExpr()) + Visit(Source); + } + + void VisitGenericSelectionExpr(const GenericSelectionExpr *E) { + Visit(E->getControllingExpr()); + Visit(E->getControllingExpr()->getType()); // FIXME: remove + + for (const auto &Assoc : E->associations()) { + Visit(Assoc); + } + } + + void VisitLambdaExpr(const LambdaExpr *Node) { + Visit(Node->getLambdaClass()); + } + + void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { + if (Node->isPartiallySubstituted()) + for (const auto &A : Node->getPartialArguments()) + Visit(A); + } + + void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { + if (const VarDecl *CatchParam = Node->getCatchParamDecl()) + Visit(CatchParam); + } + + void VisitExpressionTemplateArgument(const TemplateArgument &TA) { + Visit(TA.getAsExpr()); + } + void VisitPackTemplateArgument(const TemplateArgument &TA) { + for (const auto &TArg : TA.pack_elements()) + Visit(TArg); + } + + // Implements Visit methods for Attrs. +#include "clang/AST/AttrNodeTraverse.inc" +}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h index f8847505bc72..70e0daa08a9a 100644 --- a/include/clang/AST/ASTStructuralEquivalence.h +++ b/include/clang/AST/ASTStructuralEquivalence.h @@ -1,9 +1,8 @@ //===- ASTStructuralEquivalence.h -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -112,6 +111,10 @@ struct StructuralEquivalenceContext { static llvm::Optional<unsigned> findUntaggedStructOrUnionIndex(RecordDecl *Anon); + // If ErrorOnTagTypeMismatch is set, return the the error, otherwise get the + // relevant warning for the input error diagnostic. + unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic); + private: /// Finish checking all of the structural equivalences. /// diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h index 9df9793370c4..a29a04e5d242 100644 --- a/include/clang/AST/ASTTypeTraits.h +++ b/include/clang/AST/ASTTypeTraits.h @@ -1,9 +1,8 @@ //===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,6 +18,7 @@ #include "clang/AST/ASTFwd.h" #include "clang/AST/Decl.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/Stmt.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TypeLoc.h" @@ -38,6 +38,17 @@ struct PrintingPolicy; namespace ast_type_traits { +/// Defines how we descend a level in the AST when we pass +/// through expressions. +enum TraversalKind { + /// Will traverse all child nodes. + TK_AsIs, + + /// Will not traverse implicit casts and parentheses. + /// Corresponds to Expr::IgnoreParenImpCasts() + TK_IgnoreImplicitCastsAndParentheses +}; + /// Kind identifier. /// /// It can be constructed from any node kind and allows for runtime type @@ -59,6 +70,7 @@ public: static ASTNodeKind getFromNode(const Decl &D); static ASTNodeKind getFromNode(const Stmt &S); static ASTNodeKind getFromNode(const Type &T); + static ASTNodeKind getFromNode(const OMPClause &C); /// \} /// Returns \c true if \c this and \c Other represent the same kind. @@ -137,6 +149,9 @@ private: NKI_Type, #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, #include "clang/AST/TypeNodes.def" + NKI_OMPClause, +#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class, +#include "clang/Basic/OpenMPKinds.def" NKI_NumberOfKinds }; @@ -184,12 +199,15 @@ KIND_TO_KIND_ID(TypeLoc) KIND_TO_KIND_ID(Decl) KIND_TO_KIND_ID(Stmt) KIND_TO_KIND_ID(Type) +KIND_TO_KIND_ID(OMPClause) #define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl) #include "clang/AST/DeclNodes.inc" #define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED) #include "clang/AST/StmtNodes.inc" #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) #include "clang/AST/TypeNodes.def" +#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class) +#include "clang/Basic/OpenMPKinds.def" #undef KIND_TO_KIND_ID inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) { @@ -460,6 +478,11 @@ struct DynTypedNode::BaseConverter< T, typename std::enable_if<std::is_base_of<Type, T>::value>::type> : public DynCastPtrConverter<T, Type> {}; +template <typename T> +struct DynTypedNode::BaseConverter< + T, typename std::enable_if<std::is_base_of<OMPClause, T>::value>::type> + : public DynCastPtrConverter<T, OMPClause> {}; + template <> struct DynTypedNode::BaseConverter< NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {}; diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h index 9bf63bb6e2d7..8d2b23b3539a 100644 --- a/include/clang/AST/ASTUnresolvedSet.h +++ b/include/clang/AST/ASTUnresolvedSet.h @@ -1,9 +1,8 @@ //===- ASTUnresolvedSet.h - Unresolved sets of declarations -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h index 51de119f080e..d5a04767ca13 100644 --- a/include/clang/AST/ASTVector.h +++ b/include/clang/AST/ASTVector.h @@ -1,9 +1,8 @@ //===- ASTVector.h - Vector that uses ASTContext for allocation ---*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 3a319326d269..1fbed7ceebfa 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -1,9 +1,8 @@ //===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h index 43ad1c931967..78ce9314a2bb 100644 --- a/include/clang/AST/AttrIterator.h +++ b/include/clang/AST/AttrIterator.h @@ -1,9 +1,8 @@ //===- AttrIterator.h - Classes for attribute iteration ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/AttrVisitor.h b/include/clang/AST/AttrVisitor.h index 867f9e7ad18d..d271db010ed1 100644 --- a/include/clang/AST/AttrVisitor.h +++ b/include/clang/AST/AttrVisitor.h @@ -1,9 +1,8 @@ //===- AttrVisitor.h - Visitor for Attr subclasses --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Availability.h b/include/clang/AST/Availability.h index 28f3c3c01d20..527fc4b59a5f 100644 --- a/include/clang/AST/Availability.h +++ b/include/clang/AST/Availability.h @@ -1,9 +1,8 @@ //===--- Availability.h - Classes for availability --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h index 8fd4ac69ebd6..15600f02fcef 100644 --- a/include/clang/AST/BaseSubobject.h +++ b/include/clang/AST/BaseSubobject.h @@ -1,9 +1,8 @@ //===- BaseSubobject.h - BaseSubobject class --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -81,11 +80,6 @@ template<> struct DenseMapInfo<clang::BaseSubobject> { } }; -// It's OK to treat BaseSubobject as a POD type. -template <> struct isPodLike<clang::BaseSubobject> { - static const bool value = true; -}; - } // namespace llvm #endif // LLVM_CLANG_AST_BASESUBOBJECT_H diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def index 400efcb1981f..74a45ee4ccc0 100644 --- a/include/clang/AST/BuiltinTypes.def +++ b/include/clang/AST/BuiltinTypes.def @@ -1,9 +1,8 @@ //===-- BuiltinTypes.def - Metadata about BuiltinTypes ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index f5e23f8e8505..bb2ad9c64d3b 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -1,9 +1,8 @@ //===- CXXInheritance.h - C++ Inheritance -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index c2f01e7d5460..2e00d344533d 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -1,9 +1,8 @@ //===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -510,7 +509,7 @@ struct CanProxyAdaptor<FunctionProtoType> } LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic) - LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getTypeQuals) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getMethodQuals) using param_type_iterator = CanTypeIterator<FunctionProtoType::param_type_iterator>; diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 0aadf06fffc9..37f489c7708a 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -1,9 +1,8 @@ //===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -238,10 +237,6 @@ template<> struct DenseMapInfo<clang::CharUnits> { } }; -template <> struct isPodLike<clang::CharUnits> { - static const bool value = true; -}; - } // end namespace llvm #endif // LLVM_CLANG_AST_CHARUNITS_H diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h index 1b590562e152..2c284a271bb7 100644 --- a/include/clang/AST/Comment.h +++ b/include/clang/AST/Comment.h @@ -1,9 +1,8 @@ //===--- Comment.h - Comment AST nodes --------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h index baa22930539e..cfd2137bd68c 100644 --- a/include/clang/AST/CommentBriefParser.h +++ b/include/clang/AST/CommentBriefParser.h @@ -1,9 +1,8 @@ //===--- CommentBriefParser.h - Dumb comment parser -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h index 4fd007872c01..83a29a540d42 100644 --- a/include/clang/AST/CommentCommandTraits.h +++ b/include/clang/AST/CommentCommandTraits.h @@ -1,9 +1,8 @@ //===--- CommentCommandTraits.h - Comment command properties ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h index b9816f1a8e62..2e498d5db386 100644 --- a/include/clang/AST/CommentDiagnostic.h +++ b/include/clang/AST/CommentDiagnostic.h @@ -1,9 +1,8 @@ //===--- CommentDiagnostic.h - Diagnostics for the AST library --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h index 3ef5b7c8c998..9ddbb7d31d99 100644 --- a/include/clang/AST/CommentLexer.h +++ b/include/clang/AST/CommentLexer.h @@ -1,9 +1,8 @@ //===--- CommentLexer.h - Lexer for structured comments ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h index fa8862899c14..1a0cfb06e52b 100644 --- a/include/clang/AST/CommentParser.h +++ b/include/clang/AST/CommentParser.h @@ -1,9 +1,8 @@ //===--- CommentParser.h - Doxygen comment parser ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index 632eba782b92..307618fa5363 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -1,9 +1,8 @@ //===--- CommentSema.h - Doxygen comment semantic analysis ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h index e37e9d6cd299..d9a7439f7cc0 100644 --- a/include/clang/AST/CommentVisitor.h +++ b/include/clang/AST/CommentVisitor.h @@ -1,9 +1,8 @@ //===- CommentVisitor.h - Visitor for Comment subclasses --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/ComparisonCategories.h b/include/clang/AST/ComparisonCategories.h index 23bfd708e7eb..9d591cc81495 100644 --- a/include/clang/AST/ComparisonCategories.h +++ b/include/clang/AST/ComparisonCategories.h @@ -1,9 +1,8 @@ //===- ComparisonCategories.h - Three Way Comparison Data -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/CurrentSourceLocExprScope.h b/include/clang/AST/CurrentSourceLocExprScope.h new file mode 100644 index 000000000000..4ebbdf63abb5 --- /dev/null +++ b/include/clang/AST/CurrentSourceLocExprScope.h @@ -0,0 +1,75 @@ +//===--- CurrentSourceLocExprScope.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines types used to track the current context needed to evaluate +// a SourceLocExpr. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H +#define LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H + +#include <cassert> + +namespace clang { +class Expr; + +/// Represents the current source location and context used to determine the +/// value of the source location builtins (ex. __builtin_LINE), including the +/// context of default argument and default initializer expressions. +class CurrentSourceLocExprScope { + /// The CXXDefaultArgExpr or CXXDefaultInitExpr we're currently evaluating. + const Expr *DefaultExpr = nullptr; + +public: + /// A RAII style scope guard used for tracking the current source + /// location and context as used by the source location builtins + /// (ex. __builtin_LINE). + class SourceLocExprScopeGuard; + + const Expr *getDefaultExpr() const { return DefaultExpr; } + + explicit CurrentSourceLocExprScope() = default; + +private: + explicit CurrentSourceLocExprScope(const Expr *DefaultExpr) + : DefaultExpr(DefaultExpr) {} + + CurrentSourceLocExprScope(CurrentSourceLocExprScope const &) = default; + CurrentSourceLocExprScope & + operator=(CurrentSourceLocExprScope const &) = default; +}; + +class CurrentSourceLocExprScope::SourceLocExprScopeGuard { +public: + SourceLocExprScopeGuard(const Expr *DefaultExpr, + CurrentSourceLocExprScope &Current) + : Current(Current), OldVal(Current), Enable(false) { + assert(DefaultExpr && "the new scope should not be empty"); + if ((Enable = (Current.getDefaultExpr() == nullptr))) + Current = CurrentSourceLocExprScope(DefaultExpr); + } + + ~SourceLocExprScopeGuard() { + if (Enable) + Current = OldVal; + } + +private: + SourceLocExprScopeGuard(SourceLocExprScopeGuard const &) = delete; + SourceLocExprScopeGuard &operator=(SourceLocExprScopeGuard const &) = delete; + + CurrentSourceLocExprScope &Current; + CurrentSourceLocExprScope OldVal; + bool Enable; +}; + +} // end namespace clang + +#endif // LLVM_CLANG_AST_CURRENT_SOURCE_LOC_EXPR_SCOPE_H diff --git a/include/clang/AST/DataCollection.h b/include/clang/AST/DataCollection.h index 8b2a8345d941..37f101793ecc 100644 --- a/include/clang/AST/DataCollection.h +++ b/include/clang/AST/DataCollection.h @@ -1,9 +1,8 @@ //===--- DatatCollection.h --------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index de2765391f0f..02742801f37c 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1,9 +1,8 @@ //===- Decl.h - Classes for representing declarations -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -1227,10 +1226,15 @@ public: void setInit(Expr *I); - /// Determine whether this variable's value can be used in a + /// Determine whether this variable's value might be usable in a /// constant expression, according to the relevant language standard. /// This only checks properties of the declaration, and does not check /// whether the initializer is in fact a constant expression. + bool mightBeUsableInConstantExpressions(ASTContext &C) const; + + /// Determine whether this variable's value can be used in a + /// constant expression, according to the relevant language standard, + /// including checking whether it was initialized by a constant expression. bool isUsableInConstantExpressions(ASTContext &C) const; EvaluatedStmt *ensureEvaluatedStmt() const; @@ -1396,6 +1400,10 @@ public: NonParmVarDeclBits.IsInitCapture = IC; } + /// Determine whether this variable is actually a function parameter pack or + /// init-capture pack. + bool isParameterPack() const; + /// Whether this local extern variable declaration's previous declaration /// was declared in the same block scope. Only correct in C++. bool isPreviousDeclInSameBlockScope() const { @@ -1435,6 +1443,12 @@ public: /// template specialization or instantiation this is. TemplateSpecializationKind getTemplateSpecializationKind() const; + /// Get the template specialization kind of this variable for the purposes of + /// template instantiation. This differs from getTemplateSpecializationKind() + /// for an instantiation of a class-scope explicit specialization. + TemplateSpecializationKind + getTemplateSpecializationKindForInstantiation() const; + /// If this variable is an instantiation of a variable template or a /// static data member of a class template, determine its point of /// instantiation. @@ -1683,10 +1697,6 @@ public: QualType getOriginalType() const; - /// Determine whether this parameter is actually a function - /// parameter pack. - bool isParameterPack() const; - /// Sets the function declaration that owns this /// ParmVarDecl. Since ParmVarDecls are often created before the /// FunctionDecls that own them, this routine is required to update @@ -1743,10 +1753,19 @@ class FunctionDecl : public DeclaratorDecl, public: /// The kind of templated function a FunctionDecl can be. enum TemplatedKind { + // Not templated. TK_NonTemplate, + // The pattern in a function template declaration. TK_FunctionTemplate, + // A non-template function that is an instantiation or explicit + // specialization of a member of a templated class. TK_MemberSpecialization, + // An instantiation or explicit specialization of a function template. + // Note: this might have been instantiated from a templated class if it + // is a class-scope explicit specialization. TK_FunctionTemplateSpecialization, + // A function template specialization that hasn't yet been resolved to a + // particular specialized function template. TK_DependentFunctionTemplateSpecialization }; @@ -1842,7 +1861,7 @@ protected: FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, - bool isConstexprSpecified); + ConstexprSpecKind ConstexprKind); using redeclarable_base = Redeclarable<FunctionDecl>; @@ -1872,29 +1891,24 @@ public: using redeclarable_base::getMostRecentDecl; using redeclarable_base::isFirstDecl; - static FunctionDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, SourceLocation NLoc, - DeclarationName N, QualType T, - TypeSourceInfo *TInfo, - StorageClass SC, - bool isInlineSpecified = false, - bool hasWrittenPrototype = true, - bool isConstexprSpecified = false) { + static FunctionDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation NLoc, DeclarationName N, QualType T, + TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false, + bool hasWrittenPrototype = true, + ConstexprSpecKind ConstexprKind = CSK_unspecified) { DeclarationNameInfo NameInfo(N, NLoc); - return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, - SC, + return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC, isInlineSpecified, hasWrittenPrototype, - isConstexprSpecified); + ConstexprKind); } static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - StorageClass SC, - bool isInlineSpecified, - bool hasWrittenPrototype, - bool isConstexprSpecified = false); + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, StorageClass SC, + bool isInlineSpecified, bool hasWrittenPrototype, + ConstexprSpecKind ConstexprKind); static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2091,8 +2105,21 @@ public: } /// Whether this is a (C++11) constexpr function or constexpr constructor. - bool isConstexpr() const { return FunctionDeclBits.IsConstexpr; } - void setConstexpr(bool IC) { FunctionDeclBits.IsConstexpr = IC; } + bool isConstexpr() const { + return FunctionDeclBits.ConstexprKind != CSK_unspecified; + } + void setConstexprKind(ConstexprSpecKind CSK) { + FunctionDeclBits.ConstexprKind = CSK; + } + ConstexprSpecKind getConstexprKind() const { + return static_cast<ConstexprSpecKind>(FunctionDeclBits.ConstexprKind); + } + bool isConstexprSpecified() const { + return FunctionDeclBits.ConstexprKind == CSK_constexpr; + } + bool isConsteval() const { + return FunctionDeclBits.ConstexprKind == CSK_consteval; + } /// Whether the instantiation of this function is pending. /// This bit is set when the decision to instantiate this function is made @@ -2256,7 +2283,7 @@ public: return const_cast<FunctionDecl*>(this)->getCanonicalDecl(); } - unsigned getBuiltinID() const; + unsigned getBuiltinID(bool ConsiderWrapperFunctions = false) const; // ArrayRef interface to parameters. ArrayRef<ParmVarDecl *> parameters() const { @@ -2316,6 +2343,14 @@ public: return T->castAs<FunctionType>()->getReturnType(); } + /// Gets the ExceptionSpecificationType as declared. + ExceptionSpecificationType getExceptionSpecType() const { + auto *TSI = getTypeSourceInfo(); + QualType T = TSI ? TSI->getType() : getType(); + const auto *FPT = T->getAs<FunctionProtoType>(); + return FPT ? FPT->getExceptionSpecType() : EST_None; + } + /// Attempt to compute an informative source range covering the /// function exception specification, if any. SourceRange getExceptionSpecSourceRange() const; @@ -2355,22 +2390,14 @@ public: /// that was defined in the class body. bool isInlined() const { return FunctionDeclBits.IsInline; } - /// Whether this function is marked as explicit explicitly. - bool isExplicitSpecified() const { - return FunctionDeclBits.IsExplicitSpecified; - } - - /// State that this function is marked as explicit explicitly. - void setExplicitSpecified(bool ExpSpec = true) { - FunctionDeclBits.IsExplicitSpecified = ExpSpec; - } - bool isInlineDefinitionExternallyVisible() const; bool isMSExternInline() const; bool doesDeclarationForceExternallyVisibleDefinition() const; + bool isStatic() const { return getStorageClass() == SC_Static; } + /// Whether this function declaration represents an C++ overloaded /// operator, e.g., "operator+". bool isOverloadedOperator() const { @@ -2441,10 +2468,6 @@ public: return getPrimaryTemplate() != nullptr; } - /// Retrieve the class scope template pattern that this function - /// template specialization is instantiated from. - FunctionDecl *getClassScopeSpecializationPattern() const; - /// If this function is actually a function template specialization, /// retrieve information about this function template specialization. /// Otherwise, returns NULL. @@ -2531,6 +2554,11 @@ public: /// represents. TemplateSpecializationKind getTemplateSpecializationKind() const; + /// Determine the kind of template specialization this function represents + /// for the purpose of template instantiation. + TemplateSpecializationKind + getTemplateSpecializationKindForInstantiation() const; + /// Determine what kind of template instantiation this function /// represents. void setTemplateSpecializationKind(TemplateSpecializationKind TSK, @@ -2703,6 +2731,11 @@ public: /// bit-fields. bool isZeroLengthBitField(const ASTContext &Ctx) const; + /// Determine if this field is a subobject of zero size, that is, either a + /// zero-length bit-field or a field of empty class type with the + /// [[no_unique_address]] attribute. + bool isZeroSize(const ASTContext &Ctx) const; + /// Get the kind of (C++11) default member initializer that this field has. InClassInitStyle getInClassInitStyle() const { InitStorageKind storageKind = InitStorage.getInt(); @@ -3713,6 +3746,30 @@ public: RecordDeclBits.NonTrivialToPrimitiveDestroy = V; } + bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const { + return RecordDeclBits.HasNonTrivialToPrimitiveDefaultInitializeCUnion; + } + + void setHasNonTrivialToPrimitiveDefaultInitializeCUnion(bool V) { + RecordDeclBits.HasNonTrivialToPrimitiveDefaultInitializeCUnion = V; + } + + bool hasNonTrivialToPrimitiveDestructCUnion() const { + return RecordDeclBits.HasNonTrivialToPrimitiveDestructCUnion; + } + + void setHasNonTrivialToPrimitiveDestructCUnion(bool V) { + RecordDeclBits.HasNonTrivialToPrimitiveDestructCUnion = V; + } + + bool hasNonTrivialToPrimitiveCopyCUnion() const { + return RecordDeclBits.HasNonTrivialToPrimitiveCopyCUnion; + } + + void setHasNonTrivialToPrimitiveCopyCUnion(bool V) { + RecordDeclBits.HasNonTrivialToPrimitiveCopyCUnion = V; + } + /// Determine whether this class can be passed in registers. In C++ mode, /// it must have at least one trivial, non-deleted copy or move constructor. /// FIXME: This should be set as part of completeDefinition. @@ -3852,7 +3909,7 @@ public: static bool classofKind(Kind K) { return K == FileScopeAsm; } }; -/// Pepresents a block literal declaration, which is like an +/// Represents a block literal declaration, which is like an /// unnamed FunctionDecl. For example: /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } class BlockDecl : public Decl, public DeclContext { @@ -4009,6 +4066,13 @@ public: bool doesNotEscape() const { return BlockDeclBits.DoesNotEscape; } void setDoesNotEscape(bool B = true) { BlockDeclBits.DoesNotEscape = B; } + bool canAvoidCopyToHeap() const { + return BlockDeclBits.CanAvoidCopyToHeap; + } + void setCanAvoidCopyToHeap(bool B = true) { + BlockDeclBits.CanAvoidCopyToHeap = B; + } + bool capturesVariable(const VarDecl *var) const; void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures, @@ -4233,8 +4297,10 @@ public: SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + bool hasBraces() const { return RBraceLoc.isValid(); } + SourceLocation getEndLoc() const LLVM_READONLY { - if (RBraceLoc.isValid()) + if (hasBraces()) return RBraceLoc; // No braces: get the end location of the (only) declaration in context // (if present). diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h index 3c5056c6e55b..805342c2910a 100644 --- a/include/clang/AST/DeclAccessPair.h +++ b/include/clang/AST/DeclAccessPair.h @@ -1,9 +1,8 @@ //===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -61,12 +60,4 @@ public: }; } -// Take a moment to tell SmallVector that DeclAccessPair is POD. -namespace llvm { -template<typename> struct isPodLike; -template<> struct isPodLike<clang::DeclAccessPair> { - static const bool value = true; -}; -} - #endif diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 8405a43fa098..d64d0cb425db 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -1,9 +1,8 @@ //===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,6 +13,7 @@ #ifndef LLVM_CLANG_AST_DECLBASE_H #define LLVM_CLANG_AST_DECLBASE_H +#include "clang/AST/ASTDumperUtils.h" #include "clang/AST/AttrIterator.h" #include "clang/AST/DeclarationName.h" #include "clang/Basic/IdentifierTable.h" @@ -42,6 +42,7 @@ namespace clang { class ASTContext; class ASTMutationListener; class Attr; +class BlockDecl; class DeclContext; class ExternalSourceSymbolAttr; class FunctionDecl; @@ -176,7 +177,10 @@ public: IDNS_LocalExtern = 0x0800, /// This declaration is an OpenMP user defined reduction construction. - IDNS_OMPReduction = 0x1000 + IDNS_OMPReduction = 0x1000, + + /// This declaration is an OpenMP user defined mapper. + IDNS_OMPMapper = 0x2000, }; /// ObjCDeclQualifier - 'Qualifiers' written next to the return and @@ -324,7 +328,7 @@ protected: unsigned FromASTFile : 1; /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. - unsigned IdentifierNamespace : 13; + unsigned IdentifierNamespace : 14; /// If 0, we have not computed the linkage of this declaration. /// Otherwise, it is the linkage + 1. @@ -364,6 +368,13 @@ private: return ModuleOwnershipKind::Unowned; } +public: + Decl() = delete; + Decl(const Decl&) = delete; + Decl(Decl &&) = delete; + Decl &operator=(const Decl&) = delete; + Decl &operator=(Decl&&) = delete; + protected: Decl(Kind DK, DeclContext *DC, SourceLocation L) : NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)), @@ -597,10 +608,6 @@ public: return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate; } - /// Whether this declaration is exported (by virtue of being lexically - /// within an ExportDecl or by being a NamespaceDecl). - bool isExported() const; - /// Return true if this declaration has an attribute which acts as /// definition of the entity, such as 'alias' or 'ifunc'. bool hasDefiningAttr() const; @@ -1135,7 +1142,8 @@ public: // Same as dump(), but forces color printing. void dumpColor() const; - void dump(raw_ostream &Out, bool Deserialize = false) const; + void dump(raw_ostream &Out, bool Deserialize = false, + ASTDumpOutputFormat OutputFormat = ADOF_Default) const; /// \return Unique reproducible object identifier int64_t getID() const; @@ -1252,6 +1260,7 @@ public: /// NamespaceDecl /// TagDecl /// OMPDeclareReductionDecl +/// OMPDeclareMapperDecl /// FunctionDecl /// ObjCMethodDecl /// ObjCContainerDecl @@ -1431,6 +1440,13 @@ class DeclContext { uint64_t NonTrivialToPrimitiveCopy : 1; uint64_t NonTrivialToPrimitiveDestroy : 1; + /// The following bits indicate whether this is or contains a C union that + /// is non-trivial to default-initialize, destruct, or copy. These bits + /// imply the associated basic non-triviality predicates declared above. + uint64_t HasNonTrivialToPrimitiveDefaultInitializeCUnion : 1; + uint64_t HasNonTrivialToPrimitiveDestructCUnion : 1; + uint64_t HasNonTrivialToPrimitiveCopyCUnion : 1; + /// Indicates whether this struct is destroyed in the callee. uint64_t ParamDestroyedInCallee : 1; @@ -1439,7 +1455,7 @@ class DeclContext { }; /// Number of non-inherited bits in RecordDeclBitfields. - enum { NumRecordDeclBits = 11 }; + enum { NumRecordDeclBits = 14 }; /// Stores the bits used by OMPDeclareReductionDecl. /// If modified NumOMPDeclareReductionDeclBits and the accessor @@ -1472,10 +1488,6 @@ class DeclContext { uint64_t IsInline : 1; uint64_t IsInlineSpecified : 1; - /// This is shared by CXXConstructorDecl, - /// CXXConversionDecl, and CXXDeductionGuideDecl. - uint64_t IsExplicitSpecified : 1; - uint64_t IsVirtualAsWritten : 1; uint64_t IsPure : 1; uint64_t HasInheritedPrototype : 1; @@ -1495,7 +1507,9 @@ class DeclContext { uint64_t IsExplicitlyDefaulted : 1; uint64_t HasImplicitReturnZero : 1; uint64_t IsLateTemplateParsed : 1; - uint64_t IsConstexpr : 1; + + /// Kind of contexpr specifier as defined by ConstexprSpecKind. + uint64_t ConstexprKind : 2; uint64_t InstantiationIsPending : 1; /// Indicates if the function uses __try. @@ -1535,17 +1549,25 @@ class DeclContext { /// For the bits in FunctionDeclBitfields. uint64_t : NumFunctionDeclBits; - /// 25 bits to fit in the remaining availible space. + /// 24 bits to fit in the remaining available space. /// Note that this makes CXXConstructorDeclBitfields take /// exactly 64 bits and thus the width of NumCtorInitializers /// will need to be shrunk if some bit is added to NumDeclContextBitfields, /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields. - uint64_t NumCtorInitializers : 25; + uint64_t NumCtorInitializers : 23; uint64_t IsInheritingConstructor : 1; + + /// Whether this constructor has a trail-allocated explicit specifier. + uint64_t HasTrailingExplicitSpecifier : 1; + /// If this constructor does't have a trail-allocated explicit specifier. + /// Whether this constructor is explicit specified. + uint64_t IsSimpleExplicit : 1; }; /// Number of non-inherited bits in CXXConstructorDeclBitfields. - enum { NumCXXConstructorDeclBits = 26 }; + enum { + NumCXXConstructorDeclBits = 64 - NumDeclContextBits - NumFunctionDeclBits + }; /// Stores the bits used by ObjCMethodDecl. /// If modified NumObjCMethodDeclBits and the accessor @@ -1662,6 +1684,11 @@ class DeclContext { /// A bit that indicates this block is passed directly to a function as a /// non-escaping parameter. uint64_t DoesNotEscape : 1; + + /// A bit that indicates whether it's possible to avoid coying this block to + /// the heap when it initializes or is assigned to a local variable with + /// automatic storage. + uint64_t CanAvoidCopyToHeap : 1; }; /// Number of non-inherited bits in BlockDeclBitfields. @@ -1784,6 +1811,10 @@ public: bool isClosure() const { return getDeclKind() == Decl::Block; } + /// Return this DeclContext if it is a BlockDecl. Otherwise, return the + /// innermost enclosing BlockDecl or null if there are no enclosing blocks. + const BlockDecl *getInnermostBlockDecl() const; + bool isObjCContainer() const { switch (getDeclKind()) { case Decl::ObjCCategory: diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index d3357c245d86..7add83f89624 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1,9 +1,8 @@ //===- DeclCXX.h - Classes for representing C++ declarations --*- C++ -*-=====// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -64,6 +63,7 @@ class CXXDestructorDecl; class CXXFinalOverriderMap; class CXXIndirectPrimaryBaseSet; class CXXMethodDecl; +class DecompositionDecl; class DiagnosticBuilder; class FriendDecl; class FunctionTemplateDecl; @@ -334,10 +334,12 @@ class CXXRecordDecl : public RecordDecl { /// True when this class is a POD-type. unsigned PlainOldData : 1; - /// true when this class is empty for traits purposes, - /// i.e. has no data members other than 0-width bit-fields, has no - /// virtual function/base, and doesn't inherit from a non-empty - /// class. Doesn't take union-ness into account. + /// True when this class is empty for traits purposes, that is: + /// * has no data members other than 0-width bit-fields and empty fields + /// marked [[no_unique_address]] + /// * has no virtual function/base, and + /// * doesn't inherit from a non-empty class. + /// Doesn't take union-ness into account. unsigned Empty : 1; /// True when this class is polymorphic, i.e., has at @@ -1222,6 +1224,9 @@ public: /// lambda. TemplateParameterList *getGenericLambdaTemplateParameterList() const; + /// Retrieve the lambda template parameters that were specified explicitly. + ArrayRef<NamedDecl *> getLambdaExplicitTemplateParameters() const; + LambdaCaptureDefault getLambdaCaptureDefault() const { assert(isLambda()); return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault); @@ -1326,6 +1331,14 @@ public: /// \note This does NOT include a check for union-ness. bool isEmpty() const { return data().Empty; } + bool hasPrivateFields() const { + return data().HasPrivateFields; + } + + bool hasProtectedFields() const { + return data().HasProtectedFields; + } + /// Determine whether this class has direct non-static data members. bool hasDirectFields() const { auto &D = data(); @@ -1829,6 +1842,14 @@ public: CXXBasePath &Path, DeclarationName Name); /// Base-class lookup callback that determines whether there exists + /// an OpenMP declare mapper member with the given name. + /// + /// This callback can be used with \c lookupInBases() to find members + /// of the given name within a C++ class hierarchy. + static bool FindOMPMapperMember(const CXXBaseSpecifier *Specifier, + CXXBasePath &Path, DeclarationName Name); + + /// Base-class lookup callback that determines whether there exists /// a member with the given name that can be used in a nested-name-specifier. /// /// This callback can be used with \c lookupInBases() to find members of @@ -1975,6 +1996,53 @@ public: } }; +/// Store information needed for an explicit specifier. +/// used by CXXDeductionGuideDecl, CXXConstructorDecl and CXXConversionDecl. +class ExplicitSpecifier { + llvm::PointerIntPair<Expr *, 2, ExplicitSpecKind> ExplicitSpec{ + nullptr, ExplicitSpecKind::ResolvedFalse}; + +public: + ExplicitSpecifier() = default; + ExplicitSpecifier(Expr *Expression, ExplicitSpecKind Kind) + : ExplicitSpec(Expression, Kind) {} + ExplicitSpecKind getKind() const { return ExplicitSpec.getInt(); } + const Expr *getExpr() const { return ExplicitSpec.getPointer(); } + Expr *getExpr() { return ExplicitSpec.getPointer(); } + + /// Return true if the ExplicitSpecifier isn't defaulted. + bool isSpecified() const { + return ExplicitSpec.getInt() != ExplicitSpecKind::ResolvedFalse || + ExplicitSpec.getPointer(); + } + + /// Check for Equivalence of explicit specifiers. + /// Return True if the explicit specifier are equivalent false otherwise. + bool isEquivalent(const ExplicitSpecifier Other) const; + /// Return true if the explicit specifier is already resolved to be explicit. + bool isExplicit() const { + return ExplicitSpec.getInt() == ExplicitSpecKind::ResolvedTrue; + } + /// Return true if the ExplicitSpecifier isn't valid. + /// This state occurs after a substitution failures. + bool isInvalid() const { + return ExplicitSpec.getInt() == ExplicitSpecKind::Unresolved && + !ExplicitSpec.getPointer(); + } + void setKind(ExplicitSpecKind Kind) { ExplicitSpec.setInt(Kind); } + void setExpr(Expr *E) { ExplicitSpec.setPointer(E); } + // getFromDecl - retrieve the explicit specifier in the given declaration. + // if the given declaration has no explicit. the returned explicit specifier + // is defaulted. .isSpecified() will be false. + static ExplicitSpecifier getFromDecl(FunctionDecl *Function); + static const ExplicitSpecifier getFromDecl(const FunctionDecl *Function) { + return getFromDecl(const_cast<FunctionDecl *>(Function)); + } + static ExplicitSpecifier Invalid() { + return ExplicitSpecifier(nullptr, ExplicitSpecKind::Unresolved); + } +}; + /// Represents a C++ deduction guide declaration. /// /// \code @@ -1990,31 +2058,36 @@ class CXXDeductionGuideDecl : public FunctionDecl { private: CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - bool IsExplicit, const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - SourceLocation EndLocation) + ExplicitSpecifier ES, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, SourceLocation EndLocation) : FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo, - SC_None, false, false) { + SC_None, false, CSK_unspecified), + ExplicitSpec(ES) { if (EndLocation.isValid()) setRangeEnd(EndLocation); - setExplicitSpecified(IsExplicit); setIsCopyDeductionCandidate(false); } + ExplicitSpecifier ExplicitSpec; + void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } + public: friend class ASTDeclReader; friend class ASTDeclWriter; - static CXXDeductionGuideDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, bool IsExplicit, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - SourceLocation EndLocation); + static CXXDeductionGuideDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + ExplicitSpecifier ES, 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(); } + ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; } + const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; } + + /// Return true if the declartion is already resolved to be explicit. + bool isExplicit() const { return ExplicitSpec.isExplicit(); } /// Get the template for which this guide performs deduction. TemplateDecl *getDeducedTemplate() const { @@ -2044,11 +2117,11 @@ class CXXMethodDecl : public FunctionDecl { protected: CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - StorageClass SC, bool isInline, - bool isConstexpr, SourceLocation EndLocation) - : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, - SC, isInline, isConstexpr) { + QualType T, TypeSourceInfo *TInfo, StorageClass SC, + bool isInline, ConstexprSpecKind ConstexprKind, + SourceLocation EndLocation) + : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, isInline, + ConstexprKind) { if (EndLocation.isValid()) setRangeEnd(EndLocation); } @@ -2056,11 +2129,9 @@ protected: public: static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - StorageClass SC, - bool isInline, - bool isConstexpr, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, StorageClass SC, + bool isInline, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation); static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2161,20 +2232,20 @@ public: overridden_method_range overridden_methods() const; - /// Returns the parent of this method declaration, which + /// Return the parent of this method declaration, which /// is the class in which this method is defined. const CXXRecordDecl *getParent() const { return cast<CXXRecordDecl>(FunctionDecl::getParent()); } - /// Returns the parent of this method declaration, which + /// Return the parent of this method declaration, which /// is the class in which this method is defined. CXXRecordDecl *getParent() { return const_cast<CXXRecordDecl *>( cast<CXXRecordDecl>(FunctionDecl::getParent())); } - /// Returns the type of the \c this pointer. + /// Return the type of the \c this pointer. /// /// Should only be called for instance (i.e., non-static) methods. Note /// that for the call operator of a lambda closure type, this returns the @@ -2182,11 +2253,19 @@ public: /// 'this' type. QualType getThisType() const; + /// Return the type of the object pointed by \c this. + /// + /// See getThisType() for usage restriction. + QualType getThisObjectType() const; + static QualType getThisType(const FunctionProtoType *FPT, const CXXRecordDecl *Decl); - Qualifiers getTypeQualifiers() const { - return getType()->getAs<FunctionProtoType>()->getTypeQuals(); + static QualType getThisObjectType(const FunctionProtoType *FPT, + const CXXRecordDecl *Decl); + + Qualifiers getMethodQualifiers() const { + return getType()->getAs<FunctionProtoType>()->getMethodQuals(); } /// Retrieve the ref-qualifier associated with this method. @@ -2231,6 +2310,17 @@ public: ->getCorrespondingMethodInClass(RD, MayBeBase); } + /// Find if \p RD declares a function that overrides this function, and if so, + /// return it. Does not search base classes. + CXXMethodDecl *getCorrespondingMethodDeclaredInClass(const CXXRecordDecl *RD, + bool MayBeBase = false); + const CXXMethodDecl * + getCorrespondingMethodDeclaredInClass(const CXXRecordDecl *RD, + bool MayBeBase = false) const { + return const_cast<CXXMethodDecl *>(this) + ->getCorrespondingMethodDeclaredInClass(RD, MayBeBase); + } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { @@ -2483,7 +2573,8 @@ public: /// \endcode class CXXConstructorDecl final : public CXXMethodDecl, - private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> { + private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor, + ExplicitSpecifier> { // This class stores some data in DeclContext::CXXConstructorDeclBits // to save some space. Use the provided accessors to access it. @@ -2493,28 +2584,74 @@ class CXXConstructorDecl final LazyCXXCtorInitializersPtr CtorInitializers; CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isExplicitSpecified, bool isInline, - bool isImplicitlyDeclared, bool isConstexpr, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool isInline, + bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited); void anchor() override; + size_t numTrailingObjects(OverloadToken<InheritedConstructor>) const { + return CXXConstructorDeclBits.IsInheritingConstructor; + } + size_t numTrailingObjects(OverloadToken<ExplicitSpecifier>) const { + return CXXConstructorDeclBits.HasTrailingExplicitSpecifier; + } + + ExplicitSpecifier getExplicitSpecifierInternal() const { + if (CXXConstructorDeclBits.HasTrailingExplicitSpecifier) + return *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>(); + return ExplicitSpecifier( + nullptr, getCanonicalDecl()->CXXConstructorDeclBits.IsSimpleExplicit + ? ExplicitSpecKind::ResolvedTrue + : ExplicitSpecKind::ResolvedFalse); + } + + void setExplicitSpecifier(ExplicitSpecifier ES) { + assert((!ES.getExpr() || + CXXConstructorDeclBits.HasTrailingExplicitSpecifier) && + "cannot set this explicit specifier. no trail-allocated space for " + "explicit"); + if (ES.getExpr()) + *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>() = ES; + else + CXXConstructorDeclBits.IsSimpleExplicit = ES.isExplicit(); + } + + enum TraillingAllocKind { + TAKInheritsConstructor = 1, + TAKHasTailExplicit = 1 << 1, + }; + + uint64_t getTraillingAllocKind() const { + return numTrailingObjects(OverloadToken<InheritedConstructor>()) | + (numTrailingObjects(OverloadToken<ExplicitSpecifier>()) << 1); + } + public: friend class ASTDeclReader; friend class ASTDeclWriter; friend TrailingObjects; static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID, - bool InheritsConstructor); + uint64_t AllocKind); static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isExplicit, bool isInline, bool isImplicitlyDeclared, - bool isConstexpr, + ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, + ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited = InheritedConstructor()); + ExplicitSpecifier getExplicitSpecifier() { + return getExplicitSpecifierInternal(); + } + const ExplicitSpecifier getExplicitSpecifier() const { + return getExplicitSpecifierInternal(); + } + + /// Return true if the declartion is already resolved to be explicit. + bool isExplicit() const { return getExplicitSpecifier().isExplicit(); } + /// Iterates through the member/base initializer list. using init_iterator = CXXCtorInitializer **; @@ -2585,11 +2722,6 @@ public: CtorInitializers = Initializers; } - /// Whether this function is explicit. - bool isExplicit() const { - return getCanonicalDecl()->isExplicitSpecified(); - } - /// Determine whether this constructor is a delegating constructor. bool isDelegatingConstructor() const { return (getNumCtorInitializers() == 1) && @@ -2713,12 +2845,11 @@ class CXXDestructorDecl : public CXXMethodDecl { Expr *OperatorDeleteThisArg = nullptr; CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, /*isConstexpr=*/false, SourceLocation()) - { + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, bool isInline, + bool isImplicitlyDeclared) + : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo, + SC_None, isInline, CSK_unspecified, SourceLocation()) { setImplicit(isImplicitlyDeclared); } @@ -2768,34 +2899,39 @@ public: class CXXConversionDecl : public CXXMethodDecl { CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, - TypeSourceInfo *TInfo, bool isInline, - bool isExplicitSpecified, bool isConstexpr, - SourceLocation EndLocation) + TypeSourceInfo *TInfo, bool isInline, ExplicitSpecifier ES, + ConstexprSpecKind ConstexprKind, SourceLocation EndLocation) : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, isConstexpr, EndLocation) { - setExplicitSpecified(isExplicitSpecified); - } - + SC_None, isInline, ConstexprKind, EndLocation), + ExplicitSpec(ES) {} void anchor() override; + ExplicitSpecifier ExplicitSpec; + + void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } + public: friend class ASTDeclReader; friend class ASTDeclWriter; - static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isInline, bool isExplicit, - bool isConstexpr, - SourceLocation EndLocation); + static CXXConversionDecl * + Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, + SourceLocation EndLocation); static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); - /// Whether this function is explicit. - bool isExplicit() const { - return getCanonicalDecl()->isExplicitSpecified(); + ExplicitSpecifier getExplicitSpecifier() { + return getCanonicalDecl()->ExplicitSpec; + } + + const ExplicitSpecifier getExplicitSpecifier() const { + return getCanonicalDecl()->ExplicitSpec; } + /// Return true if the declartion is already resolved to be explicit. + bool isExplicit() const { return getExplicitSpecifier().isExplicit(); } + /// Returns the type that this conversion function is converting to. QualType getConversionType() const { return getType()->getAs<FunctionType>()->getReturnType(); @@ -3793,6 +3929,8 @@ public: /// x[0], x[1], and x[2] respectively, where x is the implicit /// DecompositionDecl of type 'int (&)[3]'. class BindingDecl : public ValueDecl { + /// The declaration that this binding binds to part of. + LazyDeclPtr Decomp; /// The binding represented by this declaration. References to this /// declaration are effectively equivalent to this expression (except /// that it is only evaluated once at the point of declaration of the @@ -3816,6 +3954,10 @@ public: /// decomposition declaration, and when the initializer is type-dependent. Expr *getBinding() const { return Binding; } + /// Get the decomposition declaration that this binding represents a + /// decomposition of. + ValueDecl *getDecomposedDecl() const; + /// Get the variable (if any) that holds the value of evaluating the binding. /// Only present for user-defined bindings for tuple-like types. VarDecl *getHoldingVar() const; @@ -3828,6 +3970,9 @@ public: this->Binding = Binding; } + /// Set the decomposed variable for this BindingDecl. + void setDecomposedDecl(ValueDecl *Decomposed) { Decomp = Decomposed; } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::Binding; } }; @@ -3855,6 +4000,8 @@ class DecompositionDecl final NumBindings(Bindings.size()) { std::uninitialized_copy(Bindings.begin(), Bindings.end(), getTrailingObjects<BindingDecl *>()); + for (auto *B : Bindings) + B->setDecomposedDecl(this); } void anchor() override; diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h index ccd82d2cf0d2..e6a4cd4381e4 100644 --- a/include/clang/AST/DeclContextInternals.h +++ b/include/clang/AST/DeclContextInternals.h @@ -1,9 +1,8 @@ //===- DeclContextInternals.h - DeclContext Representation ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -114,12 +113,11 @@ public: } DeclsTy &Vec = *getAsVector(); - DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D); + DeclsTy::iterator I = llvm::find(Vec, D); assert(I != Vec.end() && "list does not contain decl"); Vec.erase(I); - assert(std::find(Vec.begin(), Vec.end(), D) - == Vec.end() && "list still contains decl"); + assert(llvm::find(Vec, D) == Vec.end() && "list still contains decl"); } /// Remove any declarations which were imported from an external diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index b5808f23de6f..6f8306c6025e 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -1,9 +1,8 @@ //===- DeclFriend.h - Classes for C++ friend declarations -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h index 6d5aaadf529c..2be9dae9431e 100644 --- a/include/clang/AST/DeclGroup.h +++ b/include/clang/AST/DeclGroup.h @@ -1,9 +1,8 @@ //===- DeclGroup.h - Classes for representing groups of Decls ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h index 9627f440d406..41c8999736ea 100644 --- a/include/clang/AST/DeclLookups.h +++ b/include/clang/AST/DeclLookups.h @@ -1,9 +1,8 @@ //===- DeclLookups.h - Low-level interface to all names in a DC -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 5b57411f9785..8d85ac36d861 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1,9 +1,8 @@ //===- DeclObjC.h - Classes for representing declarations -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h index 8540cc5b25b6..437feaba28fb 100644 --- a/include/clang/AST/DeclOpenMP.h +++ b/include/clang/AST/DeclOpenMP.h @@ -1,9 +1,8 @@ //===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -207,6 +206,102 @@ public: } }; +/// This represents '#pragma omp declare mapper ...' directive. Map clauses are +/// allowed to use with this directive. The following example declares a user +/// defined mapper for the type 'struct vec'. This example instructs the fields +/// 'len' and 'data' should be mapped when mapping instances of 'struct vec'. +/// +/// \code +/// #pragma omp declare mapper(mid: struct vec v) map(v.len, v.data[0:N]) +/// \endcode +class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext { + friend class ASTDeclReader; + + /// Clauses associated with this mapper declaration + MutableArrayRef<OMPClause *> Clauses; + + /// Mapper variable, which is 'v' in the example above + Expr *MapperVarRef = nullptr; + + /// Name of the mapper variable + DeclarationName VarName; + + LazyDeclPtr PrevDeclInScope; + + virtual void anchor(); + + OMPDeclareMapperDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName Name, QualType Ty, + DeclarationName VarName, + OMPDeclareMapperDecl *PrevDeclInScope) + : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), VarName(VarName), + PrevDeclInScope(PrevDeclInScope) {} + + void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) { + PrevDeclInScope = Prev; + } + + /// Sets an array of clauses to this mapper declaration + void setClauses(ArrayRef<OMPClause *> CL); + +public: + /// Creates declare mapper node. + static OMPDeclareMapperDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, DeclarationName Name, + QualType T, DeclarationName VarName, + OMPDeclareMapperDecl *PrevDeclInScope); + /// Creates deserialized declare mapper node. + static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned N); + + /// Creates an array of clauses to this mapper declaration and intializes + /// them. + void CreateClauses(ASTContext &C, ArrayRef<OMPClause *> CL); + + using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator; + using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator; + using clauselist_range = llvm::iterator_range<clauselist_iterator>; + using clauselist_const_range = + llvm::iterator_range<clauselist_const_iterator>; + + unsigned clauselist_size() const { return Clauses.size(); } + bool clauselist_empty() const { return Clauses.empty(); } + + clauselist_range clauselists() { + return clauselist_range(clauselist_begin(), clauselist_end()); + } + clauselist_const_range clauselists() const { + return clauselist_const_range(clauselist_begin(), clauselist_end()); + } + clauselist_iterator clauselist_begin() { return Clauses.begin(); } + clauselist_iterator clauselist_end() { return Clauses.end(); } + clauselist_const_iterator clauselist_begin() const { return Clauses.begin(); } + clauselist_const_iterator clauselist_end() const { return Clauses.end(); } + + /// Get the variable declared in the mapper + Expr *getMapperVarRef() { return MapperVarRef; } + const Expr *getMapperVarRef() const { return MapperVarRef; } + /// Set the variable declared in the mapper + void setMapperVarRef(Expr *MapperVarRefE) { MapperVarRef = MapperVarRefE; } + + /// Get the name of the variable declared in the mapper + DeclarationName getVarName() { return VarName; } + + /// Get reference to previous declare mapper construct in the same + /// scope with the same name. + OMPDeclareMapperDecl *getPrevDeclInScope(); + const OMPDeclareMapperDecl *getPrevDeclInScope() const; + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPDeclareMapper; } + static DeclContext *castToDeclContext(const OMPDeclareMapperDecl *D) { + return static_cast<DeclContext *>(const_cast<OMPDeclareMapperDecl *>(D)); + } + static OMPDeclareMapperDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast<OMPDeclareMapperDecl *>(const_cast<DeclContext *>(DC)); + } +}; + /// Pseudo declaration for capturing expressions. Also is used for capturing of /// non-static data members in non-static member functions. /// @@ -310,6 +405,119 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == OMPRequires; } }; + +/// This represents '#pragma omp allocate ...' directive. +/// For example, in the following, the default allocator is used for both 'a' +/// and 'A::b': +/// +/// \code +/// int a; +/// #pragma omp allocate(a) +/// struct A { +/// static int b; +/// #pragma omp allocate(b) +/// }; +/// \endcode +/// +class OMPAllocateDecl final + : public Decl, + private llvm::TrailingObjects<OMPAllocateDecl, Expr *, OMPClause *> { + friend class ASTDeclReader; + friend TrailingObjects; + + /// Number of variable within the allocate directive. + unsigned NumVars = 0; + /// Number of clauses associated with the allocate directive. + unsigned NumClauses = 0; + + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return NumVars; + } + size_t numTrailingObjects(OverloadToken<OMPClause *>) const { + return NumClauses; + } + + virtual void anchor(); + + OMPAllocateDecl(Kind DK, DeclContext *DC, SourceLocation L) + : Decl(DK, DC, L) {} + + ArrayRef<const Expr *> getVars() const { + return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars); + } + + MutableArrayRef<Expr *> getVars() { + return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars); + } + + void setVars(ArrayRef<Expr *> VL); + + /// Returns an array of immutable clauses associated with this directive. + ArrayRef<OMPClause *> getClauses() const { + return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses); + } + + /// Returns an array of clauses associated with this directive. + MutableArrayRef<OMPClause *> getClauses() { + return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(), + NumClauses); + } + + /// Sets an array of clauses to this requires declaration + void setClauses(ArrayRef<OMPClause *> CL); + +public: + static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, ArrayRef<Expr *> VL, + ArrayRef<OMPClause *> CL); + static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned NVars, unsigned NClauses); + + typedef MutableArrayRef<Expr *>::iterator varlist_iterator; + typedef ArrayRef<const Expr *>::iterator varlist_const_iterator; + typedef llvm::iterator_range<varlist_iterator> varlist_range; + typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range; + using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator; + using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator; + using clauselist_range = llvm::iterator_range<clauselist_iterator>; + using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>; + + + unsigned varlist_size() const { return NumVars; } + bool varlist_empty() const { return NumVars == 0; } + unsigned clauselist_size() const { return NumClauses; } + bool clauselist_empty() const { return NumClauses == 0; } + + varlist_range varlists() { + return varlist_range(varlist_begin(), varlist_end()); + } + varlist_const_range varlists() const { + return varlist_const_range(varlist_begin(), varlist_end()); + } + varlist_iterator varlist_begin() { return getVars().begin(); } + varlist_iterator varlist_end() { return getVars().end(); } + varlist_const_iterator varlist_begin() const { return getVars().begin(); } + varlist_const_iterator varlist_end() const { return getVars().end(); } + + clauselist_range clauselists() { + return clauselist_range(clauselist_begin(), clauselist_end()); + } + clauselist_const_range clauselists() const { + return clauselist_const_range(clauselist_begin(), clauselist_end()); + } + clauselist_iterator clauselist_begin() { return getClauses().begin(); } + clauselist_iterator clauselist_end() { return getClauses().end(); } + clauselist_const_iterator clauselist_begin() const { + return getClauses().begin(); + } + clauselist_const_iterator clauselist_end() const { + return getClauses().end(); + } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPAllocate; } +}; + } // end namespace clang #endif diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index f6e3d8f300ba..235b31c1c312 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -1,9 +1,8 @@ //===- DeclTemplate.h - Classes for representing C++ templates --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -177,6 +176,11 @@ public: return SourceRange(TemplateLoc, RAngleLoc); } + void print(raw_ostream &Out, const ASTContext &Context, + bool OmitTemplateKW = false) const; + void print(raw_ostream &Out, const ASTContext &Context, + const PrintingPolicy &Policy, bool OmitTemplateKW = false) const; + public: // FIXME: workaround for MSVC 2013; remove when no longer needed using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner; @@ -505,29 +509,13 @@ public: /// Provides information about a function template specialization, /// which is a FunctionDecl that has been explicitly specialization or /// instantiated from a function template. -class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode { - FunctionTemplateSpecializationInfo(FunctionDecl *FD, - FunctionTemplateDecl *Template, - TemplateSpecializationKind TSK, - const TemplateArgumentList *TemplateArgs, - const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, - SourceLocation POI) - : Function(FD), Template(Template, TSK - 1), - TemplateArguments(TemplateArgs), - TemplateArgumentsAsWritten(TemplateArgsAsWritten), - PointOfInstantiation(POI) {} - -public: - static FunctionTemplateSpecializationInfo * - Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, - TemplateSpecializationKind TSK, - const TemplateArgumentList *TemplateArgs, - const TemplateArgumentListInfo *TemplateArgsAsWritten, - SourceLocation POI); - - /// The function template specialization that this structure - /// describes. - FunctionDecl *Function; +class FunctionTemplateSpecializationInfo final + : public llvm::FoldingSetNode, + private llvm::TrailingObjects<FunctionTemplateSpecializationInfo, + MemberSpecializationInfo *> { + /// The function template specialization that this structure describes and a + /// flag indicating if the function is a member specialization. + llvm::PointerIntPair<FunctionDecl *, 1, bool> Function; /// The function template from which this function template /// specialization was generated. @@ -535,17 +523,50 @@ public: /// The two bits contain the top 4 values of TemplateSpecializationKind. llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template; +public: /// The template arguments used to produce the function template /// specialization from the function template. const TemplateArgumentList *TemplateArguments; /// The template arguments as written in the sources, if provided. + /// FIXME: Normally null; tail-allocate this. const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten; /// The point at which this function template specialization was /// first instantiated. SourceLocation PointOfInstantiation; +private: + FunctionTemplateSpecializationInfo( + FunctionDecl *FD, FunctionTemplateDecl *Template, + TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, + const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation POI, MemberSpecializationInfo *MSInfo) + : Function(FD, MSInfo ? 1 : 0), Template(Template, TSK - 1), + TemplateArguments(TemplateArgs), + TemplateArgumentsAsWritten(TemplateArgsAsWritten), + PointOfInstantiation(POI) { + if (MSInfo) + getTrailingObjects<MemberSpecializationInfo *>()[0] = MSInfo; + } + + size_t numTrailingObjects(OverloadToken<MemberSpecializationInfo*>) const { + return Function.getInt(); + } + +public: + friend TrailingObjects; + + static FunctionTemplateSpecializationInfo * + Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, + TemplateSpecializationKind TSK, + const TemplateArgumentList *TemplateArgs, + const TemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation POI, MemberSpecializationInfo *MSInfo); + + /// Retrieve the declaration of the function template specialization. + FunctionDecl *getFunction() const { return Function.getPointer(); } + /// Retrieve the template from which this function was specialized. FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); } @@ -588,9 +609,44 @@ public: PointOfInstantiation = POI; } + /// Get the specialization info if this function template specialization is + /// also a member specialization: + /// + /// \code + /// template<typename> struct A { + /// template<typename> void f(); + /// template<> void f<int>(); // ClassScopeFunctionSpecializationDecl + /// }; + /// \endcode + /// + /// Here, A<int>::f<int> is a function template specialization that is + /// an explicit specialization of A<int>::f, but it's also a member + /// specialization (an implicit instantiation in this case) of A::f<int>. + /// Further: + /// + /// \code + /// template<> template<> void A<int>::f<int>() {} + /// \endcode + /// + /// ... declares a function template specialization that is an explicit + /// specialization of A<int>::f, and is also an explicit member + /// specialization of A::f<int>. + /// + /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo + /// need not be the same as that returned by getTemplateSpecializationKind(), + /// and represents the relationship between the function and the class-scope + /// explicit specialization in the original templated class -- whereas our + /// TemplateSpecializationKind represents the relationship between the + /// function and the function template, and should always be + /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo. + MemberSpecializationInfo *getMemberSpecializationInfo() const { + return numTrailingObjects(OverloadToken<MemberSpecializationInfo *>()) + ? getTrailingObjects<MemberSpecializationInfo *>()[0] + : nullptr; + } + void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, TemplateArguments->asArray(), - Function->getASTContext()); + Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext()); } static void @@ -956,7 +1012,7 @@ SpecEntryTraits<FunctionTemplateSpecializationInfo> { using DeclType = FunctionDecl; static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) { - return I->Function; + return I->getFunction(); } static ArrayRef<TemplateArgument> @@ -1747,6 +1803,20 @@ public: return getSpecializationKind() == TSK_ExplicitSpecialization; } + /// Is this an explicit specialization at class scope (within the class that + /// owns the primary template)? For example: + /// + /// \code + /// template<typename T> struct Outer { + /// template<typename U> struct Inner; + /// template<> struct Inner; // class-scope explicit specialization + /// }; + /// \endcode + bool isClassScopeExplicitSpecialization() const { + return isExplicitSpecialization() && + isa<CXXRecordDecl>(getLexicalDeclContext()); + } + /// True if this declaration is an explicit specialization, /// explicit instantiation declaration, or explicit instantiation /// definition. @@ -2395,8 +2465,6 @@ public: /// Declaration of a function specialization at template class scope. /// -/// This is a non-standard extension needed to support MSVC. -/// /// For example: /// \code /// template <class T> @@ -2409,17 +2477,18 @@ public: /// "template<> foo(int a)" will be saved in Specialization as a normal /// CXXMethodDecl. Then during an instantiation of class A, it will be /// transformed into an actual function specialization. +/// +/// FIXME: This is redundant; we could store the same information directly on +/// the CXXMethodDecl as a DependentFunctionTemplateSpecializationInfo. class ClassScopeFunctionSpecializationDecl : public Decl { CXXMethodDecl *Specialization; - bool HasExplicitTemplateArgs; - TemplateArgumentListInfo TemplateArgs; + const ASTTemplateArgumentListInfo *TemplateArgs; - ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc, - CXXMethodDecl *FD, bool Args, - TemplateArgumentListInfo TemplArgs) + ClassScopeFunctionSpecializationDecl( + DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD, + const ASTTemplateArgumentListInfo *TemplArgs) : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc), - Specialization(FD), HasExplicitTemplateArgs(Args), - TemplateArgs(std::move(TemplArgs)) {} + Specialization(FD), TemplateArgs(TemplArgs) {} ClassScopeFunctionSpecializationDecl(EmptyShell Empty) : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {} @@ -2431,17 +2500,20 @@ public: friend class ASTDeclWriter; CXXMethodDecl *getSpecialization() const { return Specialization; } - bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } - const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; } - - static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C, - DeclContext *DC, - SourceLocation Loc, - CXXMethodDecl *FD, - bool HasExplicitTemplateArgs, - TemplateArgumentListInfo TemplateArgs) { + bool hasExplicitTemplateArgs() const { return TemplateArgs; } + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { + return TemplateArgs; + } + + static ClassScopeFunctionSpecializationDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD, + bool HasExplicitTemplateArgs, + const TemplateArgumentListInfo &TemplateArgs) { return new (C, DC) ClassScopeFunctionSpecializationDecl( - DC, Loc, FD, HasExplicitTemplateArgs, std::move(TemplateArgs)); + DC, Loc, FD, + HasExplicitTemplateArgs + ? ASTTemplateArgumentListInfo::Create(C, TemplateArgs) + : nullptr); } static ClassScopeFunctionSpecializationDecl * @@ -2582,6 +2654,11 @@ public: return getSpecializationKind() == TSK_ExplicitSpecialization; } + bool isClassScopeExplicitSpecialization() const { + return isExplicitSpecialization() && + isa<CXXRecordDecl>(getLexicalDeclContext()); + } + /// True if this declaration is an explicit specialization, /// explicit instantiation declaration, or explicit instantiation /// definition. @@ -3013,6 +3090,42 @@ public: static bool classofKind(Kind K) { return K == VarTemplate; } }; +// \brief Declaration of a C++2a concept. +class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> { +protected: + Expr *ConstraintExpr; + + ConceptDecl(DeclContext *DC, + SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, + Expr *ConstraintExpr) + : TemplateDecl(nullptr, Concept, DC, L, Name, Params), + ConstraintExpr(ConstraintExpr) {}; +public: + static ConceptDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, + Expr *ConstraintExpr); + static ConceptDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + Expr *getConstraintExpr() const { + return ConstraintExpr; + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(getTemplateParameters()->getTemplateLoc(), + ConstraintExpr->getEndLoc()); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Concept; } + + friend class ASTReader; + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + inline NamedDecl *getAsNamedDecl(TemplateParameter P) { if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>()) return PD; diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h index c6cbc9ff7faa..8690cdda4bb7 100644 --- a/include/clang/AST/DeclVisitor.h +++ b/include/clang/AST/DeclVisitor.h @@ -1,9 +1,8 @@ //===- DeclVisitor.h - Visitor for Decl subclasses --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 62afae23ec79..90449147637d 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -1,9 +1,8 @@ //===- DeclarationName.h - Representation of declaration names --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -862,9 +861,26 @@ struct DenseMapInfo<clang::DeclarationName> { } }; -template <> -struct isPodLike<clang::DeclarationName> { static const bool value = true; }; - } // namespace llvm +// The definition of AssumedTemplateStorage is factored out of TemplateName to +// resolve a cyclic dependency between it and DeclarationName (via Type). +namespace clang { + +/// A structure for storing the information associated with a name that has +/// been assumed to be a template name (despite finding no TemplateDecls). +class AssumedTemplateStorage : public UncommonTemplateNameStorage { + friend class ASTContext; + + AssumedTemplateStorage(DeclarationName Name) + : UncommonTemplateNameStorage(Assumed, 0), Name(Name) {} + DeclarationName Name; + +public: + /// Get the name of the template. + DeclarationName getDeclName() const { return Name; } +}; + +} // namespace clang + #endif // LLVM_CLANG_AST_DECLARATIONNAME_H diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h index c21ef7907b8a..0a98dec0c25e 100644 --- a/include/clang/AST/DependentDiagnostic.h +++ b/include/clang/AST/DependentDiagnostic.h @@ -1,9 +1,8 @@ //==- DependentDiagnostic.h - Dependently-generated diagnostics --*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h index f356584144e6..2f6c314b4111 100644 --- a/include/clang/AST/EvaluatedExprVisitor.h +++ b/include/clang/AST/EvaluatedExprVisitor.h @@ -1,9 +1,8 @@ //===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 3de73428829b..d44a815c8699 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1,9 +1,8 @@ //===--- Expr.h - Classes for representing expressions ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -23,11 +22,14 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/FixedPoint.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SyncScope.h" #include "clang/Basic/TypeTraits.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/AtomicOrdering.h" @@ -103,13 +105,20 @@ struct SubobjectAdjustment { /// This represents one expression. Note that Expr's are subclasses of Stmt. /// This allows an expression to be transparently used any place a Stmt is /// required. -class Expr : public Stmt { +class Expr : public ValueStmt { QualType TR; +public: + Expr() = delete; + Expr(const Expr&) = delete; + Expr(Expr &&) = delete; + Expr &operator=(const Expr&) = delete; + Expr &operator=(Expr&&) = delete; + protected: Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack) - : Stmt(SC) + : ValueStmt(SC) { ExprBits.TypeDependent = TD; ExprBits.ValueDependent = VD; @@ -122,7 +131,7 @@ protected: } /// Construct an empty expression. - explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { } + explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { } public: QualType getType() const { return TR; } @@ -590,7 +599,8 @@ public: /// which we can fold and convert to a boolean condition using /// any crazy technique that we want to, even if the expression has /// side-effects. - bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const; + bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, + bool InConstantContext = false) const; enum SideEffectsKind { SE_NoSideEffects, ///< Strictly evaluate the expression. @@ -602,14 +612,21 @@ public: /// EvaluateAsInt - Return true if this is a constant which we can fold and /// convert to an integer, using any crazy technique that we want to. bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, - SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; + SideEffectsKind AllowSideEffects = SE_NoSideEffects, + bool InConstantContext = false) const; /// EvaluateAsFloat - Return true if this is a constant which we can fold and /// convert to a floating point value, using any crazy technique that we /// want to. - bool - EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, - SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; + bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, + SideEffectsKind AllowSideEffects = SE_NoSideEffects, + bool InConstantContext = false) const; + + /// EvaluateAsFloat - Return true if this is a constant which we can fold and + /// convert to a fixed point value. + bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, + SideEffectsKind AllowSideEffects = SE_NoSideEffects, + bool InConstantContext = false) const; /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be /// constant folded without side-effects, but discard the result. @@ -645,7 +662,8 @@ public: /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an /// lvalue with link time known address, with no side-effects. - bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const; + bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, + bool InConstantContext = false) const; /// EvaluateAsInitializer - Evaluate an expression as if it were the /// initializer of the given declaration. Returns true if the initializer @@ -738,67 +756,110 @@ public: /// member expression. static QualType findBoundMemberType(const Expr *expr); - /// IgnoreImpCasts - Skip past any implicit casts which might - /// surround this expression. Only skips ImplicitCastExprs. + /// Skip past any implicit casts which might surround this expression until + /// reaching a fixed point. Skips: + /// * ImplicitCastExpr + /// * FullExpr Expr *IgnoreImpCasts() LLVM_READONLY; - - /// IgnoreImplicit - Skip past any implicit AST nodes which might - /// surround this expression. - Expr *IgnoreImplicit() LLVM_READONLY { - return cast<Expr>(Stmt::IgnoreImplicit()); - } - - const Expr *IgnoreImplicit() const LLVM_READONLY { - return const_cast<Expr*>(this)->IgnoreImplicit(); + const Expr *IgnoreImpCasts() const { + return const_cast<Expr *>(this)->IgnoreImpCasts(); } - /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return - /// its subexpression. If that subexpression is also a ParenExpr, - /// then this method recursively returns its subexpression, and so forth. - /// Otherwise, the method returns the current Expr. - Expr *IgnoreParens() LLVM_READONLY; - - /// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr - /// or CastExprs, returning their operand. - Expr *IgnoreParenCasts() LLVM_READONLY; - - /// Ignore casts. Strip off any CastExprs, returning their operand. + /// Skip past any casts which might surround this expression until reaching + /// a fixed point. Skips: + /// * CastExpr + /// * FullExpr + /// * MaterializeTemporaryExpr + /// * SubstNonTypeTemplateParmExpr Expr *IgnoreCasts() LLVM_READONLY; - - /// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off - /// any ParenExpr or ImplicitCastExprs, returning their operand. + const Expr *IgnoreCasts() const { + return const_cast<Expr *>(this)->IgnoreCasts(); + } + + /// Skip past any implicit AST nodes which might surround this expression + /// until reaching a fixed point. Skips: + /// * What IgnoreImpCasts() skips + /// * MaterializeTemporaryExpr + /// * CXXBindTemporaryExpr + Expr *IgnoreImplicit() LLVM_READONLY; + const Expr *IgnoreImplicit() const { + return const_cast<Expr *>(this)->IgnoreImplicit(); + } + + /// Skip past any parentheses which might surround this expression until + /// reaching a fixed point. Skips: + /// * ParenExpr + /// * UnaryOperator if `UO_Extension` + /// * GenericSelectionExpr if `!isResultDependent()` + /// * ChooseExpr if `!isConditionDependent()` + /// * ConstantExpr + Expr *IgnoreParens() LLVM_READONLY; + const Expr *IgnoreParens() const { + return const_cast<Expr *>(this)->IgnoreParens(); + } + + /// Skip past any parentheses and implicit casts which might surround this + /// expression until reaching a fixed point. + /// FIXME: IgnoreParenImpCasts really ought to be equivalent to + /// IgnoreParens() + IgnoreImpCasts() until reaching a fixed point. However + /// this is currently not the case. Instead IgnoreParenImpCasts() skips: + /// * What IgnoreParens() skips + /// * What IgnoreImpCasts() skips + /// * MaterializeTemporaryExpr + /// * SubstNonTypeTemplateParmExpr Expr *IgnoreParenImpCasts() LLVM_READONLY; - - /// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a - /// call to a conversion operator, return the argument. - Expr *IgnoreConversionOperator() LLVM_READONLY; - - const Expr *IgnoreConversionOperator() const LLVM_READONLY { - return const_cast<Expr*>(this)->IgnoreConversionOperator(); + const Expr *IgnoreParenImpCasts() const { + return const_cast<Expr *>(this)->IgnoreParenImpCasts(); } - const Expr *IgnoreParenImpCasts() const LLVM_READONLY { - return const_cast<Expr*>(this)->IgnoreParenImpCasts(); + /// Skip past any parentheses and casts which might surround this expression + /// until reaching a fixed point. Skips: + /// * What IgnoreParens() skips + /// * What IgnoreCasts() skips + Expr *IgnoreParenCasts() LLVM_READONLY; + const Expr *IgnoreParenCasts() const { + return const_cast<Expr *>(this)->IgnoreParenCasts(); } - /// Ignore parentheses and lvalue casts. Strip off any ParenExpr and - /// CastExprs that represent lvalue casts, returning their operand. + /// Skip conversion operators. If this Expr is a call to a conversion + /// operator, return the argument. + Expr *IgnoreConversionOperator() LLVM_READONLY; + const Expr *IgnoreConversionOperator() const { + return const_cast<Expr *>(this)->IgnoreConversionOperator(); + } + + /// Skip past any parentheses and lvalue casts which might surround this + /// expression until reaching a fixed point. Skips: + /// * What IgnoreParens() skips + /// * What IgnoreCasts() skips, except that only lvalue-to-rvalue + /// casts are skipped + /// FIXME: This is intended purely as a temporary workaround for code + /// that hasn't yet been rewritten to do the right thing about those + /// casts, and may disappear along with the last internal use. Expr *IgnoreParenLValueCasts() LLVM_READONLY; - - const Expr *IgnoreParenLValueCasts() const LLVM_READONLY { - return const_cast<Expr*>(this)->IgnoreParenLValueCasts(); - } - - /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the - /// value (including ptr->int casts of the same size). Strip off any - /// ParenExpr or CastExprs, returning their operand. - Expr *IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY; - - /// Ignore parentheses and derived-to-base casts. + const Expr *IgnoreParenLValueCasts() const { + return const_cast<Expr *>(this)->IgnoreParenLValueCasts(); + } + + /// Skip past any parenthese and casts which do not change the value + /// (including ptr->int casts of the same size) until reaching a fixed point. + /// Skips: + /// * What IgnoreParens() skips + /// * CastExpr which do not change the value + /// * SubstNonTypeTemplateParmExpr + Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY; + const Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) const { + return const_cast<Expr *>(this)->IgnoreParenNoopCasts(Ctx); + } + + /// Skip past any parentheses and derived-to-base casts until reaching a + /// fixed point. Skips: + /// * What IgnoreParens() skips + /// * CastExpr which represent a derived-to-base cast (CK_DerivedToBase, + /// CK_UncheckedDerivedToBase and CK_NoOp) Expr *ignoreParenBaseCasts() LLVM_READONLY; - - const Expr *ignoreParenBaseCasts() const LLVM_READONLY { - return const_cast<Expr*>(this)->ignoreParenBaseCasts(); + const Expr *ignoreParenBaseCasts() const { + return const_cast<Expr *>(this)->ignoreParenBaseCasts(); } /// Determine whether this expression is a default function argument. @@ -817,24 +878,6 @@ public: /// Whether this expression is an implicit reference to 'this' in C++. bool isImplicitCXXThis() const; - const Expr *IgnoreImpCasts() const LLVM_READONLY { - return const_cast<Expr*>(this)->IgnoreImpCasts(); - } - const Expr *IgnoreParens() const LLVM_READONLY { - return const_cast<Expr*>(this)->IgnoreParens(); - } - const Expr *IgnoreParenCasts() const LLVM_READONLY { - return const_cast<Expr*>(this)->IgnoreParenCasts(); - } - /// Strip off casts, but keep parentheses. - const Expr *IgnoreCasts() const LLVM_READONLY { - return const_cast<Expr*>(this)->IgnoreCasts(); - } - - const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY { - return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx); - } - static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs); /// For an expression of class type or pointer to class type, @@ -900,20 +943,63 @@ public: } }; -/// ConstantExpr - An expression that occurs in a constant context. -class ConstantExpr : public FullExpr { - ConstantExpr(Expr *subexpr) - : FullExpr(ConstantExprClass, subexpr) {} +/// ConstantExpr - An expression that occurs in a constant context and +/// optionally the result of evaluating the expression. +class ConstantExpr final + : public FullExpr, + private llvm::TrailingObjects<ConstantExpr, APValue, uint64_t> { + static_assert(std::is_same<uint64_t, llvm::APInt::WordType>::value, + "this class assumes llvm::APInt::WordType is uint64_t for " + "trail-allocated storage"); public: - static ConstantExpr *Create(const ASTContext &Context, Expr *E) { - assert(!isa<ConstantExpr>(E)); - return new (Context) ConstantExpr(E); + /// Describes the kind of result that can be trail-allocated. + enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue }; + +private: + size_t numTrailingObjects(OverloadToken<APValue>) const { + return ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue; + } + size_t numTrailingObjects(OverloadToken<uint64_t>) const { + return ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64; } - /// Build an empty constant expression wrapper. - explicit ConstantExpr(EmptyShell Empty) - : FullExpr(ConstantExprClass, Empty) {} + void DefaultInit(ResultStorageKind StorageKind); + uint64_t &Int64Result() { + assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64 && + "invalid accessor"); + return *getTrailingObjects<uint64_t>(); + } + const uint64_t &Int64Result() const { + return const_cast<ConstantExpr *>(this)->Int64Result(); + } + APValue &APValueResult() { + assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue && + "invalid accessor"); + return *getTrailingObjects<APValue>(); + } + const APValue &APValueResult() const { + return const_cast<ConstantExpr *>(this)->APValueResult(); + } + + ConstantExpr(Expr *subexpr, ResultStorageKind StorageKind); + ConstantExpr(ResultStorageKind StorageKind, EmptyShell Empty); + +public: + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + static ConstantExpr *Create(const ASTContext &Context, Expr *E, + const APValue &Result); + static ConstantExpr *Create(const ASTContext &Context, Expr *E, + ResultStorageKind Storage = RSK_None); + static ConstantExpr *CreateEmpty(const ASTContext &Context, + ResultStorageKind StorageKind, + EmptyShell Empty); + + static ResultStorageKind getStorageKind(const APValue &Value); + static ResultStorageKind getStorageKind(const Type *T, + const ASTContext &Context); SourceLocation getBeginLoc() const LLVM_READONLY { return SubExpr->getBeginLoc(); @@ -926,6 +1012,20 @@ public: return T->getStmtClass() == ConstantExprClass; } + void SetResult(APValue Value, const ASTContext &Context) { + MoveIntoResult(Value, Context); + } + void MoveIntoResult(APValue &Value, const ASTContext &Context); + + APValue::ValueKind getResultAPValueKind() const { + return static_cast<APValue::ValueKind>(ConstantExprBits.APValueKind); + } + ResultStorageKind getResultStorageKind() const { + return static_cast<ResultStorageKind>(ConstantExprBits.ResultKind); + } + APValue getAPValueResult() const; + const APValue &getResultAsAPValue() const { return APValueResult(); } + llvm::APSInt getResultAsAPSInt() const; // Iterators child_range children() { return child_range(&SubExpr, &SubExpr+1); } const_child_range children() const { @@ -1075,7 +1175,7 @@ class DeclRefExpr final bool RefersToEnlosingVariableOrCapture, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, QualType T, - ExprValueKind VK); + ExprValueKind VK, NonOdrUseReason NOUR); /// Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {} @@ -1088,14 +1188,16 @@ public: DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T, ExprValueKind VK, SourceLocation L, - const DeclarationNameLoc &LocInfo = DeclarationNameLoc()); + const DeclarationNameLoc &LocInfo = DeclarationNameLoc(), + NonOdrUseReason NOUR = NOUR_None); static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr, - const TemplateArgumentListInfo *TemplateArgs = nullptr); + const TemplateArgumentListInfo *TemplateArgs = nullptr, + NonOdrUseReason NOUR = NOUR_None); static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, @@ -1103,7 +1205,8 @@ public: bool RefersToEnclosingVariableOrCapture, const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr, - const TemplateArgumentListInfo *TemplateArgs = nullptr); + const TemplateArgumentListInfo *TemplateArgs = nullptr, + NonOdrUseReason NOUR = NOUR_None); /// Construct an empty declaration reference expression. static DeclRefExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier, @@ -1234,6 +1337,11 @@ public: DeclRefExprBits.HadMultipleCandidates = V; } + /// Is this expression a non-odr-use reference, and if so, why? + NonOdrUseReason isNonOdrUse() const { + return static_cast<NonOdrUseReason>(DeclRefExprBits.NonOdrUseReason); + } + /// Does this DeclRefExpr refer to an enclosing local or a captured /// variable? bool refersToEnclosingVariableOrCapture() const { @@ -1466,21 +1574,28 @@ public: /// Get a raw enumeration value representing the floating-point semantics of /// this literal (32-bit IEEE, x87, ...), suitable for serialisation. - APFloatSemantics getRawSemantics() const { - return static_cast<APFloatSemantics>(FloatingLiteralBits.Semantics); + llvm::APFloatBase::Semantics getRawSemantics() const { + return static_cast<llvm::APFloatBase::Semantics>( + FloatingLiteralBits.Semantics); } /// Set the raw enumeration value representing the floating-point semantics of /// this literal (32-bit IEEE, x87, ...), suitable for serialisation. - void setRawSemantics(APFloatSemantics Sem) { + void setRawSemantics(llvm::APFloatBase::Semantics Sem) { FloatingLiteralBits.Semantics = Sem; } /// Return the APFloat semantics this literal uses. - const llvm::fltSemantics &getSemantics() const; + const llvm::fltSemantics &getSemantics() const { + return llvm::APFloatBase::EnumToSemantics( + static_cast<llvm::APFloatBase::Semantics>( + FloatingLiteralBits.Semantics)); + } /// Set the APFloat semantics this literal uses. - void setSemantics(const llvm::fltSemantics &Sem); + void setSemantics(const llvm::fltSemantics &Sem) { + FloatingLiteralBits.Semantics = llvm::APFloatBase::SemanticsToEnum(Sem); + } bool isExact() const { return FloatingLiteralBits.IsExact; } void setExact(bool E) { FloatingLiteralBits.IsExact = E; } @@ -1837,6 +1952,11 @@ public: return child_range(getTrailingObjects<Stmt *>(), getTrailingObjects<Stmt *>() + hasFunctionName()); } + + const_child_range children() const { + return const_child_range(getTrailingObjects<Stmt *>(), + getTrailingObjects<Stmt *>() + hasFunctionName()); + } }; /// ParenExpr - This represents a parethesized expression, e.g. "(1)". This @@ -2577,6 +2697,11 @@ public: NumArgs = NewNumArgs; } + /// Bluntly set a new number of arguments without doing any checks whatsoever. + /// Only used during construction of a CallExpr in a few places in Sema. + /// FIXME: Find a way to remove it. + void setNumArgsUnsafe(unsigned NewNumArgs) { NumArgs = NewNumArgs; } + typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; typedef llvm::iterator_range<arg_iterator> arg_range; @@ -2685,6 +2810,7 @@ class MemberExpr final ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { friend class ASTReader; + friend class ASTStmtReader; friend class ASTStmtWriter; friend TrailingObjects; @@ -2719,49 +2845,40 @@ class MemberExpr final return MemberExprBits.HasTemplateKWAndArgsInfo; } + MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc, + ValueDecl *MemberDecl, const DeclarationNameInfo &NameInfo, + QualType T, ExprValueKind VK, ExprObjectKind OK, + NonOdrUseReason NOUR); + MemberExpr(EmptyShell Empty) + : Expr(MemberExprClass, Empty), Base(), MemberDecl() {} + public: - MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc, - ValueDecl *memberdecl, const DeclarationNameInfo &NameInfo, - QualType ty, ExprValueKind VK, ExprObjectKind OK) - : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), - base->isValueDependent(), base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()), - MemberLoc(NameInfo.getLoc()) { - assert(memberdecl->getDeclName() == NameInfo.getName()); - MemberExprBits.IsArrow = isarrow; - MemberExprBits.HasQualifierOrFoundDecl = false; - MemberExprBits.HasTemplateKWAndArgsInfo = false; - MemberExprBits.HadMultipleCandidates = false; - MemberExprBits.OperatorLoc = operatorloc; - } - - // NOTE: this constructor should be used only when it is known that - // the member name can not provide additional syntactic info - // (i.e., source locations for C++ operator names or type source info - // for constructors, destructors and conversion operators). - MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc, - ValueDecl *memberdecl, SourceLocation l, QualType ty, - ExprValueKind VK, ExprObjectKind OK) - : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), - base->isValueDependent(), base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l) { - MemberExprBits.IsArrow = isarrow; - MemberExprBits.HasQualifierOrFoundDecl = false; - MemberExprBits.HasTemplateKWAndArgsInfo = false; - MemberExprBits.HadMultipleCandidates = false; - MemberExprBits.OperatorLoc = operatorloc; - } - - static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow, + static MemberExpr *Create(const ASTContext &C, Expr *Base, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, ValueDecl *memberdecl, - DeclAccessPair founddecl, + SourceLocation TemplateKWLoc, ValueDecl *MemberDecl, + DeclAccessPair FoundDecl, DeclarationNameInfo MemberNameInfo, - const TemplateArgumentListInfo *targs, QualType ty, - ExprValueKind VK, ExprObjectKind OK); + const TemplateArgumentListInfo *TemplateArgs, + QualType T, ExprValueKind VK, ExprObjectKind OK, + NonOdrUseReason NOUR); + + /// Create an implicit MemberExpr, with no location, qualifier, template + /// arguments, and so on. Suitable only for non-static member access. + static MemberExpr *CreateImplicit(const ASTContext &C, Expr *Base, + bool IsArrow, ValueDecl *MemberDecl, + QualType T, ExprValueKind VK, + ExprObjectKind OK) { + return Create(C, Base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(), + SourceLocation(), MemberDecl, + DeclAccessPair::make(MemberDecl, MemberDecl->getAccess()), + DeclarationNameInfo(), nullptr, T, VK, OK, NOUR_None); + } + + static MemberExpr *CreateEmpty(const ASTContext &Context, bool HasQualifier, + bool HasFoundDecl, + bool HasTemplateKWAndArgsInfo, + unsigned NumTemplateArgs); void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast<Expr>(Base); } @@ -2909,6 +3026,12 @@ public: return LO.AppleKext || !hasQualifier(); } + /// Is this expression a non-odr-use reference, and if so, why? + /// This is only meaningful if the named member is a static member. + NonOdrUseReason isNonOdrUse() const { + return static_cast<NonOdrUseReason>(MemberExprBits.NonOdrUseReason); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == MemberExprClass; } @@ -3072,6 +3195,13 @@ public: path_const_iterator path_begin() const { return path_buffer(); } path_const_iterator path_end() const { return path_buffer() + path_size(); } + llvm::iterator_range<path_iterator> path() { + return llvm::make_range(path_begin(), path_end()); + } + llvm::iterator_range<path_const_iterator> path() const { + return llvm::make_range(path_begin(), path_end()); + } + const FieldDecl *getTargetUnionField() const { assert(getCastKind() == CK_ToUnion); return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType()); @@ -3159,18 +3289,6 @@ public: friend class CastExpr; }; -inline Expr *Expr::IgnoreImpCasts() { - Expr *e = this; - while (true) - if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e)) - e = ice->getSubExpr(); - else if (FullExpr *fe = dyn_cast<FullExpr>(e)) - e = fe->getSubExpr(); - else - break; - return e; -} - /// ExplicitCastExpr - An explicit cast written in the source /// code. /// @@ -3377,6 +3495,9 @@ public: static bool isComparisonOp(Opcode Opc) { return Opc >= BO_Cmp && Opc<=BO_NE; } bool isComparisonOp() const { return isComparisonOp(getOpcode()); } + static bool isCommaOp(Opcode Opc) { return Opc == BO_Comma; } + bool isCommaOp() const { return isCommaOp(getOpcode()); } + static Opcode negateComparisonOp(Opcode Opc) { switch (Opc) { default: @@ -4137,6 +4258,71 @@ public: } }; +/// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), +/// __builtin_FUNCTION(), or __builtin_FILE(). +class SourceLocExpr final : public Expr { + SourceLocation BuiltinLoc, RParenLoc; + DeclContext *ParentContext; + +public: + enum IdentKind { Function, File, Line, Column }; + + SourceLocExpr(const ASTContext &Ctx, IdentKind Type, SourceLocation BLoc, + SourceLocation RParenLoc, DeclContext *Context); + + /// Build an empty call expression. + explicit SourceLocExpr(EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {} + + /// Return the result of evaluating this SourceLocExpr in the specified + /// (and possibly null) default argument or initialization context. + APValue EvaluateInContext(const ASTContext &Ctx, + const Expr *DefaultExpr) const; + + /// Return a string representing the name of the specific builtin function. + StringRef getBuiltinStr() const; + + IdentKind getIdentKind() const { + return static_cast<IdentKind>(SourceLocExprBits.Kind); + } + + bool isStringType() const { + switch (getIdentKind()) { + case File: + case Function: + return true; + case Line: + case Column: + return false; + } + llvm_unreachable("unknown source location expression kind"); + } + bool isIntType() const LLVM_READONLY { return !isStringType(); } + + /// If the SourceLocExpr has been resolved return the subexpression + /// representing the resolved value. Otherwise return null. + const DeclContext *getParentContext() const { return ParentContext; } + DeclContext *getParentContext() { return ParentContext; } + + SourceLocation getLocation() const { return BuiltinLoc; } + SourceLocation getBeginLoc() const { return BuiltinLoc; } + SourceLocation getEndLoc() const { return RParenLoc; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(child_iterator(), child_iterator()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == SourceLocExprClass; + } + +private: + friend class ASTStmtReader; +}; + /// Describes an C or C++ initializer list. /// /// InitListExpr describes an initializer list, which can be used to @@ -5007,99 +5193,277 @@ public: /// which names a dependent type in its association list is result-dependent, /// which means that the choice of result expression is dependent. /// Result-dependent generic associations are both type- and value-dependent. -class GenericSelectionExpr : public Expr { - enum { CONTROLLING, END_EXPR }; - TypeSourceInfo **AssocTypes; - Stmt **SubExprs; +class GenericSelectionExpr final + : public Expr, + private llvm::TrailingObjects<GenericSelectionExpr, Stmt *, + TypeSourceInfo *> { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + + /// The number of association expressions and the index of the result + /// expression in the case where the generic selection expression is not + /// result-dependent. The result index is equal to ResultDependentIndex + /// if and only if the generic selection expression is result-dependent. unsigned NumAssocs, ResultIndex; - SourceLocation GenericLoc, DefaultLoc, RParenLoc; + enum : unsigned { + ResultDependentIndex = std::numeric_limits<unsigned>::max(), + ControllingIndex = 0, + AssocExprStartIndex = 1 + }; -public: - GenericSelectionExpr(const ASTContext &Context, - SourceLocation GenericLoc, Expr *ControllingExpr, - ArrayRef<TypeSourceInfo*> AssocTypes, - ArrayRef<Expr*> AssocExprs, - SourceLocation DefaultLoc, SourceLocation RParenLoc, + /// The location of the "default" and of the right parenthesis. + SourceLocation DefaultLoc, RParenLoc; + + // GenericSelectionExpr is followed by several trailing objects. + // They are (in order): + // + // * A single Stmt * for the controlling expression. + // * An array of getNumAssocs() Stmt * for the association expressions. + // * An array of getNumAssocs() TypeSourceInfo *, one for each of the + // association expressions. + unsigned numTrailingObjects(OverloadToken<Stmt *>) const { + // Add one to account for the controlling expression; the remainder + // are the associated expressions. + return 1 + getNumAssocs(); + } + + unsigned numTrailingObjects(OverloadToken<TypeSourceInfo *>) const { + return getNumAssocs(); + } + + template <bool Const> class AssociationIteratorTy; + /// Bundle together an association expression and its TypeSourceInfo. + /// The Const template parameter is for the const and non-const versions + /// of AssociationTy. + template <bool Const> class AssociationTy { + friend class GenericSelectionExpr; + template <bool OtherConst> friend class AssociationIteratorTy; + using ExprPtrTy = + typename std::conditional<Const, const Expr *, Expr *>::type; + using TSIPtrTy = typename std::conditional<Const, const TypeSourceInfo *, + TypeSourceInfo *>::type; + ExprPtrTy E; + TSIPtrTy TSI; + bool Selected; + AssociationTy(ExprPtrTy E, TSIPtrTy TSI, bool Selected) + : E(E), TSI(TSI), Selected(Selected) {} + + public: + ExprPtrTy getAssociationExpr() const { return E; } + TSIPtrTy getTypeSourceInfo() const { return TSI; } + QualType getType() const { return TSI ? TSI->getType() : QualType(); } + bool isSelected() const { return Selected; } + AssociationTy *operator->() { return this; } + const AssociationTy *operator->() const { return this; } + }; // class AssociationTy + + /// Iterator over const and non-const Association objects. The Association + /// objects are created on the fly when the iterator is dereferenced. + /// This abstract over how exactly the association expressions and the + /// corresponding TypeSourceInfo * are stored. + template <bool Const> + class AssociationIteratorTy + : public llvm::iterator_facade_base< + AssociationIteratorTy<Const>, std::input_iterator_tag, + AssociationTy<Const>, std::ptrdiff_t, AssociationTy<Const>, + AssociationTy<Const>> { + friend class GenericSelectionExpr; + // FIXME: This iterator could conceptually be a random access iterator, and + // it would be nice if we could strengthen the iterator category someday. + // However this iterator does not satisfy two requirements of forward + // iterators: + // a) reference = T& or reference = const T& + // b) If It1 and It2 are both dereferenceable, then It1 == It2 if and only + // if *It1 and *It2 are bound to the same objects. + // An alternative design approach was discussed during review; + // store an Association object inside the iterator, and return a reference + // to it when dereferenced. This idea was discarded beacuse of nasty + // lifetime issues: + // AssociationIterator It = ...; + // const Association &Assoc = *It++; // Oops, Assoc is dangling. + using BaseTy = typename AssociationIteratorTy::iterator_facade_base; + using StmtPtrPtrTy = + typename std::conditional<Const, const Stmt *const *, Stmt **>::type; + using TSIPtrPtrTy = + typename std::conditional<Const, const TypeSourceInfo *const *, + TypeSourceInfo **>::type; + StmtPtrPtrTy E; // = nullptr; FIXME: Once support for gcc 4.8 is dropped. + TSIPtrPtrTy TSI; // Kept in sync with E. + unsigned Offset = 0, SelectedOffset = 0; + AssociationIteratorTy(StmtPtrPtrTy E, TSIPtrPtrTy TSI, unsigned Offset, + unsigned SelectedOffset) + : E(E), TSI(TSI), Offset(Offset), SelectedOffset(SelectedOffset) {} + + public: + AssociationIteratorTy() : E(nullptr), TSI(nullptr) {} + typename BaseTy::reference operator*() const { + return AssociationTy<Const>(cast<Expr>(*E), *TSI, + Offset == SelectedOffset); + } + typename BaseTy::pointer operator->() const { return **this; } + using BaseTy::operator++; + AssociationIteratorTy &operator++() { + ++E; + ++TSI; + ++Offset; + return *this; + } + bool operator==(AssociationIteratorTy Other) const { return E == Other.E; } + }; // class AssociationIterator + + /// Build a non-result-dependent generic selection expression. + GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc, + Expr *ControllingExpr, + ArrayRef<TypeSourceInfo *> AssocTypes, + ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex); - /// This constructor is used in the result-dependent case. - GenericSelectionExpr(const ASTContext &Context, - SourceLocation GenericLoc, Expr *ControllingExpr, - ArrayRef<TypeSourceInfo*> AssocTypes, - ArrayRef<Expr*> AssocExprs, - SourceLocation DefaultLoc, SourceLocation RParenLoc, + /// Build a result-dependent generic selection expression. + GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc, + Expr *ControllingExpr, + ArrayRef<TypeSourceInfo *> AssocTypes, + ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack); - explicit GenericSelectionExpr(EmptyShell Empty) - : Expr(GenericSelectionExprClass, Empty) { } + /// Build an empty generic selection expression for deserialization. + explicit GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs); +public: + /// Create a non-result-dependent generic selection expression. + static GenericSelectionExpr * + Create(const ASTContext &Context, SourceLocation GenericLoc, + Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes, + ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, + unsigned ResultIndex); + + /// Create a result-dependent generic selection expression. + static GenericSelectionExpr * + Create(const ASTContext &Context, SourceLocation GenericLoc, + Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes, + ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc, + SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack); + + /// Create an empty generic selection expression for deserialization. + static GenericSelectionExpr *CreateEmpty(const ASTContext &Context, + unsigned NumAssocs); + + using Association = AssociationTy<false>; + using ConstAssociation = AssociationTy<true>; + using AssociationIterator = AssociationIteratorTy<false>; + using ConstAssociationIterator = AssociationIteratorTy<true>; + using association_range = llvm::iterator_range<AssociationIterator>; + using const_association_range = + llvm::iterator_range<ConstAssociationIterator>; + + /// The number of association expressions. unsigned getNumAssocs() const { return NumAssocs; } - SourceLocation getGenericLoc() const { return GenericLoc; } - SourceLocation getDefaultLoc() const { return DefaultLoc; } - SourceLocation getRParenLoc() const { return RParenLoc; } - - const Expr *getAssocExpr(unsigned i) const { - return cast<Expr>(SubExprs[END_EXPR+i]); - } - Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); } - ArrayRef<Expr *> getAssocExprs() const { - return NumAssocs - ? llvm::makeArrayRef( - &reinterpret_cast<Expr **>(SubExprs)[END_EXPR], NumAssocs) - : None; - } - const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const { - return AssocTypes[i]; - } - TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; } - ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const { - return NumAssocs ? llvm::makeArrayRef(&AssocTypes[0], NumAssocs) : None; - } - - QualType getAssocType(unsigned i) const { - if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i)) - return TS->getType(); - else - return QualType(); - } - - const Expr *getControllingExpr() const { - return cast<Expr>(SubExprs[CONTROLLING]); - } - Expr *getControllingExpr() { return cast<Expr>(SubExprs[CONTROLLING]); } - - /// Whether this generic selection is result-dependent. - bool isResultDependent() const { return ResultIndex == -1U; } - /// The zero-based index of the result expression's generic association in /// the generic selection's association list. Defined only if the /// generic selection is not result-dependent. unsigned getResultIndex() const { - assert(!isResultDependent() && "Generic selection is result-dependent"); + assert(!isResultDependent() && + "Generic selection is result-dependent but getResultIndex called!"); return ResultIndex; } - /// The generic selection's result expression. Defined only if the - /// generic selection is not result-dependent. - const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); } - Expr *getResultExpr() { return getAssocExpr(getResultIndex()); } + /// Whether this generic selection is result-dependent. + bool isResultDependent() const { return ResultIndex == ResultDependentIndex; } - SourceLocation getBeginLoc() const LLVM_READONLY { return GenericLoc; } - SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } + /// Return the controlling expression of this generic selection expression. + Expr *getControllingExpr() { + return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]); + } + const Expr *getControllingExpr() const { + return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]); + } + + /// Return the result expression of this controlling expression. Defined if + /// and only if the generic selection expression is not result-dependent. + Expr *getResultExpr() { + return cast<Expr>( + getTrailingObjects<Stmt *>()[AssocExprStartIndex + getResultIndex()]); + } + const Expr *getResultExpr() const { + return cast<Expr>( + getTrailingObjects<Stmt *>()[AssocExprStartIndex + getResultIndex()]); + } + + ArrayRef<Expr *> getAssocExprs() const { + return {reinterpret_cast<Expr *const *>(getTrailingObjects<Stmt *>() + + AssocExprStartIndex), + NumAssocs}; + } + ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const { + return {getTrailingObjects<TypeSourceInfo *>(), NumAssocs}; + } + + /// Return the Ith association expression with its TypeSourceInfo, + /// bundled together in GenericSelectionExpr::(Const)Association. + Association getAssociation(unsigned I) { + assert(I < getNumAssocs() && + "Out-of-range index in GenericSelectionExpr::getAssociation!"); + return Association( + cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + I]), + getTrailingObjects<TypeSourceInfo *>()[I], + !isResultDependent() && (getResultIndex() == I)); + } + ConstAssociation getAssociation(unsigned I) const { + assert(I < getNumAssocs() && + "Out-of-range index in GenericSelectionExpr::getAssociation!"); + return ConstAssociation( + cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + I]), + getTrailingObjects<TypeSourceInfo *>()[I], + !isResultDependent() && (getResultIndex() == I)); + } + + association_range associations() { + AssociationIterator Begin(getTrailingObjects<Stmt *>() + + AssocExprStartIndex, + getTrailingObjects<TypeSourceInfo *>(), + /*Offset=*/0, ResultIndex); + AssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs, + /*Offset=*/NumAssocs, ResultIndex); + return llvm::make_range(Begin, End); + } + + const_association_range associations() const { + ConstAssociationIterator Begin(getTrailingObjects<Stmt *>() + + AssocExprStartIndex, + getTrailingObjects<TypeSourceInfo *>(), + /*Offset=*/0, ResultIndex); + ConstAssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs, + /*Offset=*/NumAssocs, ResultIndex); + return llvm::make_range(Begin, End); + } + + SourceLocation getGenericLoc() const { + return GenericSelectionExprBits.GenericLoc; + } + SourceLocation getDefaultLoc() const { return DefaultLoc; } + SourceLocation getRParenLoc() const { return RParenLoc; } + SourceLocation getBeginLoc() const { return getGenericLoc(); } + SourceLocation getEndLoc() const { return getRParenLoc(); } static bool classof(const Stmt *T) { return T->getStmtClass() == GenericSelectionExprClass; } child_range children() { - return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs); + return child_range(getTrailingObjects<Stmt *>(), + getTrailingObjects<Stmt *>() + + numTrailingObjects(OverloadToken<Stmt *>())); } const_child_range children() const { - return const_child_range(SubExprs, SubExprs + END_EXPR + NumAssocs); + return const_child_range(getTrailingObjects<Stmt *>(), + getTrailingObjects<Stmt *>() + + numTrailingObjects(OverloadToken<Stmt *>())); } - friend class ASTStmtReader; }; //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 6ef837a2fc40..28ed6cdfde14 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1,9 +1,8 @@ //===- ExprCXX.h - Classes for representing expressions ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -217,6 +216,8 @@ public: /// Represents a call to a CUDA kernel function. class CUDAKernelCallExpr final : public CallExpr { + friend class ASTStmtReader; + enum { CONFIG, END_PREARG }; // CUDAKernelCallExpr has some trailing objects belonging @@ -242,20 +243,6 @@ public: } CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); } - /// Sets the kernel configuration expression. - /// - /// Note that this method cannot be called if config has already been set to a - /// non-null value. - void setConfig(CallExpr *E) { - assert(!getConfig() && - "Cannot call setConfig if config is not null"); - setPreArg(CONFIG, E); - setInstantiationDependent(isInstantiationDependent() || - E->isInstantiationDependent()); - setContainsUnexpandedParameterPack(containsUnexpandedParameterPack() || - E->containsUnexpandedParameterPack()); - } - static bool classof(const Stmt *T) { return T->getStmtClass() == CUDAKernelCallExprClass; } @@ -588,6 +575,10 @@ public: 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()); + } }; /// The null pointer literal (C++11 [lex.nullptr]) @@ -617,6 +608,10 @@ public: 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()); + } }; /// Implicit construction of a std::initializer_list<T> object from an @@ -659,6 +654,10 @@ public: } child_range children() { return child_range(&SubExpr, &SubExpr + 1); } + + const_child_range children() const { + return const_child_range(&SubExpr, &SubExpr + 1); + } }; /// A C++ \c typeid expression (C++ [expr.typeid]), which gets @@ -749,6 +748,15 @@ public: auto **begin = reinterpret_cast<Stmt **>(&Operand); return child_range(begin, begin + 1); } + + const_child_range children() const { + if (isTypeOperand()) + return const_child_range(const_child_iterator(), const_child_iterator()); + + auto **begin = + reinterpret_cast<Stmt **>(&const_cast<CXXTypeidExpr *>(this)->Operand); + return const_child_range(begin, begin + 1); + } }; /// A member reference to an MSPropertyDecl. @@ -803,6 +811,11 @@ public: return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1); } + const_child_range children() const { + auto Children = const_cast<MSPropertyRefExpr *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == MSPropertyRefExprClass; } @@ -878,6 +891,10 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); } + + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); + } }; /// A Microsoft C++ @c __uuidof expression, which gets @@ -959,6 +976,14 @@ public: auto **begin = reinterpret_cast<Stmt **>(&Operand); return child_range(begin, begin + 1); } + + const_child_range children() const { + if (isTypeOperand()) + return const_child_range(const_child_iterator(), const_child_iterator()); + auto **begin = + reinterpret_cast<Stmt **>(&const_cast<CXXUuidofExpr *>(this)->Operand); + return const_child_range(begin, begin + 1); + } }; /// Represents the \c this expression in C++. @@ -1005,6 +1030,10 @@ public: 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()); + } }; /// A C++ throw-expression (C++ [except.throw]). @@ -1063,6 +1092,10 @@ public: child_range children() { return child_range(&Operand, Operand ? &Operand + 1 : &Operand); } + + const_child_range children() const { + return const_child_range(&Operand, Operand ? &Operand + 1 : &Operand); + } }; /// A default argument (C++ [dcl.fct.default]). @@ -1076,7 +1109,11 @@ class CXXDefaultArgExpr final : public Expr { /// The parameter whose default is being used. ParmVarDecl *Param; - CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param) + /// The context where the default argument expression was used. + DeclContext *UsedContext; + + CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param, + DeclContext *UsedContext) : Expr(SC, Param->hasUnparsedDefaultArg() ? Param->getType().getNonReferenceType() @@ -1084,7 +1121,7 @@ class CXXDefaultArgExpr final : public Expr { Param->getDefaultArg()->getValueKind(), Param->getDefaultArg()->getObjectKind(), false, false, false, false), - Param(Param) { + Param(Param), UsedContext(UsedContext) { CXXDefaultArgExprBits.Loc = Loc; } @@ -1094,8 +1131,10 @@ public: // \p Param is the parameter whose default argument is used by this // expression. static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc, - ParmVarDecl *Param) { - return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param); + ParmVarDecl *Param, + DeclContext *UsedContext) { + return new (C) + CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, UsedContext); } // Retrieve the parameter that the argument was created from. @@ -1106,6 +1145,9 @@ public: const Expr *getExpr() const { return getParam()->getDefaultArg(); } Expr *getExpr() { return getParam()->getDefaultArg(); } + const DeclContext *getUsedContext() const { return UsedContext; } + DeclContext *getUsedContext() { return UsedContext; } + /// Retrieve the location where this default argument was actually used. SourceLocation getUsedLocation() const { return CXXDefaultArgExprBits.Loc; } @@ -1124,6 +1166,10 @@ public: 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()); + } }; /// A use of a default initializer in a constructor or in aggregate @@ -1141,8 +1187,11 @@ class CXXDefaultInitExpr : public Expr { /// The field whose default is being used. FieldDecl *Field; + /// The context where the default initializer expression was used. + DeclContext *UsedContext; + CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc, - FieldDecl *Field, QualType Ty); + FieldDecl *Field, QualType Ty, DeclContext *UsedContext); CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {} @@ -1150,8 +1199,8 @@ public: /// \p Field is the non-static data member whose default initializer is used /// by this expression. static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc, - FieldDecl *Field) { - return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType()); + FieldDecl *Field, DeclContext *UsedContext) { + return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(), UsedContext); } /// Get the field whose initializer will be used. @@ -1168,6 +1217,13 @@ public: return Field->getInClassInitializer(); } + const DeclContext *getUsedContext() const { return UsedContext; } + DeclContext *getUsedContext() { return UsedContext; } + + /// Retrieve the location where this default initializer expression was + /// actually used. + SourceLocation getUsedLocation() const { return getBeginLoc(); } + SourceLocation getBeginLoc() const { return CXXDefaultInitExprBits.Loc; } SourceLocation getEndLoc() const { return CXXDefaultInitExprBits.Loc; } @@ -1179,6 +1235,10 @@ public: 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 C++ temporary. @@ -1256,6 +1316,10 @@ public: // Iterators child_range children() { return child_range(&SubExpr, &SubExpr + 1); } + + const_child_range children() const { + return const_child_range(&SubExpr, &SubExpr + 1); + } }; /// Represents a call to a C++ constructor. @@ -1439,6 +1503,11 @@ public: child_range children() { return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs()); } + + const_child_range children() const { + auto Children = const_cast<CXXConstructExpr *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } }; /// Represents a call to an inherited base class constructor from an @@ -1507,6 +1576,10 @@ public: 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 an explicit C++ type conversion that uses "functional" @@ -1833,6 +1906,10 @@ public: /// parameter list associated with it, or else return null. TemplateParameterList *getTemplateParameterList() const; + /// Get the template parameters were explicitly specified (as opposed to being + /// invented by use of an auto parameter). + ArrayRef<NamedDecl *> getExplicitTemplateParameters() const; + /// Whether this is a generic lambda. bool isGenericLambda() const { return getTemplateParameterList(); } @@ -1864,6 +1941,11 @@ public: // Includes initialization exprs plus body stmt return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1); } + + const_child_range children() const { + return const_child_range(getStoredStmts(), + getStoredStmts() + NumCaptures + 1); + } }; /// An expression "T()" which creates a value-initialized rvalue of type @@ -1907,6 +1989,10 @@ public: 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 new-expression for memory allocation and constructor @@ -1979,7 +2065,7 @@ private: CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete, bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs, - SourceRange TypeIdParens, Expr *ArraySize, + SourceRange TypeIdParens, Optional<Expr *> ArraySize, InitializationStyle InitializationStyle, Expr *Initializer, QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, SourceRange DirectInitRange); @@ -1994,7 +2080,7 @@ public: Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete, bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs, - SourceRange TypeIdParens, Expr *ArraySize, + SourceRange TypeIdParens, Optional<Expr *> ArraySize, InitializationStyle InitializationStyle, Expr *Initializer, QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, SourceRange DirectInitRange); @@ -2037,15 +2123,15 @@ public: bool isArray() const { return CXXNewExprBits.IsArray; } - Expr *getArraySize() { - return isArray() - ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]) - : nullptr; + Optional<Expr *> getArraySize() { + if (!isArray()) + return None; + return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]); } - const Expr *getArraySize() const { - return isArray() - ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]) - : nullptr; + Optional<const Expr *> getArraySize() const { + if (!isArray()) + return None; + return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]); } unsigned getNumPlacementArgs() const { @@ -2163,6 +2249,10 @@ public: // Iterators child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); } + + const_child_range children() const { + return const_child_range(const_cast<CXXNewExpr *>(this)->children()); + } }; /// Represents a \c delete expression for memory deallocation and @@ -2229,6 +2319,10 @@ public: // Iterators child_range children() { return child_range(&Argument, &Argument + 1); } + + const_child_range children() const { + return const_child_range(&Argument, &Argument + 1); + } }; /// Stores the type being destroyed by a pseudo-destructor expression. @@ -2417,6 +2511,10 @@ public: // Iterators child_range children() { return child_range(&Base, &Base + 1); } + + const_child_range children() const { + return const_child_range(&Base, &Base + 1); + } }; /// A type trait used in the implementation of various C++11 and @@ -2501,6 +2599,10 @@ public: 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()); + } }; /// An Embarcadero array type trait, as used in the implementation of @@ -2568,6 +2670,10 @@ public: 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()); + } }; /// An expression trait intrinsic. @@ -2628,6 +2734,10 @@ public: 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()); + } }; /// A reference to an overloaded function set, either an @@ -2920,6 +3030,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == UnresolvedLookupExprClass; } @@ -3074,6 +3188,10 @@ public: 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 an expression -- generally a full-expression -- that @@ -3143,6 +3261,10 @@ public: // Iterators child_range children() { return child_range(&SubExpr, &SubExpr + 1); } + + const_child_range children() const { + return const_child_range(&SubExpr, &SubExpr + 1); + } }; /// Describes an explicit type conversion that uses functional @@ -3272,6 +3394,12 @@ public: auto **begin = reinterpret_cast<Stmt **>(arg_begin()); return child_range(begin, begin + arg_size()); } + + const_child_range children() const { + auto **begin = reinterpret_cast<Stmt **>( + const_cast<CXXUnresolvedConstructExpr *>(this)->arg_begin()); + return const_child_range(begin, begin + arg_size()); + } }; /// Represents a C++ member access expression where the actual @@ -3518,6 +3646,12 @@ public: return child_range(child_iterator(), child_iterator()); return child_range(&Base, &Base + 1); } + + const_child_range children() const { + if (isImplicitAccess()) + return const_child_range(const_child_iterator(), const_child_iterator()); + return const_child_range(&Base, &Base + 1); + } }; /// Represents a C++ member access expression for which lookup @@ -3681,6 +3815,12 @@ public: return child_range(child_iterator(), child_iterator()); return child_range(&Base, &Base + 1); } + + const_child_range children() const { + if (isImplicitAccess()) + return const_child_range(const_child_iterator(), const_child_iterator()); + return const_child_range(&Base, &Base + 1); + } }; DeclAccessPair *OverloadExpr::getTrailingResults() { @@ -3750,6 +3890,10 @@ public: // Iterators child_range children() { return child_range(&Operand, &Operand + 1); } + + const_child_range children() const { + return const_child_range(&Operand, &Operand + 1); + } }; /// Represents a C++11 pack expansion that produces a sequence of @@ -3830,6 +3974,10 @@ public: child_range children() { return child_range(&Pattern, &Pattern + 1); } + + const_child_range children() const { + return const_child_range(&Pattern, &Pattern + 1); + } }; /// Represents an expression that computes the length of a parameter @@ -3951,6 +4099,10 @@ public: 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 reference to a non-type template parameter @@ -3997,6 +4149,10 @@ public: // Iterators child_range children() { return child_range(&Replacement, &Replacement + 1); } + + const_child_range children() const { + return const_child_range(&Replacement, &Replacement + 1); + } }; /// Represents a reference to a non-type template parameter pack that @@ -4059,10 +4215,14 @@ public: 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 reference to a function parameter pack that has been -/// substituted but not yet expanded. +/// Represents a reference to a function parameter pack or init-capture pack +/// that has been substituted but not yet expanded. /// /// When a pack expansion contains multiple parameter packs at different levels, /// this node is used to represent a function parameter pack at an outer level @@ -4077,13 +4237,13 @@ public: /// \endcode class FunctionParmPackExpr final : public Expr, - private llvm::TrailingObjects<FunctionParmPackExpr, ParmVarDecl *> { + private llvm::TrailingObjects<FunctionParmPackExpr, VarDecl *> { friend class ASTReader; friend class ASTStmtReader; friend TrailingObjects; /// The function parameter pack which was referenced. - ParmVarDecl *ParamPack; + VarDecl *ParamPack; /// The location of the function parameter pack reference. SourceLocation NameLoc; @@ -4091,35 +4251,35 @@ class FunctionParmPackExpr final /// The number of expansions of this pack. unsigned NumParameters; - FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack, + FunctionParmPackExpr(QualType T, VarDecl *ParamPack, SourceLocation NameLoc, unsigned NumParams, - ParmVarDecl *const *Params); + VarDecl *const *Params); public: static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T, - ParmVarDecl *ParamPack, + VarDecl *ParamPack, SourceLocation NameLoc, - ArrayRef<ParmVarDecl *> Params); + ArrayRef<VarDecl *> Params); static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context, unsigned NumParams); /// Get the parameter pack which this expression refers to. - ParmVarDecl *getParameterPack() const { return ParamPack; } + VarDecl *getParameterPack() const { return ParamPack; } /// Get the location of the parameter pack. SourceLocation getParameterPackLocation() const { return NameLoc; } /// Iterators over the parameters which the parameter pack expanded /// into. - using iterator = ParmVarDecl * const *; - iterator begin() const { return getTrailingObjects<ParmVarDecl *>(); } + using iterator = VarDecl * const *; + iterator begin() const { return getTrailingObjects<VarDecl *>(); } iterator end() const { return begin() + NumParameters; } /// Get the number of parameters in this parameter pack. unsigned getNumExpansions() const { return NumParameters; } /// Get an expansion of the parameter pack by index. - ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; } + VarDecl *getExpansion(unsigned I) const { return begin()[I]; } SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; } SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; } @@ -4131,6 +4291,10 @@ public: 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 prvalue temporary that is written into memory so that @@ -4253,6 +4417,15 @@ public: auto ES = State.get<ExtraState *>(); return child_range(&ES->Temporary, &ES->Temporary + 1); } + + const_child_range children() const { + if (State.is<Stmt *>()) + return const_child_range(State.getAddrOfPtr1(), + State.getAddrOfPtr1() + 1); + + auto ES = State.get<ExtraState *>(); + return const_child_range(&ES->Temporary, &ES->Temporary + 1); + } }; /// Represents a folding of a pack over an operator. @@ -4270,18 +4443,21 @@ class CXXFoldExpr : public Expr { SourceLocation LParenLoc; SourceLocation EllipsisLoc; SourceLocation RParenLoc; + // When 0, the number of expansions is not known. Otherwise, this is one more + // than the number of expansions. + unsigned NumExpansions; Stmt *SubExprs[2]; BinaryOperatorKind Opcode; public: CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS, - SourceLocation RParenLoc) + SourceLocation RParenLoc, Optional<unsigned> NumExpansions) : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary, /*Dependent*/ true, true, true, /*ContainsUnexpandedParameterPack*/ false), LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), - Opcode(Opcode) { + NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) { SubExprs[0] = LHS; SubExprs[1] = RHS; } @@ -4308,6 +4484,12 @@ public: SourceLocation getEllipsisLoc() const { return EllipsisLoc; } BinaryOperatorKind getOperator() const { return Opcode; } + Optional<unsigned> getNumExpansions() const { + if (NumExpansions) + return NumExpansions - 1; + return None; + } + SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; } SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } @@ -4318,6 +4500,10 @@ public: // Iterators child_range children() { return child_range(SubExprs, SubExprs + 2); } + + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + 2); + } }; /// Represents an expression that might suspend coroutine execution; @@ -4409,6 +4595,10 @@ public: return child_range(SubExprs, SubExprs + SubExpr::Count); } + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + SubExpr::Count); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == CoawaitExprClass || T->getStmtClass() == CoyieldExprClass; @@ -4493,6 +4683,10 @@ public: child_range children() { return child_range(SubExprs, SubExprs + 2); } + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + 2); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == DependentCoawaitExprClass; } @@ -4522,6 +4716,35 @@ public: } }; +/// Represents a C++2a __builtin_bit_cast(T, v) expression. Used to implement +/// std::bit_cast. These can sometimes be evaluated as part of a constant +/// expression, but otherwise CodeGen to a simple memcpy in general. +class BuiltinBitCastExpr final + : public ExplicitCastExpr, + private llvm::TrailingObjects<BuiltinBitCastExpr, CXXBaseSpecifier *> { + friend class ASTStmtReader; + friend class CastExpr; + friend class TrailingObjects; + + SourceLocation KWLoc; + SourceLocation RParenLoc; + +public: + BuiltinBitCastExpr(QualType T, ExprValueKind VK, CastKind CK, Expr *SrcExpr, + TypeSourceInfo *DstType, SourceLocation KWLoc, + SourceLocation RParenLoc) + : ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0, + DstType), + KWLoc(KWLoc), RParenLoc(RParenLoc) {} + + SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == BuiltinBitCastExprClass; + } +}; + } // namespace clang #endif // LLVM_CLANG_AST_EXPRCXX_H diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index c7b305f3304e..dbb2b2ff7099 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -1,9 +1,8 @@ //===- ExprObjC.h - Classes for representing ObjC expressions ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -73,6 +72,10 @@ public: // Iterators child_range children() { return child_range(&String, &String+1); } + const_child_range children() const { + return const_child_range(&String, &String + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCStringLiteralClass; } @@ -105,6 +108,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCBoolLiteralExprClass; } @@ -139,6 +146,12 @@ public: return BoxingMethod; } + // Indicates whether this boxed expression can be emitted as a compile-time + // constant. + bool isExpressibleAsConstantInitializer() const { + return !BoxingMethod && SubExpr; + } + SourceLocation getAtLoc() const { return Range.getBegin(); } SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } @@ -151,6 +164,10 @@ public: // Iterators child_range children() { return child_range(&SubExpr, &SubExpr+1); } + const_child_range children() const { + return const_child_range(&SubExpr, &SubExpr + 1); + } + using const_arg_iterator = ConstExprIterator; const_arg_iterator arg_begin() const { @@ -229,6 +246,11 @@ public: reinterpret_cast<Stmt **>(getElements()) + NumElements); } + const_child_range children() const { + auto Children = const_cast<ObjCArrayLiteral *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCArrayLiteralClass; } @@ -256,12 +278,6 @@ struct ObjCDictionaryElement { } // namespace clang -namespace llvm { - -template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {}; - -} // namespace llvm - namespace clang { /// Internal struct for storing Key/value pair. @@ -375,6 +391,11 @@ public: NumElements * 2); } + const_child_range children() const { + auto Children = const_cast<ObjCDictionaryLiteral *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCDictionaryLiteralClass; } @@ -420,6 +441,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCEncodeExprClass; } @@ -458,6 +483,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSelectorExprClass; } @@ -504,6 +533,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCProtocolExprClass; } @@ -567,6 +600,10 @@ public: // Iterators child_range children() { return child_range(&Base, &Base+1); } + const_child_range children() const { + return const_child_range(&Base, &Base + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIvarRefExprClass; } @@ -758,6 +795,11 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + auto Children = const_cast<ObjCPropertyRefExpr *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCPropertyRefExprClass; } @@ -867,6 +909,10 @@ public: return child_range(SubExprs, SubExprs+END_EXPR); } + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + END_EXPR); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSubscriptRefExprClass; } @@ -1187,6 +1233,13 @@ public: /// sent to. ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } + /// \return the return type of the message being sent. + /// This is not always the type of the message expression itself because + /// of references (the expression would not have a reference type). + /// It is also not always the declared return type of the method because + /// of `instancetype` (in that case it's an expression type). + QualType getCallReturnType(ASTContext &Ctx) const; + /// Source range of the receiver. SourceRange getReceiverRange() const; @@ -1402,6 +1455,8 @@ public: // Iterators child_range children(); + const_child_range children() const; + using arg_iterator = ExprIterator; using const_arg_iterator = ConstExprIterator; @@ -1488,6 +1543,10 @@ public: // Iterators child_range children() { return child_range(&Base, &Base+1); } + const_child_range children() const { + return const_child_range(&Base, &Base + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIsaExprClass; } @@ -1549,6 +1608,10 @@ public: child_range children() { return child_range(&Operand, &Operand+1); } + const_child_range children() const { + return const_child_range(&Operand, &Operand + 1); + } + // Source locations are determined by the subexpression. SourceLocation getBeginLoc() const LLVM_READONLY { return Operand->getBeginLoc(); @@ -1661,6 +1724,10 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCAvailabilityCheckExprClass; } diff --git a/include/clang/AST/ExprOpenMP.h b/include/clang/AST/ExprOpenMP.h index d88eebf5e54f..5607d2d1dc58 100644 --- a/include/clang/AST/ExprOpenMP.h +++ b/include/clang/AST/ExprOpenMP.h @@ -1,9 +1,8 @@ //===--- ExprOpenMP.h - Classes for representing expressions ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -123,6 +122,10 @@ public: child_range children() { return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); } + + const_child_range children() const { + return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); + } }; } // end namespace clang diff --git a/include/clang/AST/ExternalASTMerger.h b/include/clang/AST/ExternalASTMerger.h index 7b01fa8cbced..d89189da04f0 100644 --- a/include/clang/AST/ExternalASTMerger.h +++ b/include/clang/AST/ExternalASTMerger.h @@ -1,9 +1,8 @@ //===--- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index 525d4c78b362..304633668bd1 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -1,9 +1,8 @@ //===- ExternalASTSource.h - Abstract 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/FormatString.h b/include/clang/AST/FormatString.h index 4a89c797b648..643fb822f7f4 100644 --- a/include/clang/AST/FormatString.h +++ b/include/clang/AST/FormatString.h @@ -1,9 +1,8 @@ //= FormatString.h - Analysis of printf/fprintf format strings --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -68,6 +67,7 @@ public: None, AsChar, // 'hh' AsShort, // 'h' + AsShortLong, // 'hl' (OpenCL float/int vector element) AsLong, // 'l' AsLongLong, // 'll' AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types) @@ -437,7 +437,8 @@ public: bool usesPositionalArg() const { return UsesPositionalArg; } - bool hasValidLengthModifier(const TargetInfo &Target) const; + bool hasValidLengthModifier(const TargetInfo &Target, + const LangOptions &LO) const; bool hasStandardLengthModifier() const; diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h index a3c0cab3799f..86fd0f6aa907 100644 --- a/include/clang/AST/GlobalDecl.h +++ b/include/clang/AST/GlobalDecl.h @@ -1,9 +1,8 @@ //===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -28,6 +27,12 @@ namespace clang { +enum class DynamicInitKind : unsigned { + NoStub = 0, + Initializer, + AtExit, +}; + /// GlobalDecl - represents a global declaration. This can either be a /// CXXConstructorDecl and the constructor type (Base, Complete). /// a CXXDestructorDecl and the destructor type (Base, Complete) or @@ -56,6 +61,8 @@ public: GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {} GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {} + GlobalDecl(const VarDecl *D, DynamicInitKind StubKind) + : Value(D, unsigned(StubKind)) {} GlobalDecl getCanonicalDecl() const { GlobalDecl CanonGD; @@ -78,6 +85,13 @@ public: return static_cast<CXXDtorType>(Value.getInt()); } + DynamicInitKind getDynamicInitKind() const { + assert(isa<VarDecl>(getDecl()) && + cast<VarDecl>(getDecl())->hasGlobalStorage() && + "Decl is not a global variable!"); + return static_cast<DynamicInitKind>(Value.getInt()); + } + unsigned getMultiVersionIndex() const { assert(isa<FunctionDecl>(getDecl()) && !isa<CXXConstructorDecl>(getDecl()) && @@ -105,6 +119,20 @@ public: return Result; } + GlobalDecl getWithCtorType(CXXCtorType Type) { + assert(isa<CXXConstructorDecl>(getDecl())); + GlobalDecl Result(*this); + Result.Value.setInt(Type); + return Result; + } + + GlobalDecl getWithDtorType(CXXDtorType Type) { + assert(isa<CXXDestructorDecl>(getDecl())); + GlobalDecl Result(*this); + Result.Value.setInt(Type); + return Result; + } + GlobalDecl getWithMultiVersionIndex(unsigned Index) { assert(isa<FunctionDecl>(getDecl()) && !isa<CXXConstructorDecl>(getDecl()) && @@ -140,13 +168,6 @@ namespace llvm { } }; - // GlobalDecl isn't *technically* a POD type. However, its copy constructor, - // copy assignment operator, and destructor are all trivial. - template <> - struct isPodLike<clang::GlobalDecl> { - static const bool value = true; - }; - } // namespace llvm #endif // LLVM_CLANG_AST_GLOBALDECL_H diff --git a/include/clang/AST/JSONNodeDumper.h b/include/clang/AST/JSONNodeDumper.h new file mode 100644 index 000000000000..238e43aad78b --- /dev/null +++ b/include/clang/AST/JSONNodeDumper.h @@ -0,0 +1,425 @@ +//===--- JSONNodeDumper.h - Printing of AST nodes to JSON -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements AST dumping of components of individual AST nodes to +// a JSON. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_JSONNODEDUMPER_H +#define LLVM_CLANG_AST_JSONNODEDUMPER_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTNodeTraverser.h" +#include "clang/AST/ASTDumperUtils.h" +#include "clang/AST/AttrVisitor.h" +#include "clang/AST/CommentCommandTraits.h" +#include "clang/AST/CommentVisitor.h" +#include "clang/AST/ExprCXX.h" +#include "llvm/Support/JSON.h" + +namespace clang { + +class NodeStreamer { + bool FirstChild = true; + bool TopLevel = true; + llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending; + +protected: + llvm::json::OStream JOS; + +public: + /// Add a child of the current node. Calls DoAddChild without arguments + template <typename Fn> void AddChild(Fn DoAddChild) { + return AddChild("", DoAddChild); + } + + /// Add a child of the current node with an optional label. + /// Calls DoAddChild without arguments. + template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) { + // If we're at the top level, there's nothing interesting to do; just + // run the dumper. + if (TopLevel) { + TopLevel = false; + JOS.objectBegin(); + + DoAddChild(); + + while (!Pending.empty()) { + Pending.back()(true); + Pending.pop_back(); + } + + JOS.objectEnd(); + TopLevel = true; + return; + } + + // We need to capture an owning-string in the lambda because the lambda + // is invoked in a deferred manner. + std::string LabelStr = !Label.empty() ? Label : "inner"; + bool WasFirstChild = FirstChild; + auto DumpWithIndent = [=](bool IsLastChild) { + if (WasFirstChild) { + JOS.attributeBegin(LabelStr); + JOS.arrayBegin(); + } + + FirstChild = true; + unsigned Depth = Pending.size(); + JOS.objectBegin(); + + DoAddChild(); + + // If any children are left, they're the last at their nesting level. + // Dump those ones out now. + while (Depth < Pending.size()) { + Pending.back()(true); + this->Pending.pop_back(); + } + + JOS.objectEnd(); + + if (IsLastChild) { + JOS.arrayEnd(); + JOS.attributeEnd(); + } + }; + + if (FirstChild) { + Pending.push_back(std::move(DumpWithIndent)); + } else { + Pending.back()(false); + Pending.back() = std::move(DumpWithIndent); + } + FirstChild = false; + } + + NodeStreamer(raw_ostream &OS) : JOS(OS, 2) {} +}; + +// Dumps AST nodes in JSON format. There is no implied stability for the +// content or format of the dump between major releases of Clang, other than it +// being valid JSON output. Further, there is no requirement that the +// information dumped is a complete representation of the AST, only that the +// information presented is correct. +class JSONNodeDumper + : public ConstAttrVisitor<JSONNodeDumper>, + public comments::ConstCommentVisitor<JSONNodeDumper, void, + const comments::FullComment *>, + public ConstTemplateArgumentVisitor<JSONNodeDumper>, + public ConstStmtVisitor<JSONNodeDumper>, + public TypeVisitor<JSONNodeDumper>, + public ConstDeclVisitor<JSONNodeDumper>, + public NodeStreamer { + friend class JSONDumper; + + const SourceManager &SM; + ASTContext& Ctx; + PrintingPolicy PrintPolicy; + const comments::CommandTraits *Traits; + StringRef LastLocFilename; + unsigned LastLocLine, LastLocPresumedLine; + + using InnerAttrVisitor = ConstAttrVisitor<JSONNodeDumper>; + using InnerCommentVisitor = + comments::ConstCommentVisitor<JSONNodeDumper, void, + const comments::FullComment *>; + using InnerTemplateArgVisitor = ConstTemplateArgumentVisitor<JSONNodeDumper>; + using InnerStmtVisitor = ConstStmtVisitor<JSONNodeDumper>; + using InnerTypeVisitor = TypeVisitor<JSONNodeDumper>; + using InnerDeclVisitor = ConstDeclVisitor<JSONNodeDumper>; + + void attributeOnlyIfTrue(StringRef Key, bool Value) { + if (Value) + JOS.attribute(Key, Value); + } + + // Writes the attributes of a SourceLocation object without. + void writeBareSourceLocation(SourceLocation Loc, bool IsSpelling); + + // Writes the attributes of a SourceLocation to JSON based on its presumed + // spelling location. If the given location represents a macro invocation, + // this outputs two sub-objects: one for the spelling and one for the + // expansion location. + void writeSourceLocation(SourceLocation Loc); + void writeSourceRange(SourceRange R); + std::string createPointerRepresentation(const void *Ptr); + llvm::json::Object createQualType(QualType QT, bool Desugar = true); + llvm::json::Object createBareDeclRef(const Decl *D); + void writeBareDeclRef(const Decl *D); + llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD); + llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS); + std::string createAccessSpecifier(AccessSpecifier AS); + llvm::json::Array createCastPath(const CastExpr *C); + + void writePreviousDeclImpl(...) {} + + template <typename T> void writePreviousDeclImpl(const Mergeable<T> *D) { + const T *First = D->getFirstDecl(); + if (First != D) + JOS.attribute("firstRedecl", createPointerRepresentation(First)); + } + + template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) { + const T *Prev = D->getPreviousDecl(); + if (Prev) + JOS.attribute("previousDecl", createPointerRepresentation(Prev)); + } + void addPreviousDeclaration(const Decl *D); + + StringRef getCommentCommandName(unsigned CommandID) const; + +public: + JSONNodeDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx, + const PrintingPolicy &PrintPolicy, + const comments::CommandTraits *Traits) + : NodeStreamer(OS), SM(SrcMgr), Ctx(Ctx), PrintPolicy(PrintPolicy), + Traits(Traits), LastLocLine(0), LastLocPresumedLine(0) {} + + void Visit(const Attr *A); + void Visit(const Stmt *Node); + void Visit(const Type *T); + void Visit(QualType T); + void Visit(const Decl *D); + + void Visit(const comments::Comment *C, const comments::FullComment *FC); + void Visit(const TemplateArgument &TA, SourceRange R = {}, + const Decl *From = nullptr, StringRef Label = {}); + void Visit(const CXXCtorInitializer *Init); + void Visit(const OMPClause *C); + void Visit(const BlockDecl::Capture &C); + void Visit(const GenericSelectionExpr::ConstAssociation &A); + + void VisitTypedefType(const TypedefType *TT); + void VisitFunctionType(const FunctionType *T); + void VisitFunctionProtoType(const FunctionProtoType *T); + void VisitRValueReferenceType(const ReferenceType *RT); + void VisitArrayType(const ArrayType *AT); + void VisitConstantArrayType(const ConstantArrayType *CAT); + void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *VT); + void VisitVectorType(const VectorType *VT); + void VisitUnresolvedUsingType(const UnresolvedUsingType *UUT); + void VisitUnaryTransformType(const UnaryTransformType *UTT); + void VisitTagType(const TagType *TT); + void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT); + void VisitAutoType(const AutoType *AT); + void VisitTemplateSpecializationType(const TemplateSpecializationType *TST); + void VisitInjectedClassNameType(const InjectedClassNameType *ICNT); + void VisitObjCInterfaceType(const ObjCInterfaceType *OIT); + void VisitPackExpansionType(const PackExpansionType *PET); + void VisitElaboratedType(const ElaboratedType *ET); + void VisitMacroQualifiedType(const MacroQualifiedType *MQT); + void VisitMemberPointerType(const MemberPointerType *MPT); + + void VisitNamedDecl(const NamedDecl *ND); + void VisitTypedefDecl(const TypedefDecl *TD); + void VisitTypeAliasDecl(const TypeAliasDecl *TAD); + void VisitNamespaceDecl(const NamespaceDecl *ND); + void VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD); + void VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD); + void VisitUsingDecl(const UsingDecl *UD); + void VisitUsingShadowDecl(const UsingShadowDecl *USD); + void VisitVarDecl(const VarDecl *VD); + void VisitFieldDecl(const FieldDecl *FD); + void VisitFunctionDecl(const FunctionDecl *FD); + void VisitEnumDecl(const EnumDecl *ED); + void VisitEnumConstantDecl(const EnumConstantDecl *ECD); + void VisitRecordDecl(const RecordDecl *RD); + void VisitCXXRecordDecl(const CXXRecordDecl *RD); + void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); + void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); + void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); + void VisitLinkageSpecDecl(const LinkageSpecDecl *LSD); + void VisitAccessSpecDecl(const AccessSpecDecl *ASD); + void VisitFriendDecl(const FriendDecl *FD); + + void VisitObjCIvarDecl(const ObjCIvarDecl *D); + void VisitObjCMethodDecl(const ObjCMethodDecl *D); + void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D); + void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); + void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); + void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); + void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); + void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); + void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); + void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); + void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); + void VisitBlockDecl(const BlockDecl *D); + + void VisitDeclRefExpr(const DeclRefExpr *DRE); + void VisitPredefinedExpr(const PredefinedExpr *PE); + void VisitUnaryOperator(const UnaryOperator *UO); + void VisitBinaryOperator(const BinaryOperator *BO); + void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO); + void VisitMemberExpr(const MemberExpr *ME); + void VisitCXXNewExpr(const CXXNewExpr *NE); + void VisitCXXDeleteExpr(const CXXDeleteExpr *DE); + void VisitCXXThisExpr(const CXXThisExpr *TE); + void VisitCastExpr(const CastExpr *CE); + void VisitImplicitCastExpr(const ImplicitCastExpr *ICE); + void VisitCallExpr(const CallExpr *CE); + void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *TTE); + void VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE); + void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *ULE); + void VisitAddrLabelExpr(const AddrLabelExpr *ALE); + void VisitCXXTypeidExpr(const CXXTypeidExpr *CTE); + void VisitConstantExpr(const ConstantExpr *CE); + void VisitInitListExpr(const InitListExpr *ILE); + void VisitGenericSelectionExpr(const GenericSelectionExpr *GSE); + void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *UCE); + void VisitCXXConstructExpr(const CXXConstructExpr *CE); + void VisitExprWithCleanups(const ExprWithCleanups *EWC); + void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE); + void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *MTE); + void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *ME); + + void VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE); + void VisitObjCMessageExpr(const ObjCMessageExpr *OME); + void VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE); + void VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE); + void VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE); + void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE); + void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *OSRE); + void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE); + void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE); + + void VisitIntegerLiteral(const IntegerLiteral *IL); + void VisitCharacterLiteral(const CharacterLiteral *CL); + void VisitFixedPointLiteral(const FixedPointLiteral *FPL); + void VisitFloatingLiteral(const FloatingLiteral *FL); + void VisitStringLiteral(const StringLiteral *SL); + void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE); + + void VisitIfStmt(const IfStmt *IS); + void VisitSwitchStmt(const SwitchStmt *SS); + void VisitCaseStmt(const CaseStmt *CS); + void VisitLabelStmt(const LabelStmt *LS); + void VisitGotoStmt(const GotoStmt *GS); + void VisitWhileStmt(const WhileStmt *WS); + void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS); + + void VisitNullTemplateArgument(const TemplateArgument &TA); + void VisitTypeTemplateArgument(const TemplateArgument &TA); + void VisitDeclarationTemplateArgument(const TemplateArgument &TA); + void VisitNullPtrTemplateArgument(const TemplateArgument &TA); + void VisitIntegralTemplateArgument(const TemplateArgument &TA); + void VisitTemplateTemplateArgument(const TemplateArgument &TA); + void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA); + void VisitExpressionTemplateArgument(const TemplateArgument &TA); + void VisitPackTemplateArgument(const TemplateArgument &TA); + + void visitTextComment(const comments::TextComment *C, + const comments::FullComment *); + void visitInlineCommandComment(const comments::InlineCommandComment *C, + const comments::FullComment *); + void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C, + const comments::FullComment *); + void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C, + const comments::FullComment *); + void visitBlockCommandComment(const comments::BlockCommandComment *C, + const comments::FullComment *); + void visitParamCommandComment(const comments::ParamCommandComment *C, + const comments::FullComment *FC); + void visitTParamCommandComment(const comments::TParamCommandComment *C, + const comments::FullComment *FC); + void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C, + const comments::FullComment *); + void + visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C, + const comments::FullComment *); + void visitVerbatimLineComment(const comments::VerbatimLineComment *C, + const comments::FullComment *); +}; + +class JSONDumper : public ASTNodeTraverser<JSONDumper, JSONNodeDumper> { + JSONNodeDumper NodeDumper; + + template <typename SpecializationDecl> + void writeTemplateDeclSpecialization(const SpecializationDecl *SD, + bool DumpExplicitInst, + bool DumpRefOnly) { + bool DumpedAny = false; + for (const auto *RedeclWithBadType : SD->redecls()) { + // FIXME: The redecls() range sometimes has elements of a less-specific + // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives + // us TagDecls, and should give CXXRecordDecls). + const auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType); + if (!Redecl) { + // Found the injected-class-name for a class template. This will be + // dumped as part of its surrounding class so we don't need to dump it + // here. + assert(isa<CXXRecordDecl>(RedeclWithBadType) && + "expected an injected-class-name"); + continue; + } + + switch (Redecl->getTemplateSpecializationKind()) { + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + if (!DumpExplicitInst) + break; + LLVM_FALLTHROUGH; + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + if (DumpRefOnly) + NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(Redecl); }); + else + Visit(Redecl); + DumpedAny = true; + break; + case TSK_ExplicitSpecialization: + break; + } + } + + // Ensure we dump at least one decl for each specialization. + if (!DumpedAny) + NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(SD); }); + } + + template <typename TemplateDecl> + void writeTemplateDecl(const TemplateDecl *TD, bool DumpExplicitInst) { + // FIXME: it would be nice to dump template parameters and specializations + // to their own named arrays rather than shoving them into the "inner" + // array. However, template declarations are currently being handled at the + // wrong "level" of the traversal hierarchy and so it is difficult to + // achieve without losing information elsewhere. + + dumpTemplateParameters(TD->getTemplateParameters()); + + Visit(TD->getTemplatedDecl()); + + for (const auto *Child : TD->specializations()) + writeTemplateDeclSpecialization(Child, DumpExplicitInst, + !TD->isCanonicalDecl()); + } + +public: + JSONDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx, + const PrintingPolicy &PrintPolicy, + const comments::CommandTraits *Traits) + : NodeDumper(OS, SrcMgr, Ctx, PrintPolicy, Traits) {} + + JSONNodeDumper &doGetNodeDelegate() { return NodeDumper; } + + void VisitFunctionTemplateDecl(const FunctionTemplateDecl *FTD) { + writeTemplateDecl(FTD, true); + } + void VisitClassTemplateDecl(const ClassTemplateDecl *CTD) { + writeTemplateDecl(CTD, false); + } + void VisitVarTemplateDecl(const VarTemplateDecl *VTD) { + writeTemplateDecl(VTD, false); + } +}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_JSONNODEDUMPER_H diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h index f246bc423bfb..8e2806545dd6 100644 --- a/include/clang/AST/LambdaCapture.h +++ b/include/clang/AST/LambdaCapture.h @@ -1,9 +1,8 @@ //===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h index 47dac4362c8e..e42f0449f6db 100644 --- a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h +++ b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h @@ -1,9 +1,8 @@ //===--- LexicallyOrderedRecursiveASTVisitor.h - ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/LocInfoType.h b/include/clang/AST/LocInfoType.h index 802d9134ebde..1073174bcf91 100644 --- a/include/clang/AST/LocInfoType.h +++ b/include/clang/AST/LocInfoType.h @@ -1,9 +1,8 @@ //===--- LocInfoType.h - Parsed Type with Location Information---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index 309ed5a1a5d2..b1fbe936136a 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -1,9 +1,8 @@ //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -244,6 +243,19 @@ public: static MicrosoftMangleContext *create(ASTContext &Context, DiagnosticsEngine &Diags); }; + +class ASTNameGenerator { +public: + explicit ASTNameGenerator(ASTContext &Ctx); + ~ASTNameGenerator(); + bool writeName(const Decl *D, raw_ostream &OS); + std::string getName(const Decl *D); + std::vector<std::string> getAllManglings(const Decl *D); + +private: + class Implementation; + std::unique_ptr<Implementation> Impl; +}; } #endif diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h index ff2148e3516d..f1ca6a05dbaf 100644 --- a/include/clang/AST/MangleNumberingContext.h +++ b/include/clang/AST/MangleNumberingContext.h @@ -1,9 +1,8 @@ //=== MangleNumberingContext.h - Context for mangling numbers ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h index f9340c64f3eb..21f0c5458d81 100644 --- a/include/clang/AST/NSAPI.h +++ b/include/clang/AST/NSAPI.h @@ -1,9 +1,8 @@ //===--- NSAPI.h - NSFoundation APIs ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index 8befe9ae4258..c6fae6f465ff 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -1,9 +1,8 @@ //===- NestedNameSpecifier.h - C++ nested name specifiers -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/NonTrivialTypeVisitor.h b/include/clang/AST/NonTrivialTypeVisitor.h index bab373dbb298..aafcedb9d10b 100644 --- a/include/clang/AST/NonTrivialTypeVisitor.h +++ b/include/clang/AST/NonTrivialTypeVisitor.h @@ -1,9 +1,8 @@ //===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ODRHash.h b/include/clang/AST/ODRHash.h index feaa83844a1a..cd4a6f37f5db 100644 --- a/include/clang/AST/ODRHash.h +++ b/include/clang/AST/ODRHash.h @@ -1,9 +1,8 @@ //===-- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/AST/OSLog.h b/include/clang/AST/OSLog.h index 2b21855e7a6e..c24e79ce6da0 100644 --- a/include/clang/AST/OSLog.h +++ b/include/clang/AST/OSLog.h @@ -1,9 +1,8 @@ //= OSLog.h - Analysis of calls to os_log builtins --*- C++ -*-===============// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index bdcdf74b2630..eadcc62a3457 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -1,9 +1,8 @@ //===- OpenMPClause.h - Classes for OpenMP clauses --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -91,6 +90,15 @@ public: return const_child_range(Children.begin(), Children.end()); } + /// Get the iterator range for the expressions used in the clauses. Used + /// expressions include only the children that must be evaluated at the + /// runtime before entering the construct. + child_range used_children(); + const_child_range used_children() const { + auto Children = const_cast<OMPClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const OMPClause *) { return true; } }; @@ -157,6 +165,20 @@ public: static const OMPClauseWithPostUpdate *get(const OMPClause *C); }; +/// This structure contains most locations needed for by an OMPVarListClause. +struct OMPVarListLocTy { + /// Starting location of the clause (the clause keyword). + SourceLocation StartLoc; + /// Location of '('. + SourceLocation LParenLoc; + /// Ending location of the clause. + SourceLocation EndLoc; + OMPVarListLocTy() = default; + OMPVarListLocTy(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : StartLoc(StartLoc), LParenLoc(LParenLoc), EndLoc(EndLoc) {} +}; + /// This represents clauses with the list of variables like 'private', /// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the /// '#pragma omp ...' directives. @@ -230,6 +252,166 @@ public: } }; +/// This represents 'allocator' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp allocate(a) allocator(omp_default_mem_alloc) +/// \endcode +/// In this example directive '#pragma omp allocate' has simple 'allocator' +/// clause with the allocator 'omp_default_mem_alloc'. +class OMPAllocatorClause : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// Expression with the allocator. + Stmt *Allocator = nullptr; + + /// Set allocator. + void setAllocator(Expr *A) { Allocator = A; } + +public: + /// Build 'allocator' clause with the given allocator. + /// + /// \param A Allocator. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc), + Allocator(A) {} + + /// Build an empty clause. + OMPAllocatorClause() + : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {} + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns allocator. + Expr *getAllocator() const { return cast_or_null<Expr>(Allocator); } + + child_range children() { return child_range(&Allocator, &Allocator + 1); } + + const_child_range children() const { + return const_child_range(&Allocator, &Allocator + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_allocator; + } +}; + +/// This represents clause 'allocate' in the '#pragma omp ...' directives. +/// +/// \code +/// #pragma omp parallel private(a) allocate(omp_default_mem_alloc :a) +/// \endcode +/// In this example directive '#pragma omp parallel' has clause 'private' +/// and clause 'allocate' for the variable 'a'. +class OMPAllocateClause final + : public OMPVarListClause<OMPAllocateClause>, + private llvm::TrailingObjects<OMPAllocateClause, Expr *> { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Allocator specified in the clause, or 'nullptr' if the default one is + /// used. + Expr *Allocator = nullptr; + /// Position of the ':' delimiter in the clause; + SourceLocation ColonLoc; + + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param Allocator Allocator expression. + /// \param ColonLoc Location of ':' delimiter. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, + Expr *Allocator, SourceLocation ColonLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause<OMPAllocateClause>(OMPC_allocate, StartLoc, LParenLoc, + EndLoc, N), + Allocator(Allocator), ColonLoc(ColonLoc) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + explicit OMPAllocateClause(unsigned N) + : OMPVarListClause<OMPAllocateClause>(OMPC_allocate, SourceLocation(), + SourceLocation(), SourceLocation(), + N) {} + + /// Sets location of ':' symbol in clause. + void setColonLoc(SourceLocation CL) { ColonLoc = CL; } + + void setAllocator(Expr *A) { Allocator = A; } + +public: + /// Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param Allocator Allocator expression. + /// \param ColonLoc Location of ':' delimiter. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + static OMPAllocateClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, Expr *Allocator, + SourceLocation ColonLoc, + SourceLocation EndLoc, ArrayRef<Expr *> VL); + + /// Returns the allocator expression or nullptr, if no allocator is specified. + Expr *getAllocator() const { return Allocator; } + + /// Returns the location of the ':' delimiter. + SourceLocation getColonLoc() const { return ColonLoc; } + + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + static OMPAllocateClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + const_child_range children() const { + auto Children = const_cast<OMPAllocateClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_allocate; + } +}; + /// This represents 'if' clause in the '#pragma omp ...' directive. /// /// \code @@ -315,6 +497,16 @@ public: child_range children() { return child_range(&Condition, &Condition + 1); } + const_child_range children() const { + return const_child_range(&Condition, &Condition + 1); + } + + child_range used_children(); + const_child_range used_children() const { + auto Children = const_cast<OMPIfClause *>(this)->used_children(); + return const_child_range(Children.begin(), Children.end()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_if; } @@ -366,6 +558,17 @@ public: child_range children() { return child_range(&Condition, &Condition + 1); } + const_child_range children() const { + return const_child_range(&Condition, &Condition + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_final; } @@ -427,6 +630,17 @@ public: child_range children() { return child_range(&NumThreads, &NumThreads + 1); } + const_child_range children() const { + return const_child_range(&NumThreads, &NumThreads + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_num_threads; } @@ -482,6 +696,17 @@ public: child_range children() { return child_range(&Safelen, &Safelen + 1); } + const_child_range children() const { + return const_child_range(&Safelen, &Safelen + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_safelen; } @@ -536,6 +761,17 @@ public: child_range children() { return child_range(&Simdlen, &Simdlen + 1); } + const_child_range children() const { + return const_child_range(&Simdlen, &Simdlen + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_simdlen; } @@ -591,6 +827,17 @@ public: child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); } + const_child_range children() const { + return const_child_range(&NumForLoops, &NumForLoops + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_collapse; } @@ -659,6 +906,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_default; } @@ -729,6 +987,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_proc_bind; } @@ -760,6 +1029,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_unified_address; } @@ -791,6 +1071,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_unified_shared_memory; } @@ -822,6 +1113,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_reverse_offload; } @@ -854,6 +1156,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_dynamic_allocators; } @@ -933,6 +1246,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_atomic_default_mem_order; } @@ -1114,6 +1438,18 @@ public: reinterpret_cast<Stmt **>(&ChunkSize) + 1); } + const_child_range children() const { + auto Children = const_cast<OMPScheduleClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_schedule; } @@ -1199,6 +1535,17 @@ public: child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); } + const_child_range children() const { + return const_child_range(&NumForLoops, &NumForLoops + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_ordered; } @@ -1227,6 +1574,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_nowait; } @@ -1255,6 +1613,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_untied; } @@ -1284,6 +1653,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_mergeable; } @@ -1311,6 +1691,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_read; } @@ -1339,6 +1730,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_write; } @@ -1368,6 +1770,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_update; } @@ -1397,6 +1810,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_capture; } @@ -1426,6 +1850,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_seq_cst; } @@ -1519,6 +1954,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPPrivateClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_private; } @@ -1646,6 +2093,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPFirstprivateClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_firstprivate; } @@ -1845,6 +2304,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPLastprivateClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_lastprivate; } @@ -1905,6 +2376,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPSharedClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_shared; } @@ -2127,6 +2610,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPReductionClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_reduction; } @@ -2347,6 +2842,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPTaskReductionClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_task_reduction; } @@ -2590,6 +3097,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPInReductionClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_in_reduction; } @@ -2829,6 +3348,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPLinearClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_linear; } @@ -2916,6 +3447,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPAlignedClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_aligned; } @@ -3080,6 +3623,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPCopyinClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_copyin; } @@ -3231,6 +3786,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPCopyprivateClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_copyprivate; } @@ -3296,6 +3863,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPFlushClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_flush; } @@ -3415,6 +3994,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPDependClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_depend; } @@ -3478,6 +4069,17 @@ public: child_range children() { return child_range(&Device, &Device + 1); } + const_child_range children() const { + return const_child_range(&Device, &Device + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_device; } @@ -3506,6 +4108,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_threads; } @@ -3533,6 +4146,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_simd; } @@ -3596,6 +4220,24 @@ protected: getUniqueDeclarationsTotalNumber(ArrayRef<const ValueDecl *> Declarations); }; +/// This structure contains all sizes needed for by an +/// OMPMappableExprListClause. +struct OMPMappableExprListSizeTy { + /// Number of expressions listed. + unsigned NumVars; + /// Number of unique base declarations. + unsigned NumUniqueDeclarations; + /// Number of component lists. + unsigned NumComponentLists; + /// Total number of expression components. + unsigned NumComponents; + OMPMappableExprListSizeTy() = default; + OMPMappableExprListSizeTy(unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : NumVars(NumVars), NumUniqueDeclarations(NumUniqueDeclarations), + NumComponentLists(NumComponentLists), NumComponents(NumComponents) {} +}; + /// This represents clauses with a list of expressions that are mappable. /// Examples of these clauses are 'map' in /// '#pragma omp target [enter|exit] [data]...' directives, and 'to' and 'from @@ -3614,28 +4256,44 @@ class OMPMappableExprListClause : public OMPVarListClause<T>, /// Total number of components in this clause. unsigned NumComponents; + /// C++ nested name specifier for the associated user-defined mapper. + NestedNameSpecifierLoc MapperQualifierLoc; + + /// The associated user-defined mapper identifier information. + DeclarationNameInfo MapperIdInfo; + protected: /// Build a clause for \a NumUniqueDeclarations declarations, \a /// NumComponentLists total component lists, and \a NumComponents total /// components. /// /// \param K Kind of the clause. - /// \param StartLoc Starting location of the clause (the clause keyword). - /// \param LParenLoc Location of '('. - /// \param EndLoc Ending location of the clause. - /// \param NumVars Number of expressions listed in the clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause - one - /// list for each expression in the clause. - /// \param NumComponents Total number of expression components in the clause. - OMPMappableExprListClause(OpenMPClauseKind K, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, - unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPVarListClause<T>(K, StartLoc, LParenLoc, EndLoc, NumVars), - NumUniqueDeclarations(NumUniqueDeclarations), - NumComponentLists(NumComponentLists), NumComponents(NumComponents) {} + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + /// \param MapperQualifierLocPtr C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperIdInfoPtr The identifier of associated user-defined mapper. + OMPMappableExprListClause( + OpenMPClauseKind K, const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes, + NestedNameSpecifierLoc *MapperQualifierLocPtr = nullptr, + DeclarationNameInfo *MapperIdInfoPtr = nullptr) + : OMPVarListClause<T>(K, Locs.StartLoc, Locs.LParenLoc, Locs.EndLoc, + Sizes.NumVars), + NumUniqueDeclarations(Sizes.NumUniqueDeclarations), + NumComponentLists(Sizes.NumComponentLists), + NumComponents(Sizes.NumComponents) { + if (MapperQualifierLocPtr) + MapperQualifierLoc = *MapperQualifierLocPtr; + if (MapperIdInfoPtr) + MapperIdInfo = *MapperIdInfoPtr; + } /// Get the unique declarations that are in the trailing objects of the /// class. @@ -3816,6 +4474,42 @@ protected: } } + /// Set the nested name specifier of associated user-defined mapper. + void setMapperQualifierLoc(NestedNameSpecifierLoc NNSL) { + MapperQualifierLoc = NNSL; + } + + /// Set the name of associated user-defined mapper. + void setMapperIdInfo(DeclarationNameInfo MapperId) { + MapperIdInfo = MapperId; + } + + /// Get the user-defined mapper references that are in the trailing objects of + /// the class. + MutableArrayRef<Expr *> getUDMapperRefs() { + return llvm::makeMutableArrayRef<Expr *>( + static_cast<T *>(this)->template getTrailingObjects<Expr *>() + + OMPVarListClause<T>::varlist_size(), + OMPVarListClause<T>::varlist_size()); + } + + /// Get the user-defined mappers references that are in the trailing objects + /// of the class. + ArrayRef<Expr *> getUDMapperRefs() const { + return llvm::makeArrayRef<Expr *>( + static_cast<T *>(this)->template getTrailingObjects<Expr *>() + + OMPVarListClause<T>::varlist_size(), + OMPVarListClause<T>::varlist_size()); + } + + /// Set the user-defined mappers that are in the trailing objects of the + /// class. + void setUDMapperRefs(ArrayRef<Expr *> DMDs) { + assert(DMDs.size() == OMPVarListClause<T>::varlist_size() && + "Unexpected number of user-defined mappers."); + std::copy(DMDs.begin(), DMDs.end(), getUDMapperRefs().begin()); + } + public: /// Return the number of unique base declarations in this clause. unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; } @@ -3827,6 +4521,14 @@ public: /// clause. unsigned getTotalComponentsNum() const { return NumComponents; } + /// Gets the nested name specifier for associated user-defined mapper. + NestedNameSpecifierLoc getMapperQualifierLoc() const { + return MapperQualifierLoc; + } + + /// Gets the name info for associated user-defined mapper. + const DeclarationNameInfo &getMapperIdInfo() const { return MapperIdInfo; } + /// Iterator that browse the components by lists. It also allows /// browsing components of a single declaration. class const_component_lists_iterator @@ -4030,6 +4732,27 @@ public: auto A = getComponentsRef(); return const_all_components_range(A.begin(), A.end()); } + + using mapperlist_iterator = MutableArrayRef<Expr *>::iterator; + using mapperlist_const_iterator = ArrayRef<const Expr *>::iterator; + using mapperlist_range = llvm::iterator_range<mapperlist_iterator>; + using mapperlist_const_range = + llvm::iterator_range<mapperlist_const_iterator>; + + mapperlist_iterator mapperlist_begin() { return getUDMapperRefs().begin(); } + mapperlist_iterator mapperlist_end() { return getUDMapperRefs().end(); } + mapperlist_const_iterator mapperlist_begin() const { + return getUDMapperRefs().begin(); + } + mapperlist_const_iterator mapperlist_end() const { + return getUDMapperRefs().end(); + } + mapperlist_range mapperlists() { + return mapperlist_range(mapperlist_begin(), mapperlist_end()); + } + mapperlist_const_range mapperlists() const { + return mapperlist_const_range(mapperlist_begin(), mapperlist_end()); + } }; /// This represents clause 'map' in the '#pragma omp ...' @@ -4052,7 +4775,9 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>, /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. size_t numTrailingObjects(OverloadToken<Expr *>) const { - return varlist_size(); + // There are varlist_size() of expressions, and varlist_size() of + // user-defined mappers. + return 2 * varlist_size(); } size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { return getUniqueDeclarationsNum(); @@ -4069,9 +4794,9 @@ public: private: /// Map-type-modifiers for the 'map' clause. OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = { - OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown - }; - + OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, + OMPC_MAP_MODIFIER_unknown}; + /// Location of map-type-modifiers for the 'map' clause. SourceLocation MapTypeModifiersLoc[NumberOfModifiers]; @@ -4093,50 +4818,49 @@ private: /// /// \param MapModifiers Map-type-modifiers. /// \param MapModifiersLoc Locations of map-type-modifiers. + /// \param MapperQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperIdInfo The identifier of associated user-defined mapper. /// \param MapType Map type. /// \param MapTypeIsImplicit Map type is inferred implicitly. /// \param MapLoc Location of the map type. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. explicit OMPMapClause(ArrayRef<OpenMPMapModifierKind> MapModifiers, ArrayRef<SourceLocation> MapModifiersLoc, + NestedNameSpecifierLoc MapperQualifierLoc, + DeclarationNameInfo MapperIdInfo, OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, - SourceLocation MapLoc, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, - unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc, - NumVars, NumUniqueDeclarations, - NumComponentLists, NumComponents), - MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), - MapLoc(MapLoc) { - assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() - && "Unexpected number of map type modifiers."); - llvm::copy(MapModifiers, std::begin(MapTypeModifiers)); - - assert(llvm::array_lengthof(MapTypeModifiersLoc) == - MapModifiersLoc.size() && - "Unexpected number of map type modifier locations."); - llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc)); + SourceLocation MapLoc, const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc, + &MapperIdInfo), + MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { + assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() && + "Unexpected number of map type modifiers."); + llvm::copy(MapModifiers, std::begin(MapTypeModifiers)); + + assert(llvm::array_lengthof(MapTypeModifiersLoc) == + MapModifiersLoc.size() && + "Unexpected number of map type modifier locations."); + llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc)); } /// Build an empty clause. /// - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. - explicit OMPMapClause(unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause( - OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(), - NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_map, OMPVarListLocTy(), Sizes) {} /// Set map-type-modifier for the clause. /// @@ -4175,41 +4899,44 @@ public: /// Creates clause with a list of variables \a VL. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \param Vars The original expression used in the clause. /// \param Declarations Declarations used in the clause. /// \param ComponentLists Component lists used in the clause. + /// \param UDMapperRefs References to user-defined mappers associated with + /// expressions used in the clause. /// \param MapModifiers Map-type-modifiers. /// \param MapModifiersLoc Location of map-type-modifiers. + /// \param UDMQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperId The identifier of associated user-defined mapper. /// \param Type Map type. /// \param TypeIsImplicit Map type is inferred implicitly. /// \param TypeLoc Location of the map type. - static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, - ArrayRef<Expr *> Vars, - ArrayRef<ValueDecl *> Declarations, - MappableExprComponentListsRef ComponentLists, - ArrayRef<OpenMPMapModifierKind> MapModifiers, - ArrayRef<SourceLocation> MapModifiersLoc, - OpenMPMapClauseKind Type, bool TypeIsImplicit, - SourceLocation TypeLoc); + static OMPMapClause * + Create(const ASTContext &C, const OMPVarListLocTy &Locs, + ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists, + ArrayRef<Expr *> UDMapperRefs, + ArrayRef<OpenMPMapModifierKind> MapModifiers, + ArrayRef<SourceLocation> MapModifiersLoc, + NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, + OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc); /// Creates an empty clause with the place for \a NumVars original /// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists /// lists, and \a NumComponents expression components. /// /// \param C AST context. - /// \param NumVars Number of expressions listed in the clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of unique base declarations in this - /// clause. - /// \param NumComponents Total number of expression components in the clause. - static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPMapClause *CreateEmpty(const ASTContext &C, + const OMPMappableExprListSizeTy &Sizes); /// Fetches mapping kind for the clause. OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; } @@ -4233,7 +4960,7 @@ public: /// Fetches the map-type-modifier location at 'Cnt' index of array of /// modifiers' locations. /// - /// \param Cnt index for map-type-modifier location. + /// \param Cnt index for map-type-modifier location. SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY { assert(Cnt < NumberOfModifiers && "Requested modifier location exceeds total number of modifiers."); @@ -4244,7 +4971,7 @@ public: ArrayRef<OpenMPMapModifierKind> getMapTypeModifiers() const LLVM_READONLY { return llvm::makeArrayRef(MapTypeModifiers); } - + /// Fetches ArrayRef of location of map-type-modifiers. ArrayRef<SourceLocation> getMapTypeModifiersLoc() const LLVM_READONLY { return llvm::makeArrayRef(MapTypeModifiersLoc); @@ -4262,6 +4989,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPMapClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_map; } @@ -4326,6 +5065,17 @@ public: child_range children() { return child_range(&NumTeams, &NumTeams + 1); } + const_child_range children() const { + return const_child_range(&NumTeams, &NumTeams + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_num_teams; } @@ -4391,6 +5141,17 @@ public: child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); } + const_child_range children() const { + return const_child_range(&ThreadLimit, &ThreadLimit + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_thread_limit; } @@ -4448,6 +5209,17 @@ public: child_range children() { return child_range(&Priority, &Priority + 1); } + const_child_range children() const { + return const_child_range(&Priority, &Priority + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_priority; } @@ -4499,6 +5271,17 @@ public: child_range children() { return child_range(&Grainsize, &Grainsize + 1); } + const_child_range children() const { + return const_child_range(&Grainsize, &Grainsize + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_grainsize; } @@ -4527,6 +5310,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_nogroup; } @@ -4578,6 +5372,17 @@ public: child_range children() { return child_range(&NumTasks, &NumTasks + 1); } + const_child_range children() const { + return const_child_range(&NumTasks, &NumTasks + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_num_tasks; } @@ -4628,6 +5433,17 @@ public: child_range children() { return child_range(&Hint, &Hint + 1); } + const_child_range children() const { + return const_child_range(&Hint, &Hint + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_hint; } @@ -4735,6 +5551,18 @@ public: reinterpret_cast<Stmt **>(&ChunkSize) + 1); } + const_child_range children() const { + auto Children = const_cast<OMPDistScheduleClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_dist_schedule; } @@ -4836,6 +5664,17 @@ public: return child_range(child_iterator(), child_iterator()); } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_defaultmap; } @@ -4860,38 +5699,40 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>, /// Build clause with number of variables \a NumVars. /// - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. - explicit OMPToClause(SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause(OMPC_to, StartLoc, LParenLoc, EndLoc, NumVars, - NumUniqueDeclarations, NumComponentLists, - NumComponents) {} + /// \param MapperQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperIdInfo The identifier of associated user-defined mapper. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPToClause(NestedNameSpecifierLoc MapperQualifierLoc, + DeclarationNameInfo MapperIdInfo, + const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc, + &MapperIdInfo) {} /// Build an empty clause. /// - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. - explicit OMPToClause(unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause( - OMPC_to, SourceLocation(), SourceLocation(), SourceLocation(), - NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_to, OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. size_t numTrailingObjects(OverloadToken<Expr *>) const { - return varlist_size(); + // There are varlist_size() of expressions, and varlist_size() of + // user-defined mappers. + return 2 * varlist_size(); } size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { return getUniqueDeclarationsNum(); @@ -4904,36 +5745,53 @@ public: /// Creates clause with a list of variables \a Vars. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \param Vars The original expression used in the clause. /// \param Declarations Declarations used in the clause. /// \param ComponentLists Component lists used in the clause. - static OMPToClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, + /// \param UDMapperRefs References to user-defined mappers associated with + /// expressions used in the clause. + /// \param UDMQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperId The identifier of associated user-defined mapper. + static OMPToClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, - MappableExprComponentListsRef ComponentLists); + MappableExprComponentListsRef ComponentLists, + ArrayRef<Expr *> UDMapperRefs, + NestedNameSpecifierLoc UDMQualifierLoc, + DeclarationNameInfo MapperId); /// Creates an empty clause with the place for \a NumVars variables. /// /// \param C AST context. - /// \param NumVars Number of expressions listed in the clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of unique base declarations in this - /// clause. - /// \param NumComponents Total number of expression components in the clause. - static OMPToClause *CreateEmpty(const ASTContext &C, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPToClause *CreateEmpty(const ASTContext &C, + const OMPMappableExprListSizeTy &Sizes); child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPToClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_to; } @@ -4959,38 +5817,40 @@ class OMPFromClause final /// Build clause with number of variables \a NumVars. /// - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. - explicit OMPFromClause(SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause(OMPC_from, StartLoc, LParenLoc, EndLoc, - NumVars, NumUniqueDeclarations, - NumComponentLists, NumComponents) {} + /// \param MapperQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperIdInfo The identifier of associated user-defined mapper. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPFromClause(NestedNameSpecifierLoc MapperQualifierLoc, + DeclarationNameInfo MapperIdInfo, + const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc, + &MapperIdInfo) {} /// Build an empty clause. /// - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. - explicit OMPFromClause(unsigned NumVars, unsigned NumUniqueDeclarations, - unsigned NumComponentLists, unsigned NumComponents) - : OMPMappableExprListClause( - OMPC_from, SourceLocation(), SourceLocation(), SourceLocation(), - NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_from, OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. size_t numTrailingObjects(OverloadToken<Expr *>) const { - return varlist_size(); + // There are varlist_size() of expressions, and varlist_size() of + // user-defined mappers. + return 2 * varlist_size(); } size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { return getUniqueDeclarationsNum(); @@ -5003,36 +5863,53 @@ public: /// Creates clause with a list of variables \a Vars. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \param Vars The original expression used in the clause. /// \param Declarations Declarations used in the clause. /// \param ComponentLists Component lists used in the clause. - static OMPFromClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, + /// \param UDMapperRefs References to user-defined mappers associated with + /// expressions used in the clause. + /// \param UDMQualifierLoc C++ nested name specifier for the associated + /// user-defined mapper. + /// \param MapperId The identifier of associated user-defined mapper. + static OMPFromClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, - MappableExprComponentListsRef ComponentLists); + MappableExprComponentListsRef ComponentLists, + ArrayRef<Expr *> UDMapperRefs, + NestedNameSpecifierLoc UDMQualifierLoc, + DeclarationNameInfo MapperId); /// Creates an empty clause with the place for \a NumVars variables. /// /// \param C AST context. - /// \param NumVars Number of expressions listed in the clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of unique base declarations in this - /// clause. - /// \param NumComponents Total number of expression components in the clause. - static OMPFromClause *CreateEmpty(const ASTContext &C, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPFromClause *CreateEmpty(const ASTContext &C, + const OMPMappableExprListSizeTy &Sizes); child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPFromClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_from; } @@ -5058,38 +5935,28 @@ class OMPUseDevicePtrClause final /// Build clause with number of variables \a NumVars. /// - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. - explicit OMPUseDevicePtrClause(SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents) - : OMPMappableExprListClause(OMPC_use_device_ptr, StartLoc, LParenLoc, - EndLoc, NumVars, NumUniqueDeclarations, - NumComponentLists, NumComponents) {} + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {} /// Build an empty clause. /// - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. - explicit OMPUseDevicePtrClause(unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents) - : OMPMappableExprListClause(OMPC_use_device_ptr, SourceLocation(), - SourceLocation(), SourceLocation(), NumVars, - NumUniqueDeclarations, NumComponentLists, - NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -5135,34 +6002,30 @@ public: /// Creates clause with a list of variables \a Vars. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \param Vars The original expression used in the clause. /// \param PrivateVars Expressions referring to private copies. /// \param Inits Expressions referring to private copy initializers. /// \param Declarations Declarations used in the clause. /// \param ComponentLists Component lists used in the clause. static OMPUseDevicePtrClause * - Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef<Expr *> Vars, - ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits, - ArrayRef<ValueDecl *> Declarations, + Create(const ASTContext &C, const OMPVarListLocTy &Locs, + ArrayRef<Expr *> Vars, ArrayRef<Expr *> PrivateVars, + ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists); /// Creates an empty clause with the place for \a NumVars variables. /// /// \param C AST context. - /// \param NumVars Number of expressions listed in the clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of unique base declarations in this - /// clause. - /// \param NumComponents Total number of expression components in the clause. - static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C, - unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPUseDevicePtrClause * + CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); using private_copies_iterator = MutableArrayRef<Expr *>::iterator; using private_copies_const_iterator = ArrayRef<const Expr *>::iterator; @@ -5198,6 +6061,18 @@ public: reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPUseDevicePtrClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_use_device_ptr; } @@ -5223,38 +6098,28 @@ class OMPIsDevicePtrClause final /// Build clause with number of variables \a NumVars. /// - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. - explicit OMPIsDevicePtrClause(SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, - unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents) - : OMPMappableExprListClause(OMPC_is_device_ptr, StartLoc, LParenLoc, - EndLoc, NumVars, NumUniqueDeclarations, - NumComponentLists, NumComponents) {} + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {} /// Build an empty clause. /// - /// \param NumVars Number of expressions listed in this clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of component lists in this clause. - /// \param NumComponents Total number of expression components in the clause. - explicit OMPIsDevicePtrClause(unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents) - : OMPMappableExprListClause(OMPC_is_device_ptr, SourceLocation(), - SourceLocation(), SourceLocation(), NumVars, - NumUniqueDeclarations, NumComponentLists, - NumComponents) {} + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -5272,37 +6137,45 @@ public: /// Creates clause with a list of variables \a Vars. /// /// \param C AST context. - /// \param StartLoc Starting location of the clause. - /// \param EndLoc Ending location of the clause. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. /// \param Vars The original expression used in the clause. /// \param Declarations Declarations used in the clause. /// \param ComponentLists Component lists used in the clause. static OMPIsDevicePtrClause * - Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef<Expr *> Vars, - ArrayRef<ValueDecl *> Declarations, + Create(const ASTContext &C, const OMPVarListLocTy &Locs, + ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists); /// Creates an empty clause with the place for \a NumVars variables. /// /// \param C AST context. - /// \param NumVars Number of expressions listed in the clause. - /// \param NumUniqueDeclarations Number of unique base declarations in this - /// clause. - /// \param NumComponentLists Number of unique base declarations in this - /// clause. - /// \param NumComponents Total number of expression components in the clause. - static OMPIsDevicePtrClause *CreateEmpty(const ASTContext &C, - unsigned NumVars, - unsigned NumUniqueDeclarations, - unsigned NumComponentLists, - unsigned NumComponents); + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPIsDevicePtrClause * + CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), reinterpret_cast<Stmt **>(varlist_end())); } + const_child_range children() const { + auto Children = const_cast<OMPIsDevicePtrClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_is_device_ptr; } diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def index cd19091e31d6..9af92c1ae7ff 100644 --- a/include/clang/AST/OperationKinds.def +++ b/include/clang/AST/OperationKinds.def @@ -1,9 +1,8 @@ //===--- OperationKinds.def - Operations Database ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -67,6 +66,10 @@ CAST_OPERATION(BitCast) /// bool b; reinterpret_cast<char&>(b) = 'a'; CAST_OPERATION(LValueBitCast) +/// CK_LValueToRValueBitCast - A conversion that causes us to reinterpret an +/// lvalue as an rvalue of a different type. Created by __builtin_bit_cast. +CAST_OPERATION(LValueToRValueBitCast) + /// CK_LValueToRValue - A conversion which causes the extraction of /// an r-value from the operand gl-value. The result of an r-value /// conversion is always unqualified. @@ -201,6 +204,14 @@ CAST_OPERATION(IntegralToFloating) /// (_Accum) 0.5r CAST_OPERATION(FixedPointCast) +/// CK_FixedPointToIntegral - Fixed point to integral. +/// (int) 2.0k +CAST_OPERATION(FixedPointToIntegral) + +/// CK_IntegralToFixedPoint - Integral to a fixed point. +/// (_Accum) 2 +CAST_OPERATION(IntegralToFixedPoint) + /// CK_FixedPointToBoolean - Fixed point to boolean. /// (bool) 0.5r CAST_OPERATION(FixedPointToBoolean) diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h index ac512d721e34..679e0fdd4056 100644 --- a/include/clang/AST/OperationKinds.h +++ b/include/clang/AST/OperationKinds.h @@ -1,9 +1,8 @@ //===- OperationKinds.h - Operation enums -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h index c1c76ceaaf69..1e65d7efd272 100644 --- a/include/clang/AST/ParentMap.h +++ b/include/clang/AST/ParentMap.h @@ -1,9 +1,8 @@ //===--- ParentMap.h - Mappings from Stmts to their Parents -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/PrettyDeclStackTrace.h b/include/clang/AST/PrettyDeclStackTrace.h index 8eb519eae26d..899bbcb3be45 100644 --- a/include/clang/AST/PrettyDeclStackTrace.h +++ b/include/clang/AST/PrettyDeclStackTrace.h @@ -1,9 +1,8 @@ //===- PrettyDeclStackTrace.h - Stack trace for decl processing -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 3c877f5ea19c..0cd62ba373dc 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -1,9 +1,8 @@ //===--- PrettyPrinter.h - Classes for aiding with AST printing -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/QualTypeNames.h b/include/clang/AST/QualTypeNames.h index 422ed9e4c8fc..8313e0441be5 100644 --- a/include/clang/AST/QualTypeNames.h +++ b/include/clang/AST/QualTypeNames.h @@ -1,7 +1,8 @@ //===--- QualTypeNames.h - Generate Complete QualType Names ----*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // ===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h index d17c9df67e41..5dc8694e77e9 100644 --- a/include/clang/AST/RawCommentList.h +++ b/include/clang/AST/RawCommentList.h @@ -1,9 +1,8 @@ //===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index a546c200ffe0..b259791af509 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -1,9 +1,8 @@ //===- RecordLayout.h - Layout information for a struct/union ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 44aba6355758..698fba2f4ed1 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1,9 +1,8 @@ //===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -1066,6 +1065,9 @@ DEF_TRAVERSE_TYPE(AttributedType, DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); }) +DEF_TRAVERSE_TYPE(MacroQualifiedType, + { TRY_TO(TraverseType(T->getUnderlyingType())); }) + DEF_TRAVERSE_TYPE(ElaboratedType, { if (T->getQualifier()) { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); @@ -1309,6 +1311,9 @@ DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {}) DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) +DEF_TRAVERSE_TYPELOC(MacroQualifiedType, + { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) + DEF_TRAVERSE_TYPELOC(AttributedType, { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); }) @@ -1459,9 +1464,9 @@ DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, { TRY_TO(TraverseDecl(D->getSpecialization())); if (D->hasExplicitTemplateArgs()) { - const TemplateArgumentListInfo &args = D->templateArgs(); - TRY_TO(TraverseTemplateArgumentLocsHelper(args.getArgumentArray(), - args.size())); + TRY_TO(TraverseTemplateArgumentLocsHelper( + D->getTemplateArgsAsWritten()->getTemplateArgs(), + D->getTemplateArgsAsWritten()->NumTemplateArgs)); } }) @@ -1590,7 +1595,7 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { TRY_TO(TraverseStmt(I)); } }) - + DEF_TRAVERSE_DECL(OMPRequiresDecl, { for (auto *C : D->clauselists()) { TRY_TO(TraverseOMPClause(C)); @@ -1605,8 +1610,22 @@ DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, { return true; }) +DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, { + for (auto *C : D->clauselists()) + TRY_TO(TraverseOMPClause(C)); + TRY_TO(TraverseType(D->getType())); + return true; +}) + DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); }) +DEF_TRAVERSE_DECL(OMPAllocateDecl, { + for (auto *I : D->varlists()) + TRY_TO(TraverseStmt(I)); + for (auto *C : D->clauselists()) + TRY_TO(TraverseOMPClause(C)); +}) + // A helper method for TemplateDecl's children. template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper( @@ -1781,6 +1800,11 @@ DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, { TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); }) +DEF_TRAVERSE_DECL(ConceptDecl, { + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); + TRY_TO(TraverseStmt(D->getConstraintExpr())); +}) + DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, { // A dependent using declaration which was marked with 'typename'. // template<class T> class A : public B<T> { using typename B<T>::foo; }; @@ -2263,6 +2287,10 @@ DEF_TRAVERSE_STMT(CXXStaticCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) +DEF_TRAVERSE_STMT(BuiltinBitCastExpr, { + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); +}) + template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr( InitListExpr *S, DataRecursionQueue *Queue) { @@ -2301,10 +2329,10 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr( // generic associations). DEF_TRAVERSE_STMT(GenericSelectionExpr, { TRY_TO(TraverseStmt(S->getControllingExpr())); - for (unsigned i = 0; i != S->getNumAssocs(); ++i) { - if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i)) - TRY_TO(TraverseTypeLoc(TS->getTypeLoc())); - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAssocExpr(i)); + for (const GenericSelectionExpr::Association &Assoc : S->associations()) { + if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo()) + TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr()); } ShouldVisitChildren = false; }) @@ -2410,6 +2438,10 @@ DEF_TRAVERSE_STMT(LambdaExpr, { TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>(); + for (Decl *D : S->getExplicitTemplateParameters()) { + // Visit explicit template parameters. + TRY_TO(TraverseDecl(D)); + } if (S->hasExplicitParameters()) { // Visit parameters. for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) @@ -2527,6 +2559,8 @@ DEF_TRAVERSE_STMT(PredefinedExpr, {}) DEF_TRAVERSE_STMT(ShuffleVectorExpr, {}) DEF_TRAVERSE_STMT(ConvertVectorExpr, {}) DEF_TRAVERSE_STMT(StmtExpr, {}) +DEF_TRAVERSE_STMT(SourceLocExpr, {}) + DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); if (S->hasExplicitTemplateArgs()) { @@ -2814,6 +2848,20 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate( } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPAllocatorClause( + OMPAllocatorClause *C) { + TRY_TO(TraverseStmt(C->getAllocator())); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPAllocateClause(OMPAllocateClause *C) { + TRY_TO(TraverseStmt(C->getAllocator())); + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) { TRY_TO(VisitOMPClauseWithPreInit(C)); TRY_TO(TraverseStmt(C->getCondition())); diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h index c2bd6e6fd136..0975773dd2cb 100644 --- a/include/clang/AST/Redeclarable.h +++ b/include/clang/AST/Redeclarable.h @@ -1,9 +1,8 @@ //===- Redeclarable.h - Base for Decls that can be redeclared --*- C++ -*-====// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -362,6 +361,13 @@ public: decl_type &operator*() { return *Ptr; } const decl_type &operator*() const { return *Ptr; } + friend bool operator==(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS) { + return LHS.Ptr == RHS.Ptr; + } + friend bool operator!=(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS) { + return LHS.Ptr != RHS.Ptr; + } + private: friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>; diff --git a/include/clang/AST/SelectorLocationsKind.h b/include/clang/AST/SelectorLocationsKind.h index 6ca2dba47558..6e9923de6742 100644 --- a/include/clang/AST/SelectorLocationsKind.h +++ b/include/clang/AST/SelectorLocationsKind.h @@ -1,9 +1,8 @@ //===--- SelectorLocationsKind.h - Kind of selector locations ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index ff5baa21adff..403b88ac3a3c 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -1,9 +1,8 @@ //===- Stmt.h - Classes for representing statements -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -47,6 +46,7 @@ class Attr; class CapturedDecl; class Decl; class Expr; +class AddrLabelExpr; class LabelDecl; class ODRHash; class PrinterHelper; @@ -92,12 +92,20 @@ protected: //===--- Statement bitfields classes ---===// class StmtBitfields { + friend class ASTStmtReader; + friend class ASTStmtWriter; friend class Stmt; /// The statement class. unsigned sClass : 8; + + /// This bit is set only for the Stmts that are the structured-block of + /// OpenMP executable directives. Directives that have a structured block + /// are called "non-standalone" directives. + /// I.e. those returned by OMPExecutableDirective::getStructuredBlock(). + unsigned IsOMPStructuredBlock : 1; }; - enum { NumStmtBits = 8 }; + enum { NumStmtBits = 9 }; class NullStmtBitfields { friend class ASTStmtReader; @@ -314,6 +322,33 @@ protected: }; enum { NumExprBits = NumStmtBits + 9 }; + class ConstantExprBitfields { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend class ConstantExpr; + + unsigned : NumExprBits; + + /// The kind of result that is trail-allocated. + unsigned ResultKind : 2; + + /// Kind of Result as defined by APValue::Kind + unsigned APValueKind : 4; + + /// When ResultKind == RSK_Int64. whether the trail-allocated integer is + /// signed. + unsigned IsUnsigned : 1; + + /// When ResultKind == RSK_Int64. the BitWidth of the trail-allocated + /// integer. 7 bits because it is the minimal number of bit to represent a + /// value from 0 to 64 (the size of the trail-allocated number). + unsigned BitWidth : 7; + + /// When ResultKind == RSK_APValue. Wether the ASTContext will cleanup the + /// destructor on the trail-allocated APValue. + unsigned HasCleanup : 1; + }; + class PredefinedExprBitfields { friend class ASTStmtReader; friend class PredefinedExpr; @@ -343,19 +378,12 @@ protected: unsigned HasFoundDecl : 1; unsigned HadMultipleCandidates : 1; unsigned RefersToEnclosingVariableOrCapture : 1; + unsigned NonOdrUseReason : 2; /// The location of the declaration name itself. SourceLocation Loc; }; - enum APFloatSemantics { - IEEEhalf, - IEEEsingle, - IEEEdouble, - x87DoubleExtended, - IEEEquad, - PPCDoubleDouble - }; class FloatingLiteralBitfields { friend class FloatingLiteral; @@ -445,6 +473,7 @@ protected: enum { NumCallExprBits = 32 }; class MemberExprBitfields { + friend class ASTStmtReader; friend class MemberExpr; unsigned : NumExprBits; @@ -469,6 +498,11 @@ protected: /// was resolved from an overloaded set having size greater than 1. unsigned HadMultipleCandidates : 1; + /// Value of type NonOdrUseReason indicating why this MemberExpr does + /// not constitute an odr-use of the named declaration. Meaningful only + /// when naming a static member. + unsigned NonOdrUseReason : 2; + /// This is the location of the -> or . in the expression. SourceLocation OperatorLoc; }; @@ -521,6 +555,16 @@ protected: unsigned NumExprs; }; + class GenericSelectionExprBitfields { + friend class ASTStmtReader; + friend class GenericSelectionExpr; + + unsigned : NumExprBits; + + /// The location of the "_Generic". + SourceLocation GenericLoc; + }; + class PseudoObjectExprBitfields { friend class ASTStmtReader; // deserialization friend class PseudoObjectExpr; @@ -533,6 +577,17 @@ protected: unsigned ResultIndex : 32 - 8 - NumExprBits; }; + class SourceLocExprBitfields { + friend class ASTStmtReader; + friend class SourceLocExpr; + + unsigned : NumExprBits; + + /// The kind of source location builtin represented by the SourceLocExpr. + /// Ex. __builtin_LINE, __builtin_FUNCTION, ect. + unsigned Kind : 2; + }; + //===--- C++ Expression bitfields classes ---===// class CXXOperatorCallExprBitfields { @@ -902,6 +957,7 @@ protected: // Expressions ExprBitfields ExprBits; + ConstantExprBitfields ConstantExprBits; PredefinedExprBitfields PredefinedExprBits; DeclRefExprBitfields DeclRefExprBits; FloatingLiteralBitfields FloatingLiteralBits; @@ -916,7 +972,9 @@ protected: BinaryOperatorBitfields BinaryOperatorBits; InitListExprBitfields InitListExprBits; ParenListExprBitfields ParenListExprBits; + GenericSelectionExprBitfields GenericSelectionExprBits; PseudoObjectExprBitfields PseudoObjectExprBits; + SourceLocExprBitfields SourceLocExprBits; // C++ Expressions CXXOperatorCallExprBitfields CXXOperatorCallExprBits; @@ -976,38 +1034,31 @@ public: struct EmptyShell {}; protected: - /// Iterator for iterating over Stmt * arrays that contain only Expr * + /// Iterator for iterating over Stmt * arrays that contain only T *. /// /// This is needed because AST nodes use Stmt* arrays to store /// references to children (to be compatible with StmtIterator). - struct ExprIterator - : llvm::iterator_adaptor_base<ExprIterator, Stmt **, - std::random_access_iterator_tag, Expr *> { - ExprIterator() : iterator_adaptor_base(nullptr) {} - ExprIterator(Stmt **I) : iterator_adaptor_base(I) {} - - reference operator*() const { - assert((*I)->getStmtClass() >= firstExprConstant && - (*I)->getStmtClass() <= lastExprConstant); - return *reinterpret_cast<Expr **>(I); - } - }; + template<typename T, typename TPtr = T *, typename StmtPtr = Stmt *> + struct CastIterator + : llvm::iterator_adaptor_base<CastIterator<T, TPtr, StmtPtr>, StmtPtr *, + std::random_access_iterator_tag, TPtr> { + using Base = typename CastIterator::iterator_adaptor_base; - /// Const iterator for iterating over Stmt * arrays that contain only Expr * - struct ConstExprIterator - : llvm::iterator_adaptor_base<ConstExprIterator, const Stmt *const *, - std::random_access_iterator_tag, - const Expr *const> { - ConstExprIterator() : iterator_adaptor_base(nullptr) {} - ConstExprIterator(const Stmt *const *I) : iterator_adaptor_base(I) {} + CastIterator() : Base(nullptr) {} + CastIterator(StmtPtr *I) : Base(I) {} - reference operator*() const { - assert((*I)->getStmtClass() >= firstExprConstant && - (*I)->getStmtClass() <= lastExprConstant); - return *reinterpret_cast<const Expr *const *>(I); + typename Base::value_type operator*() const { + return cast_or_null<T>(*this->I); } }; + /// Const iterator for iterating over Stmt * arrays that contain only T *. + template <typename T> + using ConstCastIterator = CastIterator<T, const T *const, const Stmt *const>; + + using ExprIterator = CastIterator<Expr>; + using ConstExprIterator = ConstCastIterator<Expr>; + private: /// Whether statistic collection is enabled. static bool StatisticsEnabled; @@ -1017,12 +1068,19 @@ protected: explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {} public: + Stmt() = delete; + Stmt(const Stmt &) = delete; + Stmt(Stmt &&) = delete; + Stmt &operator=(const Stmt &) = delete; + Stmt &operator=(Stmt &&) = delete; + Stmt(StmtClass SC) { static_assert(sizeof(*this) <= 8, "changing bitfields changed sizeof(Stmt)"); static_assert(sizeof(*this) % alignof(void *) == 0, "Insufficient alignment!"); StmtBits.sClass = SC; + StmtBits.IsOMPStructuredBlock = false; if (StatisticsEnabled) Stmt::addStmtClass(SC); } @@ -1032,6 +1090,11 @@ public: const char *getStmtClassName() const; + bool isOMPStructuredBlock() const { return StmtBits.IsOMPStructuredBlock; } + void setIsOMPStructuredBlock(bool IsOMPStructuredBlock) { + StmtBits.IsOMPStructuredBlock = IsOMPStructuredBlock; + } + /// SourceLocation tokens are not useful in isolation - they are low level /// value objects created/interpreted by SourceManager. We assume AST /// clients will have a pointer to the respective SourceManager. @@ -1065,17 +1128,14 @@ public: StringRef NewlineSymbol = "\n", const ASTContext *Context = nullptr) const; + /// Pretty-prints in JSON format. + void printJson(raw_ostream &Out, PrinterHelper *Helper, + const PrintingPolicy &Policy, bool AddQuotes) const; + /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only /// works on systems with GraphViz (Mac OS X) or dot+gv installed. void viewAST() const; - /// Skip past any implicit AST nodes which might surround this - /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes. - Stmt *IgnoreImplicit(); - const Stmt *IgnoreImplicit() const { - return const_cast<Stmt *>(this)->IgnoreImplicit(); - } - /// Skip no-op (attributed, compound) container stmts and skip captured /// stmt at the top, if \a IgnoreCaptured is true. Stmt *IgnoreContainers(bool IgnoreCaptured = false); @@ -1178,6 +1238,11 @@ public: child_iterator(DG.end(), DG.end())); } + const_child_range children() const { + auto Children = const_cast<DeclStmt *>(this)->children(); + return const_child_range(Children); + } + using decl_iterator = DeclGroupRef::iterator; using const_decl_iterator = DeclGroupRef::const_iterator; using decl_range = llvm::iterator_range<decl_iterator>; @@ -1235,6 +1300,10 @@ public: 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()); + } }; /// CompoundStmt - This represents a group of statements like { stmt stmt }. @@ -1280,11 +1349,6 @@ public: return !body_empty() ? body_begin()[size() - 1] : nullptr; } - void setLastStmt(Stmt *S) { - assert(!body_empty() && "setLastStmt"); - body_begin()[size() - 1] = S; - } - using const_body_iterator = Stmt *const *; using body_const_range = llvm::iterator_range<const_body_iterator>; @@ -1327,6 +1391,26 @@ public: return const_reverse_body_iterator(body_begin()); } + // Get the Stmt that StmtExpr would consider to be the result of this + // compound statement. This is used by StmtExpr to properly emulate the GCC + // compound expression extension, which ignores trailing NullStmts when + // getting the result of the expression. + // i.e. ({ 5;;; }) + // ^^ ignored + // If we don't find something that isn't a NullStmt, just return the last + // Stmt. + Stmt *getStmtExprResult() { + for (auto *B : llvm::reverse(body())) { + if (!isa<NullStmt>(B)) + return B; + } + return body_back(); + } + + const Stmt *getStmtExprResult() const { + return const_cast<CompoundStmt *>(this)->getStmtExprResult(); + } + SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; } SourceLocation getEndLoc() const { return RBraceLoc; } @@ -1539,6 +1623,12 @@ public: getTrailingObjects<Stmt *>() + numTrailingObjects(OverloadToken<Stmt *>())); } + + const_child_range children() const { + return const_child_range(getTrailingObjects<Stmt *>(), + getTrailingObjects<Stmt *>() + + numTrailingObjects(OverloadToken<Stmt *>())); + } }; class DefaultStmt : public SwitchCase { @@ -1570,6 +1660,10 @@ public: // Iterators child_range children() { return child_range(&SubStmt, &SubStmt + 1); } + + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } }; SourceLocation SwitchCase::getEndLoc() const { @@ -1588,21 +1682,44 @@ Stmt *SwitchCase::getSubStmt() { llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!"); } +/// Represents a statement that could possibly have a value and type. This +/// covers expression-statements, as well as labels and attributed statements. +/// +/// Value statements have a special meaning when they are the last non-null +/// statement in a GNU statement expression, where they determine the value +/// of the statement expression. +class ValueStmt : public Stmt { +protected: + using Stmt::Stmt; + +public: + const Expr *getExprStmt() const; + Expr *getExprStmt() { + const ValueStmt *ConstThis = this; + return const_cast<Expr*>(ConstThis->getExprStmt()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() >= firstValueStmtConstant && + T->getStmtClass() <= lastValueStmtConstant; + } +}; + /// LabelStmt - Represents a label, which has a substatement. For example: /// foo: return; -class LabelStmt : public Stmt { +class LabelStmt : public ValueStmt { LabelDecl *TheDecl; Stmt *SubStmt; public: /// Build a label statement. LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt) - : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) { + : ValueStmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) { setIdentLoc(IL); } /// Build an empty label statement. - explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) {} + explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {} SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; } void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; } @@ -1621,6 +1738,10 @@ public: child_range children() { return child_range(&SubStmt, &SubStmt + 1); } + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == LabelStmtClass; } @@ -1631,7 +1752,7 @@ public: /// Represents an attribute applied to a statement. For example: /// [[omp::for(...)]] for (...) { ... } class AttributedStmt final - : public Stmt, + : public ValueStmt, private llvm::TrailingObjects<AttributedStmt, const Attr *> { friend class ASTStmtReader; friend TrailingObjects; @@ -1640,14 +1761,14 @@ class AttributedStmt final AttributedStmt(SourceLocation Loc, ArrayRef<const Attr *> Attrs, Stmt *SubStmt) - : Stmt(AttributedStmtClass), SubStmt(SubStmt) { + : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) { AttributedStmtBits.NumAttrs = Attrs.size(); AttributedStmtBits.AttrLoc = Loc; std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr()); } explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs) - : Stmt(AttributedStmtClass, Empty) { + : ValueStmt(AttributedStmtClass, Empty) { AttributedStmtBits.NumAttrs = NumAttrs; AttributedStmtBits.AttrLoc = SourceLocation{}; std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr); @@ -1678,6 +1799,10 @@ public: child_range children() { return child_range(&SubStmt, &SubStmt + 1); } + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == AttributedStmtClass; } @@ -1877,6 +2002,12 @@ public: numTrailingObjects(OverloadToken<Stmt *>())); } + const_child_range children() const { + return const_child_range(getTrailingObjects<Stmt *>(), + getTrailingObjects<Stmt *>() + + numTrailingObjects(OverloadToken<Stmt *>())); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == IfStmtClass; } @@ -2054,6 +2185,12 @@ public: numTrailingObjects(OverloadToken<Stmt *>())); } + const_child_range children() const { + return const_child_range(getTrailingObjects<Stmt *>(), + getTrailingObjects<Stmt *>() + + numTrailingObjects(OverloadToken<Stmt *>())); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == SwitchStmtClass; } @@ -2179,6 +2316,12 @@ public: getTrailingObjects<Stmt *>() + numTrailingObjects(OverloadToken<Stmt *>())); } + + const_child_range children() const { + return const_child_range(getTrailingObjects<Stmt *>(), + getTrailingObjects<Stmt *>() + + numTrailingObjects(OverloadToken<Stmt *>())); + } }; /// DoStmt - This represents a 'do/while' stmt. @@ -2229,6 +2372,10 @@ public: 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); + } }; /// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of @@ -2298,6 +2445,10 @@ public: 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); + } }; /// GotoStmt - This represents a direct goto. @@ -2333,6 +2484,10 @@ public: 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()); + } }; /// IndirectGotoStmt - This represents an indirect goto. @@ -2378,6 +2533,10 @@ public: // Iterators child_range children() { return child_range(&Target, &Target + 1); } + + const_child_range children() const { + return const_child_range(&Target, &Target + 1); + } }; /// ContinueStmt - This represents a continue. @@ -2404,6 +2563,10 @@ public: 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()); + } }; /// BreakStmt - This represents a break. @@ -2430,6 +2593,10 @@ public: 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()); + } }; /// ReturnStmt - This represents a return, optionally of an expression: @@ -2514,6 +2681,12 @@ public: return child_range(&RetExpr, &RetExpr + 1); return child_range(child_iterator(), child_iterator()); } + + const_child_range children() const { + if (RetExpr) + return const_child_range(&RetExpr, &RetExpr + 1); + return const_child_range(const_child_iterator(), const_child_iterator()); + } }; /// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt. @@ -2669,6 +2842,10 @@ public: child_range children() { return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); } + + const_child_range children() const { + return const_child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs); + } }; /// This represents a GCC inline-assembly statement extension. @@ -2682,13 +2859,15 @@ class GCCAsmStmt : public AsmStmt { StringLiteral **Constraints = nullptr; StringLiteral **Clobbers = nullptr; IdentifierInfo **Names = nullptr; + unsigned NumLabels = 0; public: GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile, unsigned numoutputs, unsigned numinputs, IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, - StringLiteral **clobbers, SourceLocation rparenloc); + StringLiteral **clobbers, unsigned numlabels, + SourceLocation rparenloc); /// Build an empty inline-assembly statement. explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {} @@ -2813,6 +2992,51 @@ public: return const_cast<GCCAsmStmt*>(this)->getInputExpr(i); } + //===--- Labels ---===// + + bool isAsmGoto() const { + return NumLabels > 0; + } + + unsigned getNumLabels() const { + return NumLabels; + } + + IdentifierInfo *getLabelIdentifier(unsigned i) const { + return Names[i + NumInputs]; + } + + AddrLabelExpr *getLabelExpr(unsigned i) const; + StringRef getLabelName(unsigned i) const; + using labels_iterator = CastIterator<AddrLabelExpr>; + using const_labels_iterator = ConstCastIterator<AddrLabelExpr>; + using labels_range = llvm::iterator_range<labels_iterator>; + using labels_const_range = llvm::iterator_range<const_labels_iterator>; + + labels_iterator begin_labels() { + return &Exprs[0] + NumInputs; + } + + labels_iterator end_labels() { + return &Exprs[0] + NumInputs + NumLabels; + } + + labels_range labels() { + return labels_range(begin_labels(), end_labels()); + } + + const_labels_iterator begin_labels() const { + return &Exprs[0] + NumInputs; + } + + const_labels_iterator end_labels() const { + return &Exprs[0] + NumInputs + NumLabels; + } + + labels_const_range labels() const { + return labels_const_range(begin_labels(), end_labels()); + } + private: void setOutputsAndInputsAndClobbers(const ASTContext &C, IdentifierInfo **Names, @@ -2820,6 +3044,7 @@ private: Stmt **Exprs, unsigned NumOutputs, unsigned NumInputs, + unsigned NumLabels, StringLiteral **Clobbers, unsigned NumClobbers); @@ -2945,6 +3170,10 @@ public: child_range children() { return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]); } + + const_child_range children() const { + return const_child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]); + } }; class SEHExceptStmt : public Stmt { @@ -2982,6 +3211,10 @@ public: return child_range(Children, Children+2); } + const_child_range children() const { + return const_child_range(Children, Children + 2); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == SEHExceptStmtClass; } @@ -3013,6 +3246,10 @@ public: return child_range(&Block,&Block+1); } + const_child_range children() const { + return const_child_range(&Block, &Block + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == SEHFinallyStmtClass; } @@ -3061,6 +3298,10 @@ public: return child_range(Children, Children+2); } + const_child_range children() const { + return const_child_range(Children, Children + 2); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == SEHTryStmtClass; } @@ -3091,6 +3332,10 @@ public: 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()); + } }; /// This captures a statement into a function. For example, the following @@ -3311,6 +3556,8 @@ public: } child_range children(); + + const_child_range children() const; }; } // namespace clang diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index d3a3cf783c66..4d1f3e8ef255 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -1,9 +1,8 @@ //===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -57,6 +56,10 @@ public: child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); } + const_child_range children() const { + return const_child_range(&HandlerBlock, &HandlerBlock + 1); + } + friend class ASTStmtReader; }; @@ -115,6 +118,10 @@ public: child_range children() { return child_range(getStmts(), getStmts() + getNumHandlers() + 1); } + + const_child_range children() const { + return const_child_range(getStmts(), getStmts() + getNumHandlers() + 1); + } }; /// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for @@ -209,6 +216,10 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[END]); } + + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[END]); + } }; /// Representation of a Microsoft __if_exists or __if_not_exists @@ -291,6 +302,10 @@ public: return child_range(&SubStmt, &SubStmt+1); } + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == MSDependentExistsStmtClass; } @@ -416,6 +431,12 @@ public: getStoredStmts() + SubStmt::FirstParamMove + NumParams); } + const_child_range children() const { + return const_child_range(getStoredStmts(), getStoredStmts() + + SubStmt::FirstParamMove + + NumParams); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == CoroutineBodyStmtClass; } @@ -480,6 +501,13 @@ public: return child_range(SubStmts, SubStmts + SubStmt::Count); } + const_child_range children() const { + if (!getOperand()) + return const_child_range(SubStmts + SubStmt::PromiseCall, + SubStmts + SubStmt::Count); + return const_child_range(SubStmts, SubStmts + SubStmt::Count); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == CoreturnStmtClass; } diff --git a/include/clang/AST/StmtDataCollectors.td b/include/clang/AST/StmtDataCollectors.td index 90ca08027330..a46d2714eb4b 100644 --- a/include/clang/AST/StmtDataCollectors.td +++ b/include/clang/AST/StmtDataCollectors.td @@ -189,8 +189,8 @@ class CXXFoldExpr { } class GenericSelectionExpr { code Code = [{ - for (unsigned i = 0; i < S->getNumAssocs(); ++i) { - addData(S->getAssocType(i)); + for (const GenericSelectionExpr::ConstAssociation &Assoc : S->associations()) { + addData(Assoc.getType()); } }]; } diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h index 02c77b242c7c..ee1e8cfa1912 100644 --- a/include/clang/AST/StmtGraphTraits.h +++ b/include/clang/AST/StmtGraphTraits.h @@ -1,9 +1,8 @@ //===- StmtGraphTraits.h - Graph Traits for the class Stmt ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h index 806edaa38821..911205347aad 100644 --- a/include/clang/AST/StmtIterator.h +++ b/include/clang/AST/StmtIterator.h @@ -1,9 +1,8 @@ //===- StmtIterator.h - Iterators for Statements ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h index f0c0a9aeb6ac..948ef2421cb9 100644 --- a/include/clang/AST/StmtObjC.h +++ b/include/clang/AST/StmtObjC.h @@ -1,9 +1,8 @@ //===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -68,6 +67,10 @@ public: child_range children() { return child_range(&SubExprs[0], &SubExprs[END_EXPR]); } + + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[END_EXPR]); + } }; /// Represents Objective-C's \@catch statement. @@ -114,6 +117,10 @@ public: } child_range children() { return child_range(&Body, &Body + 1); } + + const_child_range children() const { + return const_child_range(&Body, &Body + 1); + } }; /// Represents Objective-C's \@finally statement @@ -148,6 +155,10 @@ public: child_range children() { return child_range(&AtFinallyStmt, &AtFinallyStmt+1); } + + const_child_range children() const { + return const_child_range(&AtFinallyStmt, &AtFinallyStmt + 1); + } }; /// Represents Objective-C's \@try ... \@catch ... \@finally statement. @@ -249,6 +260,10 @@ public: return child_range(getStmts(), getStmts() + 1 + NumCatchStmts + HasFinally); } + + const_child_range children() const { + return const_child_range(const_cast<ObjCAtTryStmt *>(this)->children()); + } }; /// Represents Objective-C's \@synchronized statement. @@ -307,6 +322,10 @@ public: child_range children() { return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR); } + + const_child_range children() const { + return const_child_range(&SubStmts[0], &SubStmts[0] + END_EXPR); + } }; /// Represents Objective-C's \@throw statement. @@ -339,6 +358,10 @@ public: } child_range children() { return child_range(&Throw, &Throw+1); } + + const_child_range children() const { + return const_child_range(&Throw, &Throw + 1); + } }; /// Represents Objective-C's \@autoreleasepool Statement @@ -370,6 +393,10 @@ public: } child_range children() { return child_range(&SubStmt, &SubStmt + 1); } + + const_child_range children() const { + return const_child_range(&SubStmt, &SubStmt + 1); + } }; } // end namespace clang diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index d1eedd62b372..e37f5b1e0004 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -1,9 +1,8 @@ //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file @@ -88,6 +87,63 @@ protected: } public: + /// Iterates over expressions/statements used in the construct. + class used_clauses_child_iterator + : public llvm::iterator_adaptor_base< + used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator, + std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { + ArrayRef<OMPClause *>::iterator End; + OMPClause::child_iterator ChildI, ChildEnd; + + void MoveToNext() { + if (ChildI != ChildEnd) + return; + while (this->I != End) { + ++this->I; + if (this->I != End) { + ChildI = (*this->I)->used_children().begin(); + ChildEnd = (*this->I)->used_children().end(); + if (ChildI != ChildEnd) + return; + } + } + } + + public: + explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses) + : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()), + End(Clauses.end()) { + if (this->I != End) { + ChildI = (*this->I)->used_children().begin(); + ChildEnd = (*this->I)->used_children().end(); + MoveToNext(); + } + } + Stmt *operator*() const { return *ChildI; } + Stmt *operator->() const { return **this; } + + used_clauses_child_iterator &operator++() { + ++ChildI; + if (ChildI != ChildEnd) + return *this; + if (this->I != End) { + ++this->I; + if (this->I != End) { + ChildI = (*this->I)->used_children().begin(); + ChildEnd = (*this->I)->used_children().end(); + } + } + MoveToNext(); + return *this; + } + }; + + static llvm::iterator_range<used_clauses_child_iterator> + used_clauses_children(ArrayRef<OMPClause *> Clauses) { + return {used_clauses_child_iterator(Clauses), + used_clauses_child_iterator(llvm::makeArrayRef(Clauses.end(), 0))}; + } + /// Iterates over a filtered subrange of clauses applied to a /// directive. /// @@ -257,11 +313,35 @@ public: return child_range(ChildStorage, ChildStorage + 1); } + const_child_range children() const { + if (!hasAssociatedStmt()) + return const_child_range(const_child_iterator(), const_child_iterator()); + Stmt **ChildStorage = reinterpret_cast<Stmt **>( + const_cast<OMPExecutableDirective *>(this)->getClauses().end()); + return const_child_range(ChildStorage, ChildStorage + 1); + } + ArrayRef<OMPClause *> clauses() { return getClauses(); } ArrayRef<OMPClause *> clauses() const { return const_cast<OMPExecutableDirective *>(this)->getClauses(); } + + /// Returns whether or not this is a Standalone directive. + /// + /// Stand-alone directives are executable directives + /// that have no associated user code. + bool isStandaloneDirective() const; + + /// Returns the AST node representing OpenMP structured-block of this + /// OpenMP executable directive, + /// Prerequisite: Executable Directive must not be Standalone directive. + const Stmt *getStructuredBlock() const; + + Stmt *getStructuredBlock() { + return const_cast<Stmt *>( + const_cast<const OMPExecutableDirective *>(this)->getStructuredBlock()); + } }; /// This represents '#pragma omp parallel' directive. diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h index ea40e0497307..d3be93d228cc 100644 --- a/include/clang/AST/StmtVisitor.h +++ b/include/clang/AST/StmtVisitor.h @@ -1,9 +1,8 @@ //===- StmtVisitor.h - Visitor for Stmt subclasses --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TemplateArgumentVisitor.h b/include/clang/AST/TemplateArgumentVisitor.h index e1cc392a1705..190aa97adf45 100644 --- a/include/clang/AST/TemplateArgumentVisitor.h +++ b/include/clang/AST/TemplateArgumentVisitor.h @@ -1,9 +1,8 @@ //===- TemplateArgumentVisitor.h - Visitor for TArg subclasses --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index e3a773b4e490..058a5bc0a067 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -1,9 +1,8 @@ //===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 48272597d4d1..4cc6f5e6ce82 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -1,9 +1,8 @@ //===- TemplateName.h - C++ Template Name Representation --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -32,6 +31,8 @@ class NamedDecl; class NestedNameSpecifier; enum OverloadedOperatorKind : int; class OverloadedTemplateStorage; +class AssumedTemplateStorage; +class PartialDiagnostic; struct PrintingPolicy; class QualifiedTemplateName; class SubstTemplateTemplateParmPackStorage; @@ -46,6 +47,7 @@ class UncommonTemplateNameStorage { protected: enum Kind { Overloaded, + Assumed, // defined in DeclarationName.h SubstTemplateTemplateParm, SubstTemplateTemplateParmPack }; @@ -78,6 +80,12 @@ public: : nullptr; } + AssumedTemplateStorage *getAsAssumedTemplateName() { + return Bits.Kind == Assumed + ? reinterpret_cast<AssumedTemplateStorage *>(this) + : nullptr; + } + SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() { return Bits.Kind == SubstTemplateTemplateParm ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this) @@ -194,6 +202,10 @@ public: /// A set of overloaded template declarations. OverloadedTemplate, + /// An unqualified-id that has been assumed to name a function template + /// that will be found by ADL. + AssumedTemplate, + /// A qualified template name, where the qualification is kept /// to describe the source code as written. QualifiedTemplate, @@ -215,6 +227,7 @@ public: TemplateName() = default; explicit TemplateName(TemplateDecl *Template); explicit TemplateName(OverloadedTemplateStorage *Storage); + explicit TemplateName(AssumedTemplateStorage *Storage); explicit TemplateName(SubstTemplateTemplateParmStorage *Storage); explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage); explicit TemplateName(QualifiedTemplateName *Qual); @@ -236,7 +249,7 @@ public: TemplateDecl *getAsTemplateDecl() const; /// Retrieve the underlying, overloaded function template - // declarations that this template name refers to, if known. + /// declarations that this template name refers to, if known. /// /// \returns The set of overloaded function templates that this template /// name refers to, if known. If the template name does not refer to a @@ -244,6 +257,10 @@ public: /// refers to a single template, returns NULL. OverloadedTemplateStorage *getAsOverloadedTemplate() const; + /// Retrieve information on a name that has been assumed to be a + /// template-name in order to permit a call via ADL. + AssumedTemplateStorage *getAsAssumedTemplateName() const; + /// Retrieve the substituted template template parameter, if /// known. /// @@ -320,6 +337,8 @@ public: /// into a diagnostic with <<. const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, TemplateName N); +const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + TemplateName N); /// A structure for storing the information associated with a /// substituted template template parameter. diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h index 794066376300..4c2d0710963b 100644 --- a/include/clang/AST/TextNodeDumper.h +++ b/include/clang/AST/TextNodeDumper.h @@ -1,9 +1,8 @@ //===--- TextNodeDumper.h - Printing of AST nodes -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,6 +18,7 @@ #include "clang/AST/AttrVisitor.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/CommentVisitor.h" +#include "clang/AST/DeclVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" @@ -129,7 +129,8 @@ class TextNodeDumper public ConstAttrVisitor<TextNodeDumper>, public ConstTemplateArgumentVisitor<TextNodeDumper>, public ConstStmtVisitor<TextNodeDumper>, - public TypeVisitor<TextNodeDumper> { + public TypeVisitor<TextNodeDumper>, + public ConstDeclVisitor<TextNodeDumper> { raw_ostream &OS; const bool ShowColors; @@ -145,6 +146,8 @@ class TextNodeDumper const comments::CommandTraits *Traits; + const ASTContext *Context; + const char *getCommandName(unsigned CommandID); public: @@ -173,6 +176,8 @@ public: void Visit(const BlockDecl::Capture &C); + void Visit(const GenericSelectionExpr::ConstAssociation &A); + void dumpPointer(const void *Ptr); void dumpLocation(SourceLocation Loc); void dumpSourceRange(SourceRange R); @@ -225,6 +230,7 @@ public: void VisitLabelStmt(const LabelStmt *Node); void VisitGotoStmt(const GotoStmt *Node); void VisitCaseStmt(const CaseStmt *Node); + void VisitConstantExpr(const ConstantExpr *Node); void VisitCallExpr(const CallExpr *Node); void VisitCastExpr(const CastExpr *Node); void VisitImplicitCastExpr(const ImplicitCastExpr *Node); @@ -236,6 +242,7 @@ public: void VisitFloatingLiteral(const FloatingLiteral *Node); void VisitStringLiteral(const StringLiteral *Str); void VisitInitListExpr(const InitListExpr *ILE); + void VisitGenericSelectionExpr(const GenericSelectionExpr *E); void VisitUnaryOperator(const UnaryOperator *Node); void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node); void VisitMemberExpr(const MemberExpr *Node); @@ -289,8 +296,58 @@ public: void VisitObjCInterfaceType(const ObjCInterfaceType *T); void VisitPackExpansionType(const PackExpansionType *T); -private: - void dumpCXXTemporary(const CXXTemporary *Temporary); + void VisitLabelDecl(const LabelDecl *D); + void VisitTypedefDecl(const TypedefDecl *D); + void VisitEnumDecl(const EnumDecl *D); + void VisitRecordDecl(const RecordDecl *D); + void VisitEnumConstantDecl(const EnumConstantDecl *D); + void VisitIndirectFieldDecl(const IndirectFieldDecl *D); + void VisitFunctionDecl(const FunctionDecl *D); + void VisitFieldDecl(const FieldDecl *D); + void VisitVarDecl(const VarDecl *D); + void VisitBindingDecl(const BindingDecl *D); + void VisitCapturedDecl(const CapturedDecl *D); + void VisitImportDecl(const ImportDecl *D); + void VisitPragmaCommentDecl(const PragmaCommentDecl *D); + void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D); + void VisitOMPExecutableDirective(const OMPExecutableDirective *D); + void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D); + void VisitOMPRequiresDecl(const OMPRequiresDecl *D); + void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D); + void VisitNamespaceDecl(const NamespaceDecl *D); + void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D); + void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); + void VisitTypeAliasDecl(const TypeAliasDecl *D); + void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D); + void VisitCXXRecordDecl(const CXXRecordDecl *D); + void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); + void VisitClassTemplateDecl(const ClassTemplateDecl *D); + void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D); + void VisitVarTemplateDecl(const VarTemplateDecl *D); + void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); + void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); + void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); + void VisitUsingDecl(const UsingDecl *D); + void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); + void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); + void VisitUsingShadowDecl(const UsingShadowDecl *D); + void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D); + void VisitLinkageSpecDecl(const LinkageSpecDecl *D); + void VisitAccessSpecDecl(const AccessSpecDecl *D); + void VisitFriendDecl(const FriendDecl *D); + void VisitObjCIvarDecl(const ObjCIvarDecl *D); + void VisitObjCMethodDecl(const ObjCMethodDecl *D); + void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D); + void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); + void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); + void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); + void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); + void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); + void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); + void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); + void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); + void VisitBlockDecl(const BlockDecl *D); + void VisitConceptDecl(const ConceptDecl *D); }; } // namespace clang diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index d4c97b1b5efc..584655fe789e 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1,9 +1,8 @@ //===- Type.h - C Language Family Type Representation -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -95,9 +94,6 @@ namespace llvm { enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; }; - template <> - struct isPodLike<clang::QualType> { static const bool value = true; }; - } // namespace llvm namespace clang { @@ -321,6 +317,11 @@ public: qs.removeObjCLifetime(); return qs; } + Qualifiers withoutAddressSpace() const { + Qualifiers qs = *this; + qs.removeAddressSpace(); + return qs; + } bool hasObjCLifetime() const { return Mask & LifetimeMask; } ObjCLifetime getObjCLifetime() const { @@ -459,21 +460,25 @@ public: Mask |= qs.Mask; } - /// Returns true if this address space is a superset of the other one. + /// Returns true if address space A is equal to or a superset of B. /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of /// overlapping address spaces. /// CL1.1 or CL1.2: /// every address space is a superset of itself. /// CL2.0 adds: /// __generic is a superset of any address space except for __constant. + static bool isAddressSpaceSupersetOf(LangAS A, LangAS B) { + // Address spaces must match exactly. + return A == B || + // Otherwise in OpenCLC v2.0 s6.5.5: every address space except + // for __constant can be used as __generic. + (A == LangAS::opencl_generic && B != LangAS::opencl_constant); + } + + /// Returns true if the address space in these qualifiers is equal to or + /// a superset of the address space in the argument qualifiers. bool isAddressSpaceSupersetOf(Qualifiers other) const { - return - // Address spaces must match exactly. - getAddressSpace() == other.getAddressSpace() || - // Otherwise in OpenCLC v2.0 s6.5.5: every address space except - // for __constant can be used as __generic. - (getAddressSpace() == LangAS::opencl_generic && - other.getAddressSpace() != LangAS::opencl_constant); + return isAddressSpaceSupersetOf(getAddressSpace(), other.getAddressSpace()); } /// Determines if these qualifiers compatibly include another set. @@ -1153,6 +1158,22 @@ public: return isDestructedTypeImpl(*this); } + /// Check if this is or contains a C union that is non-trivial to + /// default-initialize, which is a union that has a member that is non-trivial + /// to default-initialize. If this returns true, + /// isNonTrivialToPrimitiveDefaultInitialize returns PDIK_Struct. + bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const; + + /// Check if this is or contains a C union that is non-trivial to destruct, + /// which is a union that has a member that is non-trivial to destruct. If + /// this returns true, isDestructedType returns DK_nontrivial_c_struct. + bool hasNonTrivialToPrimitiveDestructCUnion() const; + + /// Check if this is or contains a C union that is non-trivial to copy, which + /// is a union that has a member that is non-trivial to copy. If this returns + /// true, isNonTrivialToPrimitiveCopy returns PCK_Struct. + bool hasNonTrivialToPrimitiveCopyCUnion() const; + /// Determine whether expressions of the given type are forbidden /// from being lvalues in C. /// @@ -1225,6 +1246,11 @@ private: const ASTContext &C); static QualType IgnoreParens(QualType T); static DestructionKind isDestructedTypeImpl(QualType type); + + /// Check if \param RD is or contains a non-trivial C union. + static bool hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD); + static bool hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD); + static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD); }; } // namespace clang @@ -1404,7 +1430,7 @@ enum class AutoTypeKeyword { /// /// Types, once created, are immutable. /// -class Type : public ExtQualsTypeCommonBase { +class alignas(8) Type : public ExtQualsTypeCommonBase { public: enum TypeClass { #define TYPE(Class, Base) Class, @@ -1806,7 +1832,9 @@ public: friend class ASTWriter; Type(const Type &) = delete; + Type(Type &&) = delete; Type &operator=(const Type &) = delete; + Type &operator=(Type &&) = delete; TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); } @@ -1953,6 +1981,7 @@ public: bool isLValueReferenceType() const; bool isRValueReferenceType() const; bool isFunctionPointerType() const; + bool isFunctionReferenceType() const; bool isMemberPointerType() const; bool isMemberFunctionPointerType() const; bool isMemberDataPointerType() const; @@ -1986,7 +2015,7 @@ public: bool isObjCQualifiedClassType() const; // Class<foo> bool isObjCObjectOrInterfaceType() const; bool isObjCIdType() const; // id - + bool isDecltypeType() const; /// Was this type written with the special inert-in-ARC __unsafe_unretained /// qualifier? /// @@ -2269,6 +2298,9 @@ public: /// ISO/IEC JTC1 SC22 WG14 N1169. bool isFixedPointType() const; + /// Return true if this is a fixed point or integer type. + bool isFixedPointOrIntegerType() const; + /// Return true if this is a saturated fixed point type according to /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. bool isSaturatedFixedPointType() const; @@ -3843,6 +3875,7 @@ private: case EST_MSAny: case EST_BasicNoexcept: case EST_Unparsed: + case EST_NoThrow: return {0, 0, 0}; case EST_Dynamic: @@ -3902,7 +3935,7 @@ public: EPI.Variadic = isVariadic(); EPI.HasTrailingReturn = hasTrailingReturn(); EPI.ExceptionSpec.Type = getExceptionSpecType(); - EPI.TypeQuals = getTypeQuals(); + EPI.TypeQuals = getMethodQuals(); EPI.RefQualifier = getRefQualifier(); if (EPI.ExceptionSpec.Type == EST_Dynamic) { EPI.ExceptionSpec.Exceptions = exceptions(); @@ -4012,7 +4045,7 @@ public: /// Whether this function prototype has a trailing return type. bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; } - Qualifiers getTypeQuals() const { + Qualifiers getMethodQuals() const { if (hasExtQualifiers()) return *getTrailingObjects<Qualifiers>(); else @@ -4172,6 +4205,41 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } }; +/// Sugar type that represents a type that was qualified by a qualifier written +/// as a macro invocation. +class MacroQualifiedType : public Type { + friend class ASTContext; // ASTContext creates these. + + QualType UnderlyingTy; + const IdentifierInfo *MacroII; + + MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy, + const IdentifierInfo *MacroII) + : Type(MacroQualified, CanonTy, UnderlyingTy->isDependentType(), + UnderlyingTy->isInstantiationDependentType(), + UnderlyingTy->isVariablyModifiedType(), + UnderlyingTy->containsUnexpandedParameterPack()), + UnderlyingTy(UnderlyingTy), MacroII(MacroII) { + assert(isa<AttributedType>(UnderlyingTy) && + "Expected a macro qualified type to only wrap attributed types."); + } + +public: + const IdentifierInfo *getMacroIdentifier() const { return MacroII; } + QualType getUnderlyingType() const { return UnderlyingTy; } + + /// Return this attributed type's modified type with no qualifiers attached to + /// it. + QualType getModifiedType() const; + + bool isSugared() const { return true; } + QualType desugar() const; + + static bool classof(const Type *T) { + return T->getTypeClass() == MacroQualified; + } +}; + /// Represents a `typeof` (or __typeof__) expression (a GCC extension). class TypeOfExprType : public Type { Expr *TOExpr; @@ -4750,9 +4818,9 @@ class AutoType : public DeducedType, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, - bool IsDeducedAsDependent) + bool IsDeducedAsDependent, bool IsDeducedAsPack) : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent, - IsDeducedAsDependent, /*ContainsPack=*/false) { + IsDeducedAsDependent, IsDeducedAsPack) { AutoTypeBits.Keyword = (unsigned)Keyword; } @@ -4766,14 +4834,16 @@ public: } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDeducedType(), getKeyword(), isDependentType()); + Profile(ID, getDeducedType(), getKeyword(), isDependentType(), + containsUnexpandedParameterPack()); } static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, - AutoTypeKeyword Keyword, bool IsDependent) { + AutoTypeKeyword Keyword, bool IsDependent, bool IsPack) { ID.AddPointer(Deduced.getAsOpaquePtr()); ID.AddInteger((unsigned)Keyword); ID.AddBoolean(IsDependent); + ID.AddBoolean(IsPack); } static bool classof(const Type *T) { @@ -6194,6 +6264,24 @@ inline Qualifiers::GC QualType::getObjCGCAttr() const { return getQualifiers().getObjCGCAttr(); } +inline bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion() const { + if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) + return hasNonTrivialToPrimitiveDefaultInitializeCUnion(RD); + return false; +} + +inline bool QualType::hasNonTrivialToPrimitiveDestructCUnion() const { + if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) + return hasNonTrivialToPrimitiveDestructCUnion(RD); + return false; +} + +inline bool QualType::hasNonTrivialToPrimitiveCopyCUnion() const { + if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl()) + return hasNonTrivialToPrimitiveCopyCUnion(RD); + return false; +} + inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { if (const auto *PT = t.getAs<PointerType>()) { if (const auto *FT = PT->getPointeeType()->getAs<FunctionType>()) @@ -6324,6 +6412,13 @@ inline bool Type::isFunctionPointerType() const { return false; } +inline bool Type::isFunctionReferenceType() const { + if (const auto *T = getAs<ReferenceType>()) + return T->getPointeeType()->isFunctionType(); + else + return false; +} + inline bool Type::isMemberPointerType() const { return isa<MemberPointerType>(CanonicalType); } @@ -6441,6 +6536,10 @@ inline bool Type::isObjCBuiltinType() const { return isObjCIdType() || isObjCClassType() || isObjCSelType(); } +inline bool Type::isDecltypeType() const { + return isa<DecltypeType>(this); +} + #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ inline bool Type::is##Id##Type() const { \ return isSpecificBuiltinType(BuiltinType::Id); \ @@ -6596,6 +6695,10 @@ inline bool Type::isFixedPointType() const { return false; } +inline bool Type::isFixedPointOrIntegerType() const { + return isFixedPointType() || isIntegerType(); +} + inline bool Type::isSaturatedFixedPointType() const { if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) { return BT->getKind() >= BuiltinType::SatShortAccum && @@ -6785,6 +6888,8 @@ template <typename T> const T *Type::getAsAdjusted() const { Ty = P->desugar().getTypePtr(); else if (const auto *A = dyn_cast<AdjustedType>(Ty)) Ty = A->desugar().getTypePtr(); + else if (const auto *M = dyn_cast<MacroQualifiedType>(Ty)) + Ty = M->desugar().getTypePtr(); else break; } @@ -6841,6 +6946,8 @@ QualType DecayedType::getPointeeType() const { // Get the decimal string representation of a fixed point type, represented // as a scaled integer. +// TODO: At some point, we should change the arguments to instead just accept an +// APFixedPoint instead of APSInt and scale. void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val, unsigned Scale); diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 1e89e9386719..40d17f991f1f 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -1,9 +1,8 @@ //===- TypeLoc.h - Type Source Info Wrapper ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -174,6 +173,9 @@ public: TypeLoc IgnoreParens() const; + /// Strips MacroDefinitionTypeLocs from a type location. + TypeLoc IgnoreMacroDefinitions() const; + /// Find a type with the location of an explicit type qualifier. /// /// The result, if non-null, will be one of: @@ -1081,6 +1083,39 @@ public: } }; +struct MacroQualifiedLocInfo { + SourceLocation ExpansionLoc; +}; + +class MacroQualifiedTypeLoc + : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc, + MacroQualifiedType, MacroQualifiedLocInfo> { +public: + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + setExpansionLoc(Loc); + } + + TypeLoc getInnerLoc() const { return getInnerTypeLoc(); } + + const IdentifierInfo *getMacroIdentifier() const { + return getTypePtr()->getMacroIdentifier(); + } + + SourceLocation getExpansionLoc() const { + return this->getLocalData()->ExpansionLoc; + } + + void setExpansionLoc(SourceLocation Loc) { + this->getLocalData()->ExpansionLoc = Loc; + } + + QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); } + + SourceRange getLocalSourceRange() const { + return getInnerLoc().getLocalSourceRange(); + } +}; + struct ParenLocInfo { SourceLocation LParenLoc; SourceLocation RParenLoc; @@ -2290,6 +2325,8 @@ inline T TypeLoc::getAsAdjusted() const { Cur = ETL.getNamedTypeLoc(); else if (auto ATL = Cur.getAs<AdjustedTypeLoc>()) Cur = ATL.getOriginalLoc(); + else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>()) + Cur = MQL.getInnerLoc(); else break; } diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def index 4590e489e3f7..c0dfe150d6cc 100644 --- a/include/clang/AST/TypeLocNodes.def +++ b/include/clang/AST/TypeLocNodes.def @@ -1,9 +1,8 @@ //===-- TypeLocNodes.def - Metadata about TypeLoc wrappers ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h index db5775aa146e..ec780884e96c 100644 --- a/include/clang/AST/TypeLocVisitor.h +++ b/include/clang/AST/TypeLocVisitor.h @@ -1,9 +1,8 @@ //===--- TypeLocVisitor.h - Visitor for TypeLoc subclasses ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index 8638f94bda14..58a5f880cbe6 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -1,9 +1,8 @@ //===-- TypeNodes.def - Metadata about Type AST nodes -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -83,6 +82,7 @@ TYPE(FunctionNoProto, FunctionType) DEPENDENT_TYPE(UnresolvedUsing, Type) NON_CANONICAL_TYPE(Paren, Type) NON_CANONICAL_TYPE(Typedef, Type) +NON_CANONICAL_TYPE(MacroQualified, Type) NON_CANONICAL_TYPE(Adjusted, Type) NON_CANONICAL_TYPE(Decayed, AdjustedType) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type) diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h index 7ea78071f5cf..6630105136f5 100644 --- a/include/clang/AST/TypeOrdering.h +++ b/include/clang/AST/TypeOrdering.h @@ -1,9 +1,8 @@ //===-------------- TypeOrdering.h - Total ordering for types ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h index 75fa0ec15ce2..8930ec853949 100644 --- a/include/clang/AST/TypeVisitor.h +++ b/include/clang/AST/TypeVisitor.h @@ -1,9 +1,8 @@ //===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index b62e9f138bb6..cfc0b87eec7e 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -1,9 +1,8 @@ //===- UnresolvedSet.h - Unresolved sets of declarations --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h index 3a8a6a9c15f0..4acbc1f9e96b 100644 --- a/include/clang/AST/VTTBuilder.h +++ b/include/clang/AST/VTTBuilder.h @@ -1,9 +1,8 @@ //===- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h index 4a779db01ff8..43c84292c091 100644 --- a/include/clang/AST/VTableBuilder.h +++ b/include/clang/AST/VTableBuilder.h @@ -1,9 +1,8 @@ //===--- VTableBuilder.h - C++ vtable layout builder --------------*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h index 324c02db3fe0..4c8dd87cecbb 100644 --- a/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/include/clang/ASTMatchers/ASTMatchFinder.h @@ -1,9 +1,8 @@ //===--- ASTMatchFinder.h - Structural query framework ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 5cdb964a92c2..063d8217d9aa 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -1,9 +1,8 @@ //===- ASTMatchers.h - Structural query framework ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -57,10 +56,12 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenMP.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -1137,6 +1138,17 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl> cxxConversionDecl; +/// Matches user-defined and implicitly generated deduction guide. +/// +/// Example matches the deduction guide. +/// \code +/// template<typename T> +/// class X { X(int) }; +/// X(int) -> X<int>; +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl> + cxxDeductionGuideDecl; + /// Matches variable declarations. /// /// Note: this does not match declarations of member variables, which are @@ -2159,6 +2171,10 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr; +/// Matches GNU __builtin_choose_expr. +extern const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr> + chooseExpr; + /// Matches GNU __null expression. extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr; @@ -2487,6 +2503,9 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType, /// \endcode /// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf)) /// matches \c sizeof(x) +/// +/// If the matcher is use from clang-query, UnaryExprOrTypeTrait parameter +/// should be passed as a quoted string. e.g., ofKind("UETT_SizeOf"). AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) { return Node.getKind() == Kind; } @@ -2887,14 +2906,22 @@ AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher<NamedDecl>, InnerMatcher.matches(*UnderlyingDecl, Finder, Builder); } -/// Matches on the implicit object argument of a member call expression. +/// Matches on the implicit object argument of a member call expression, after +/// stripping off any parentheses or implicit casts. /// -/// Example matches y.x() -/// (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))) +/// Given /// \code -/// class Y { public: void x(); }; -/// void z() { Y y; y.x(); } +/// class Y { public: void m(); }; +/// Y g(); +/// class X : public Y {}; +/// void z(Y y, X x) { y.m(); (g()).m(); x.m(); } /// \endcode +/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))))) +/// matches `y.m()` and `(g()).m()`. +/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X"))))) +/// matches `x.m()`. +/// cxxMemberCallExpr(on(callExpr())) +/// matches `(g()).m()`. /// /// FIXME: Overload to allow directly matching types? AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>, @@ -2922,10 +2949,59 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>, return InnerMatcher.matches(TypeDecl, Finder, Builder); } +/// Returns true when the Objective-C method declaration is a class method. +/// +/// Example +/// matcher = objcMethodDecl(isClassMethod()) +/// matches +/// \code +/// @interface I + (void)foo; @end +/// \endcode +/// but not +/// \code +/// @interface I - (void)bar; @end +/// \endcode +AST_MATCHER(ObjCMethodDecl, isClassMethod) { + return Node.isClassMethod(); +} + +/// Returns true when the Objective-C method declaration is an instance method. +/// +/// Example +/// matcher = objcMethodDecl(isInstanceMethod()) +/// matches +/// \code +/// @interface I - (void)bar; @end +/// \endcode +/// but not +/// \code +/// @interface I + (void)foo; @end +/// \endcode +AST_MATCHER(ObjCMethodDecl, isInstanceMethod) { + return Node.isInstanceMethod(); +} + +/// Returns true when the Objective-C message is sent to a class. +/// +/// Example +/// matcher = objcMessageExpr(isClassMessage()) +/// matches +/// \code +/// [NSString stringWithFormat:@"format"]; +/// \endcode +/// but not +/// \code +/// NSString *x = @"hello"; +/// [x containsString:@"h"]; +/// \endcode +AST_MATCHER(ObjCMessageExpr, isClassMessage) { + return Node.isClassMessage(); +} + /// Returns true when the Objective-C message is sent to an instance. /// /// Example -/// matcher = objcMessagaeExpr(isInstanceMessage()) +/// matcher = objcMessageExpr(isInstanceMessage()) /// matches /// \code /// NSString *x = @"hello"; @@ -3254,6 +3330,23 @@ AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>, .matches(Node, Finder, Builder); } +/// Matches on the implicit object argument of a member call expression. Unlike +/// `on`, matches the argument directly without stripping away anything. +/// +/// Given +/// \code +/// class Y { public: void m(); }; +/// Y g(); +/// class X : public Y { void g(); }; +/// void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); } +/// \endcode +/// cxxMemberCallExpr(onImplicitObjectArgument(hasType( +/// cxxRecordDecl(hasName("Y"))))) +/// matches `y.m()`, `x.m()` and (g()).m(), but not `x.g()`. +/// cxxMemberCallExpr(on(callExpr())) +/// does not match `(g()).m()`, because the parens are not ignored. +/// +/// FIXME: Overload to allow directly matching types? AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, internal::Matcher<Expr>, InnerMatcher) { const Expr *ExprNode = Node.getImplicitObjectArgument(); @@ -3261,8 +3354,22 @@ AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, InnerMatcher.matches(*ExprNode, Finder, Builder)); } -/// Matches if the expression's type either matches the specified -/// matcher, or is a pointer to a type that matches the InnerMatcher. +/// Matches if the type of the expression's implicit object argument either +/// matches the InnerMatcher, or is a pointer to a type that matches the +/// InnerMatcher. +/// +/// Given +/// \code +/// class Y { public: void m(); }; +/// class X : public Y { void g(); }; +/// void z() { Y y; y.m(); Y *p; p->m(); X x; x.m(); x.g(); } +/// \endcode +/// cxxMemberCallExpr(thisPointerType(hasDeclaration( +/// cxxRecordDecl(hasName("Y"))))) +/// matches `y.m()`, `p->m()` and `x.m()`. +/// cxxMemberCallExpr(thisPointerType(hasDeclaration( +/// cxxRecordDecl(hasName("X"))))) +/// matches `x.g()`. AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, internal::Matcher<QualType>, InnerMatcher, 0) { return onImplicitObjectArgument( @@ -4439,6 +4546,9 @@ AST_POLYMORPHIC_MATCHER_P(hasSourceExpression, /// \code /// int *p = 0; /// \endcode +/// +/// If the matcher is use from clang-query, CastKind parameter +/// should be passed as a quoted string. e.g., ofKind("CK_NullToPointer"). AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) { return Node.getCastKind() == Kind; } @@ -4964,18 +5074,22 @@ AST_MATCHER_P(MemberExpr, member, return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); } -/// Matches a member expression where the object expression is -/// matched by a given matcher. +/// Matches a member expression where the object expression is matched by a +/// given matcher. Implicit object expressions are included; that is, it matches +/// use of implicit `this`. /// /// Given /// \code -/// struct X { int m; }; -/// void f(X x) { x.m; m; } +/// struct X { +/// int m; +/// int f(X x) { x.m; return m; } +/// }; /// \endcode -/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))))) -/// matches "x.m" and "m" -/// with hasObjectExpression(...) -/// matching "x" and the implicit object expression of "m" which has type X*. +/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))) +/// matches `x.m`, but not `m`; however, +/// memberExpr(hasObjectExpression(hasType(pointsTo( +// cxxRecordDecl(hasName("X")))))) +/// matches `m` (aka. `this->m`), but not `x.m`. AST_POLYMORPHIC_MATCHER_P( hasObjectExpression, AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr, @@ -6051,26 +6165,63 @@ AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) { return Node.isDelegatingConstructor(); } -/// Matches constructor and conversion declarations that are marked with -/// the explicit keyword. +/// Matches constructor, conversion function, and deduction guide declarations +/// that have an explicit specifier if this explicit specifier is resolved to +/// true. /// /// Given /// \code +/// template<bool b> /// struct S { /// S(int); // #1 /// explicit S(double); // #2 /// operator int(); // #3 /// explicit operator bool(); // #4 +/// explicit(false) S(bool) // # 7 +/// explicit(true) S(char) // # 8 +/// explicit(b) S(S) // # 9 /// }; +/// S(int) -> S<true> // #5 +/// explicit S(double) -> S<false> // #6 /// \endcode -/// cxxConstructorDecl(isExplicit()) will match #2, but not #1. +/// cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9. /// cxxConversionDecl(isExplicit()) will match #4, but not #3. -AST_POLYMORPHIC_MATCHER(isExplicit, - AST_POLYMORPHIC_SUPPORTED_TYPES(CXXConstructorDecl, - CXXConversionDecl)) { +/// cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5. +AST_POLYMORPHIC_MATCHER(isExplicit, AST_POLYMORPHIC_SUPPORTED_TYPES( + CXXConstructorDecl, CXXConversionDecl, + CXXDeductionGuideDecl)) { return Node.isExplicit(); } +/// Matches the expression in an explicit specifier if present in the given +/// declaration. +/// +/// Given +/// \code +/// template<bool b> +/// struct S { +/// S(int); // #1 +/// explicit S(double); // #2 +/// operator int(); // #3 +/// explicit operator bool(); // #4 +/// explicit(false) S(bool) // # 7 +/// explicit(true) S(char) // # 8 +/// explicit(b) S(S) // # 9 +/// }; +/// S(int) -> S<true> // #5 +/// explicit S(double) -> S<false> // #6 +/// \endcode +/// cxxConstructorDecl(hasExplicitSpecifier(constantExpr())) will match #7, #8 and #9, but not #1 or #2. +/// cxxConversionDecl(hasExplicitSpecifier(constantExpr())) will not match #3 or #4. +/// cxxDeductionGuideDecl(hasExplicitSpecifier(constantExpr())) will not match #5 or #6. +AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher<Expr>, + InnerMatcher) { + ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(&Node); + if (!ES.getExpr()) + return false; + return InnerMatcher.matches(*ES.getExpr(), Finder, Builder); +} + /// Matches function and namespace declarations that are marked with /// the inline keyword. /// @@ -6109,6 +6260,29 @@ AST_MATCHER(NamespaceDecl, isAnonymous) { return Node.isAnonymousNamespace(); } +/// Matches declarations in the namespace `std`, but not in nested namespaces. +/// +/// Given +/// \code +/// class vector {}; +/// namespace foo { +/// class vector {}; +/// namespace std { +/// class vector {}; +/// } +/// } +/// namespace std { +/// inline namespace __1 { +/// class vector {}; // #1 +/// namespace experimental { +/// class vector {}; +/// } +/// } +/// } +/// \endcode +/// cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1. +AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); } + /// If the given case statement does not use the GNU case range /// extension, matches the constant given in the statement. /// @@ -6133,7 +6307,7 @@ AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>, /// __attribute__((device)) void f() { ... } /// \endcode /// decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of -/// f. If the matcher is use from clang-query, attr::Kind parameter should be +/// f. If the matcher is used from clang-query, attr::Kind parameter should be /// passed as a quoted string. e.g., hasAttr("attr::CUDADevice"). AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) { for (const auto *Attr : Node.attrs()) { @@ -6284,8 +6458,8 @@ AST_MATCHER(CXXNewExpr, isArray) { /// cxxNewExpr(hasArraySize(intgerLiteral(equals(10)))) /// matches the expression 'new MyClass[10]'. AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher) { - return Node.isArray() && - InnerMatcher.matches(*Node.getArraySize(), Finder, Builder); + return Node.isArray() && *Node.getArraySize() && + InnerMatcher.matches(**Node.getArraySize(), Finder, Builder); } /// Matches a class declaration that is defined. @@ -6323,6 +6497,203 @@ AST_MATCHER(FunctionDecl, hasTrailingReturn) { return false; } +/// Matches expressions that match InnerMatcher that are possibly wrapped in an +/// elidable constructor. +/// +/// In C++17 copy elidable constructors are no longer being +/// generated in the AST as it is not permitted by the standard. They are +/// however part of the AST in C++14 and earlier. Therefore, to write a matcher +/// that works in all language modes, the matcher has to skip elidable +/// constructor AST nodes if they appear in the AST. This matcher can be used to +/// skip those elidable constructors. +/// +/// Given +/// +/// \code +/// struct H {}; +/// H G(); +/// void f() { +/// H D = G(); +/// } +/// \endcode +/// +/// ``varDecl(hasInitializer(any( +/// ignoringElidableConstructorCall(callExpr()), +/// exprWithCleanups(ignoringElidableConstructorCall(callExpr()))))`` +/// matches ``H D = G()`` +AST_MATCHER_P(Expr, ignoringElidableConstructorCall, + ast_matchers::internal::Matcher<Expr>, InnerMatcher) { + if (const auto *CtorExpr = dyn_cast<CXXConstructExpr>(&Node)) { + if (CtorExpr->isElidable()) { + if (const auto *MaterializeTemp = + dyn_cast<MaterializeTemporaryExpr>(CtorExpr->getArg(0))) { + return InnerMatcher.matches(*MaterializeTemp->GetTemporaryExpr(), + Finder, Builder); + } + } + } + return InnerMatcher.matches(Node, Finder, Builder); +} + +//----------------------------------------------------------------------------// +// OpenMP handling. +//----------------------------------------------------------------------------// + +/// Matches any ``#pragma omp`` executable directive. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp taskyield +/// \endcode +/// +/// ``ompExecutableDirective()`` matches ``omp parallel``, +/// ``omp parallel default(none)`` and ``omp taskyield``. +extern const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective> + ompExecutableDirective; + +/// Matches standalone OpenMP directives, +/// i.e., directives that can't have a structured block. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// {} +/// #pragma omp taskyield +/// \endcode +/// +/// ``ompExecutableDirective(isStandaloneDirective()))`` matches +/// ``omp taskyield``. +AST_MATCHER(OMPExecutableDirective, isStandaloneDirective) { + return Node.isStandaloneDirective(); +} + +/// Matches the Stmt AST node that is marked as being the structured-block +/// of an OpenMP executable directive. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// {} +/// \endcode +/// +/// ``stmt(isOMPStructuredBlock()))`` matches ``{}``. +AST_MATCHER(Stmt, isOMPStructuredBlock) { return Node.isOMPStructuredBlock(); } + +/// Matches the structured-block of the OpenMP executable directive +/// +/// Prerequisite: the executable directive must not be standalone directive. +/// If it is, it will never match. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// ; +/// #pragma omp parallel +/// {} +/// \endcode +/// +/// ``ompExecutableDirective(hasStructuredBlock(nullStmt()))`` will match ``;`` +AST_MATCHER_P(OMPExecutableDirective, hasStructuredBlock, + internal::Matcher<Stmt>, InnerMatcher) { + if (Node.isStandaloneDirective()) + return false; // Standalone directives have no structured blocks. + return InnerMatcher.matches(*Node.getStructuredBlock(), Finder, Builder); +} + +/// Matches any clause in an OpenMP directive. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// \endcode +/// +/// ``ompExecutableDirective(hasAnyClause(anything()))`` matches +/// ``omp parallel default(none)``. +AST_MATCHER_P(OMPExecutableDirective, hasAnyClause, + internal::Matcher<OMPClause>, InnerMatcher) { + ArrayRef<OMPClause *> Clauses = Node.clauses(); + return matchesFirstInPointerRange(InnerMatcher, Clauses.begin(), + Clauses.end(), Finder, Builder); +} + +/// Matches OpenMP ``default`` clause. +/// +/// Given +/// +/// \code +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// #pragma omp parallel +/// \endcode +/// +/// ``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause> + ompDefaultClause; + +/// Matches if the OpenMP ``default`` clause has ``none`` kind specified. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// \endcode +/// +/// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. +AST_MATCHER(OMPDefaultClause, isNoneKind) { + return Node.getDefaultKind() == OMPC_DEFAULT_none; +} + +/// Matches if the OpenMP ``default`` clause has ``shared`` kind specified. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// \endcode +/// +/// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. +AST_MATCHER(OMPDefaultClause, isSharedKind) { + return Node.getDefaultKind() == OMPC_DEFAULT_shared; +} + +/// Matches if the OpenMP directive is allowed to contain the specified OpenMP +/// clause kind. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel for +/// #pragma omp for +/// \endcode +/// +/// `ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches +/// ``omp parallel`` and ``omp parallel for``. +/// +/// If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter +/// should be passed as a quoted string. e.g., +/// ``isAllowedToContainClauseKind("OMPC_default").`` +AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind, + OpenMPClauseKind, CKind) { + return isAllowedClauseForDirective(Node.getDirectiveKind(), CKind); +} + +//----------------------------------------------------------------------------// +// End OpenMP handling. +//----------------------------------------------------------------------------// + } // namespace ast_matchers } // namespace clang diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h index 34851a907e0d..b1bb0bfa3218 100644 --- a/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -1,9 +1,8 @@ //===- ASTMatchersInternal.h - Structural query framework -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -951,15 +950,6 @@ const bool IsBaseType<T>::value; /// all nodes, as all nodes have ancestors. class ASTMatchFinder { public: - /// Defines how we descend a level in the AST when we pass - /// through expressions. - enum TraversalKind { - /// Will traverse any child nodes. - TK_AsIs, - - /// Will not traverse implicit casts and parentheses. - TK_IgnoreImplicitCastsAndParentheses - }; /// Defines how bindings are processed on recursive matches. enum BindKind { @@ -990,11 +980,9 @@ public: BoundNodesTreeBuilder *Builder) = 0; template <typename T> - bool matchesChildOf(const T &Node, - const DynTypedMatcher &Matcher, + bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, - TraversalKind Traverse, - BindKind Bind) { + ast_type_traits::TraversalKind Traverse, BindKind Bind) { static_assert(std::is_base_of<Decl, T>::value || std::is_base_of<Stmt, T>::value || std::is_base_of<NestedNameSpecifier, T>::value || @@ -1043,7 +1031,7 @@ protected: virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, - TraversalKind Traverse, + ast_type_traits::TraversalKind Traverse, BindKind Bind) = 0; virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node, @@ -1291,7 +1279,7 @@ public: bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { return Finder->matchesChildOf(Node, this->InnerMatcher, Builder, - ASTMatchFinder::TK_AsIs, + ast_type_traits::TraversalKind::TK_AsIs, ASTMatchFinder::BK_First); } }; @@ -1314,7 +1302,7 @@ class ForEachMatcher : public WrapperMatcherInterface<T> { BoundNodesTreeBuilder* Builder) const override { return Finder->matchesChildOf( Node, this->InnerMatcher, Builder, - ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, + ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses, ASTMatchFinder::BK_All); } }; @@ -1548,8 +1536,7 @@ inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode( /// given matchers, if SourceT can be dynamically casted into TargetT. /// /// For example: -/// const VariadicDynCastAllOfMatcher< -/// Decl, CXXRecordDecl> record; +/// const VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> record; /// Creates a functor record(...) that creates a Matcher<Decl> given /// a variable number of arguments of type Matcher<CXXRecordDecl>. /// The returned matcher matches if the given Decl can by dynamically diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h index 3080f86699b5..1d96ba6231cf 100644 --- a/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -1,9 +1,8 @@ //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h index ccd9590f4bb4..7dd304797c4f 100644 --- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h +++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h @@ -1,9 +1,8 @@ //===--- Diagnostics.h - Helper class for error diagnostics -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h index 136265d32847..15e0aa7ecd27 100644 --- a/include/clang/ASTMatchers/Dynamic/Parser.h +++ b/include/clang/ASTMatchers/Dynamic/Parser.h @@ -1,9 +1,8 @@ //===- Parser.h - Matcher expression parser ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h index ad8628b4b0d9..215206b2f50c 100644 --- a/include/clang/ASTMatchers/Dynamic/Registry.h +++ b/include/clang/ASTMatchers/Dynamic/Registry.h @@ -1,9 +1,8 @@ //===- Registry.h - Matcher registry ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h index 45ac3cadf685..511472a4157c 100644 --- a/include/clang/ASTMatchers/Dynamic/VariantValue.h +++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -1,8 +1,7 @@ //===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/ -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h index 49da6815ace9..16c0a7af0504 100644 --- a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h +++ b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h @@ -1,9 +1,8 @@ //===- CFGReachabilityAnalysis.h - Basic reachability analysis --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h index 5a70989e5087..dec1ae3b2b4b 100644 --- a/include/clang/Analysis/Analyses/Consumed.h +++ b/include/clang/Analysis/Analyses/Consumed.h @@ -1,9 +1,8 @@ //===- Consumed.h -----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h index 021e98dcd885..061c98137da2 100644 --- a/include/clang/Analysis/Analyses/Dominators.h +++ b/include/clang/Analysis/Analyses/Dominators.h @@ -1,9 +1,8 @@ //- Dominators.h - Implementation of dominators tree for Clang CFG -*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,6 +18,7 @@ #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/iterator.h" +#include "llvm/Support/GenericIteratedDominanceFrontier.h" #include "llvm/Support/GenericDomTree.h" #include "llvm/Support/GenericDomTreeConstruction.h" #include "llvm/Support/raw_ostream.h" @@ -37,132 +37,319 @@ namespace clang { using DomTreeNode = llvm::DomTreeNodeBase<CFGBlock>; -/// Concrete subclass of DominatorTreeBase for Clang -/// This class implements the dominators tree functionality given a Clang CFG. -/// -class DominatorTree : public ManagedAnalysis { +/// Dominator tree builder for Clang's CFG based on llvm::DominatorTreeBase. +template <bool IsPostDom> +class CFGDominatorTreeImpl : public ManagedAnalysis { virtual void anchor(); public: - llvm::DomTreeBase<CFGBlock> *DT; + using DominatorTreeBase = llvm::DominatorTreeBase<CFGBlock, IsPostDom>; - DominatorTree() { - DT = new llvm::DomTreeBase<CFGBlock>(); + CFGDominatorTreeImpl() = default; + + CFGDominatorTreeImpl(CFG *cfg) { + buildDominatorTree(cfg); } - ~DominatorTree() override { delete DT; } + ~CFGDominatorTreeImpl() override = default; + + DominatorTreeBase &getBase() { return DT; } - llvm::DomTreeBase<CFGBlock>& getBase() { return *DT; } + CFG *getCFG() { return cfg; } - /// This method returns the root CFGBlock of the dominators tree. + /// \returns the root CFGBlock of the dominators tree. CFGBlock *getRoot() const { - return DT->getRoot(); + return DT.getRoot(); } - /// This method returns the root DomTreeNode, which is the wrapper - /// for CFGBlock. - DomTreeNode *getRootNode() const { - return DT->getRootNode(); + /// \returns the root DomTreeNode, which is the wrapper for CFGBlock. + DomTreeNode *getRootNode() { + return DT.getRootNode(); } - /// This method compares two dominator trees. - /// The method returns false if the other dominator tree matches this - /// dominator tree, otherwise returns true. - bool compare(DominatorTree &Other) const { + /// Compares two dominator trees. + /// \returns false if the other dominator tree matches this dominator tree, + /// false otherwise. + bool compare(CFGDominatorTreeImpl &Other) const { DomTreeNode *R = getRootNode(); DomTreeNode *OtherR = Other.getRootNode(); if (!R || !OtherR || R->getBlock() != OtherR->getBlock()) return true; - if (DT->compare(Other.getBase())) + if (DT.compare(Other.getBase())) return true; return false; } - /// This method builds the dominator tree for a given CFG - /// The CFG information is passed via AnalysisDeclContext - void buildDominatorTree(AnalysisDeclContext &AC) { - cfg = AC.getCFG(); - DT->recalculate(*cfg); + /// Builds the dominator tree for a given CFG. + void buildDominatorTree(CFG *cfg) { + assert(cfg); + this->cfg = cfg; + DT.recalculate(*cfg); } - /// This method dumps immediate dominators for each block, - /// mainly used for debug purposes. + /// Dumps immediate dominators for each block. void dump() { - llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n"; + llvm::errs() << "Immediate " << (IsPostDom ? "post " : "") + << "dominance tree (Node#,IDom#):\n"; for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { - if(DT->getNode(*I)->getIDom()) + + assert(*I && + "LLVM's Dominator tree builder uses nullpointers to signify the " + "virtual root!"); + + DomTreeNode *IDom = DT.getNode(*I)->getIDom(); + if (IDom && IDom->getBlock()) llvm::errs() << "(" << (*I)->getBlockID() << "," - << DT->getNode(*I)->getIDom()->getBlock()->getBlockID() + << IDom->getBlock()->getBlockID() << ")\n"; - else llvm::errs() << "(" << (*I)->getBlockID() - << "," << (*I)->getBlockID() << ")\n"; + else { + bool IsEntryBlock = *I == &(*I)->getParent()->getEntry(); + bool IsExitBlock = *I == &(*I)->getParent()->getExit(); + + bool IsDomTreeRoot = !IDom && !IsPostDom && IsEntryBlock; + bool IsPostDomTreeRoot = + IDom && !IDom->getBlock() && IsPostDom && IsExitBlock; + + assert((IsDomTreeRoot || IsPostDomTreeRoot) && + "If the immediate dominator node is nullptr, the CFG block " + "should be the exit point (since it's the root of the dominator " + "tree), or if the CFG block it refers to is a nullpointer, it " + "must be the entry block (since it's the root of the post " + "dominator tree)"); + + (void)IsDomTreeRoot; + (void)IsPostDomTreeRoot; + + llvm::errs() << "(" << (*I)->getBlockID() + << "," << (*I)->getBlockID() << ")\n"; + } } } - /// This method tests if one CFGBlock dominates the other. - /// The method return true if A dominates B, false otherwise. + /// Tests whether \p A dominates \p B. /// Note a block always dominates itself. bool dominates(const CFGBlock *A, const CFGBlock *B) const { - return DT->dominates(A, B); + return DT.dominates(A, B); } - /// This method tests if one CFGBlock properly dominates the other. - /// The method return true if A properly dominates B, false otherwise. + /// Tests whether \p A properly dominates \p B. + /// \returns false if \p A is the same block as \p B, otherwise whether A + /// dominates B. bool properlyDominates(const CFGBlock *A, const CFGBlock *B) const { - return DT->properlyDominates(A, B); + return DT.properlyDominates(A, B); } - /// This method finds the nearest common dominator CFG block - /// for CFG block A and B. If there is no such block then return NULL. + /// \returns the nearest common dominator CFG block for CFG block \p A and \p + /// B. If there is no such block then return NULL. CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) { - return DT->findNearestCommonDominator(A, B); + return DT.findNearestCommonDominator(A, B); } const CFGBlock *findNearestCommonDominator(const CFGBlock *A, const CFGBlock *B) { - return DT->findNearestCommonDominator(A, B); + return DT.findNearestCommonDominator(A, B); } - /// This method is used to update the dominator - /// tree information when a node's immediate dominator changes. + /// Update the dominator tree information when a node's immediate dominator + /// changes. void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) { - DT->changeImmediateDominator(N, NewIDom); + DT.changeImmediateDominator(N, NewIDom); } - /// This method tests if the given CFGBlock can be reachable from root. - /// Returns true if reachable, false otherwise. + /// Tests whether \p A is reachable from the entry block. bool isReachableFromEntry(const CFGBlock *A) { - return DT->isReachableFromEntry(A); + return DT.isReachableFromEntry(A); } - /// This method releases the memory held by the dominator tree. + /// Releases the memory held by the dominator tree. virtual void releaseMemory() { - DT->releaseMemory(); + DT.releaseMemory(); } - /// This method converts the dominator tree to human readable form. + /// Converts the dominator tree to human readable form. virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const { - DT->print(OS); + DT.print(OS); } private: CFG *cfg; + DominatorTreeBase DT; +}; + +using CFGDomTree = CFGDominatorTreeImpl</*IsPostDom*/ false>; +using CFGPostDomTree = CFGDominatorTreeImpl</*IsPostDom*/ true>; + +template<> void CFGDominatorTreeImpl<true>::anchor(); +template<> void CFGDominatorTreeImpl<false>::anchor(); + +} // end of namespace clang + +namespace llvm { +namespace IDFCalculatorDetail { + +/// Specialize ChildrenGetterTy to skip nullpointer successors. +template <bool IsPostDom> +struct ChildrenGetterTy<clang::CFGBlock, IsPostDom> { + using NodeRef = typename GraphTraits<clang::CFGBlock>::NodeRef; + using ChildrenTy = SmallVector<NodeRef, 8>; + + ChildrenTy get(const NodeRef &N) { + using OrderedNodeTy = + typename IDFCalculatorBase<clang::CFGBlock, IsPostDom>::OrderedNodeTy; + + auto Children = children<OrderedNodeTy>(N); + ChildrenTy Ret{Children.begin(), Children.end()}; + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; + } +}; + +} // end of namespace IDFCalculatorDetail +} // end of namespace llvm + +namespace clang { + +class ControlDependencyCalculator : public ManagedAnalysis { + using IDFCalculator = llvm::IDFCalculatorBase<CFGBlock, /*IsPostDom=*/true>; + using CFGBlockVector = llvm::SmallVector<CFGBlock *, 4>; + using CFGBlockSet = llvm::SmallPtrSet<CFGBlock *, 4>; + + CFGPostDomTree PostDomTree; + IDFCalculator IDFCalc; + + llvm::DenseMap<CFGBlock *, CFGBlockVector> ControlDepenencyMap; + +public: + ControlDependencyCalculator(CFG *cfg) + : PostDomTree(cfg), IDFCalc(PostDomTree.getBase()) {} + + const CFGPostDomTree &getCFGPostDomTree() const { return PostDomTree; } + + // Lazily retrieves the set of control dependencies to \p A. + const CFGBlockVector &getControlDependencies(CFGBlock *A) { + auto It = ControlDepenencyMap.find(A); + if (It == ControlDepenencyMap.end()) { + CFGBlockSet DefiningBlock = {A}; + IDFCalc.setDefiningBlocks(DefiningBlock); + + CFGBlockVector ControlDependencies; + IDFCalc.calculate(ControlDependencies); + + It = ControlDepenencyMap.insert({A, ControlDependencies}).first; + } + + assert(It != ControlDepenencyMap.end()); + return It->second; + } + + /// Whether \p A is control dependent on \p B. + bool isControlDependent(CFGBlock *A, CFGBlock *B) { + return llvm::is_contained(getControlDependencies(A), B); + } + + // Dumps immediate control dependencies for each block. + LLVM_DUMP_METHOD void dump() { + CFG *cfg = PostDomTree.getCFG(); + llvm::errs() << "Control dependencies (Node#,Dependency#):\n"; + for (CFGBlock *BB : *cfg) { + + assert(BB && + "LLVM's Dominator tree builder uses nullpointers to signify the " + "virtual root!"); + + for (CFGBlock *isControlDependency : getControlDependencies(BB)) + llvm::errs() << "(" << BB->getBlockID() + << "," + << isControlDependency->getBlockID() + << ")\n"; + } + } }; } // namespace clang +namespace llvm { + +/// Clang's CFG contains nullpointers for unreachable succesors, e.g. when an +/// if statement's condition is always false, it's 'then' branch is represented +/// with a nullptr. This however will result in a nullpointer derefernece for +/// dominator tree calculation. +/// +/// To circumvent this, let's just crudely specialize the children getters +/// used in LLVM's dominator tree builder. +namespace DomTreeBuilder { + +using ClangCFGDomChildrenGetter = +SemiNCAInfo<clang::CFGDomTree::DominatorTreeBase>::ChildrenGetter< + /*Inverse=*/false>; + +template <> +template <> +inline ClangCFGDomChildrenGetter::ResultTy ClangCFGDomChildrenGetter::Get( + clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/false>) { + auto RChildren = reverse(children<NodePtr>(N)); + ResultTy Ret(RChildren.begin(), RChildren.end()); + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; +} + +using ClangCFGDomReverseChildrenGetter = +SemiNCAInfo<clang::CFGDomTree::DominatorTreeBase>::ChildrenGetter< + /*Inverse=*/true>; + +template <> +template <> +inline ClangCFGDomReverseChildrenGetter::ResultTy +ClangCFGDomReverseChildrenGetter::Get( + clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/true>) { + auto IChildren = inverse_children<NodePtr>(N); + ResultTy Ret(IChildren.begin(), IChildren.end()); + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; +} + +using ClangCFGPostDomChildrenGetter = +SemiNCAInfo<clang::CFGPostDomTree::DominatorTreeBase>::ChildrenGetter< + /*Inverse=*/false>; + +template <> +template <> +inline ClangCFGPostDomChildrenGetter::ResultTy +ClangCFGPostDomChildrenGetter::Get( + clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/false>) { + auto RChildren = reverse(children<NodePtr>(N)); + ResultTy Ret(RChildren.begin(), RChildren.end()); + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; +} + +using ClangCFGPostDomReverseChildrenGetter = +SemiNCAInfo<clang::CFGPostDomTree::DominatorTreeBase>::ChildrenGetter< + /*Inverse=*/true>; + +template <> +template <> +inline ClangCFGPostDomReverseChildrenGetter::ResultTy +ClangCFGPostDomReverseChildrenGetter::Get( + clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/true>) { + auto IChildren = inverse_children<NodePtr>(N); + ResultTy Ret(IChildren.begin(), IChildren.end()); + Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end()); + return Ret; +} + +} // end of namespace DomTreeBuilder + //===------------------------------------- /// DominatorTree GraphTraits specialization so the DominatorTree can be /// iterable by generic graph iterators. /// -namespace llvm { - -template <> struct GraphTraits< ::clang::DomTreeNode* > { +template <> struct GraphTraits<clang::DomTreeNode *> { using NodeRef = ::clang::DomTreeNode *; using ChildIteratorType = ::clang::DomTreeNode::iterator; @@ -182,17 +369,17 @@ template <> struct GraphTraits< ::clang::DomTreeNode* > { } }; -template <> struct GraphTraits< ::clang::DominatorTree* > - : public GraphTraits< ::clang::DomTreeNode* > { - static NodeRef getEntryNode(::clang::DominatorTree *DT) { +template <> struct GraphTraits<clang::CFGDomTree *> + : public GraphTraits<clang::DomTreeNode *> { + static NodeRef getEntryNode(clang::CFGDomTree *DT) { return DT->getRootNode(); } - static nodes_iterator nodes_begin(::clang::DominatorTree *N) { + static nodes_iterator nodes_begin(clang::CFGDomTree *N) { return nodes_iterator(df_begin(getEntryNode(N))); } - static nodes_iterator nodes_end(::clang::DominatorTree *N) { + static nodes_iterator nodes_end(clang::CFGDomTree *N) { return nodes_iterator(df_end(getEntryNode(N))); } }; diff --git a/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h index edc6e00f1d00..9397c5df78ab 100644 --- a/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h +++ b/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h @@ -1,9 +1,8 @@ //===---------- ExprMutationAnalyzer.h ------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h index 114597661a67..a46c35ee5b30 100644 --- a/include/clang/Analysis/Analyses/LiveVariables.h +++ b/include/clang/Analysis/Analyses/LiveVariables.h @@ -1,9 +1,8 @@ //===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h index 7df3dc66c311..08fda0982df4 100644 --- a/include/clang/Analysis/Analyses/PostOrderCFGView.h +++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h @@ -1,9 +1,8 @@ //===- PostOrderCFGView.h - Post order view of CFG blocks -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h index d79f1b03df7b..514b9458d331 100644 --- a/include/clang/Analysis/Analyses/ReachableCode.h +++ b/include/clang/Analysis/Analyses/ReachableCode.h @@ -1,9 +1,8 @@ //===- ReachableCode.h -----------------------------------------*- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h index c72db6f2b24b..18659aa4e5bb 100644 --- a/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/include/clang/Analysis/Analyses/ThreadSafety.h @@ -1,9 +1,8 @@ //===- ThreadSafety.h -------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -120,18 +119,22 @@ public: /// \param Kind -- the capability's name parameter (role, mutex, etc). /// \param Expected -- the kind of lock expected. /// \param Received -- the kind of lock received. - /// \param Loc -- The SourceLocation of the Unlock. + /// \param LocLocked -- The SourceLocation of the Lock. + /// \param LocUnlock -- The SourceLocation of the Unlock. virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName, LockKind Expected, LockKind Received, - SourceLocation Loc) {} + SourceLocation LocLocked, + SourceLocation LocUnlock) {} /// Warn about lock function calls for locks which are already held. /// \param Kind -- the capability's name parameter (role, mutex, etc). /// \param LockName -- A StringRef name for the lock expression, to be printed /// in the error message. - /// \param Loc -- The location of the second lock expression. + /// \param LocLocked -- The location of the first lock expression. + /// \param LocDoubleLock -- The location of the second lock expression. virtual void handleDoubleLock(StringRef Kind, Name LockName, - SourceLocation Loc) {} + SourceLocation LocLocked, + SourceLocation LocDoubleLock) {} /// Warn about situations where a mutex is sometimes held and sometimes not. /// The three situations are: diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 422a1db7f6fd..4a58fe870944 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -1,9 +1,8 @@ //===- ThreadSafetyCommon.h -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h index 2508af1af107..8d938c1b23c0 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h @@ -1,9 +1,8 @@ //===- ThreadSafetyLogical.h -----------------------------------*- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // This file defines a representation for logical expressions with SExpr leaves diff --git a/include/clang/Analysis/Analyses/ThreadSafetyOps.def b/include/clang/Analysis/Analyses/ThreadSafetyOps.def index 0d2458b0c893..fc4881a7f0fd 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyOps.def +++ b/include/clang/Analysis/Analyses/ThreadSafetyOps.def @@ -1,9 +1,8 @@ //===- ThreadSafetyTIL.h ---------------------------------------*- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h index c106a9a42731..c26d2ed99dd2 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h @@ -1,9 +1,8 @@ //===- ThreadSafetyTIL.h ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT in the llvm repository for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -1605,7 +1604,7 @@ public: /// Return the index of BB, or Predecessors.size if BB is not a predecessor. unsigned findPredecessorIndex(const BasicBlock *BB) const { - auto I = std::find(Predecessors.cbegin(), Predecessors.cend(), BB); + auto I = llvm::find(Predecessors, BB); return std::distance(Predecessors.cbegin(), I); } diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h index 32aadf526587..e81c00d3dddb 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h @@ -1,9 +1,8 @@ //===- ThreadSafetyTraverse.h -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h index 16583939d542..e3b6e61d3026 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h @@ -1,9 +1,8 @@ //===- ThreadSafetyUtil.h ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h index 79d89e0633fd..479be1fec048 100644 --- a/include/clang/Analysis/Analyses/UninitializedValues.h +++ b/include/clang/Analysis/Analyses/UninitializedValues.h @@ -1,9 +1,8 @@ //=- UninitializedValues.h - Finding uses of uninitialized values -*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/AnalysisDeclContext.h b/include/clang/Analysis/AnalysisDeclContext.h index 490d2ce346be..1961d571e9e1 100644 --- a/include/clang/Analysis/AnalysisDeclContext.h +++ b/include/clang/Analysis/AnalysisDeclContext.h @@ -1,9 +1,8 @@ // AnalysisDeclContext.h - Analysis context for Path Sens analysis -*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -275,11 +274,17 @@ public: virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; void dumpStack( - raw_ostream &OS, StringRef Indent = {}, const char *NL = "\n", - const char *Sep = "", + raw_ostream &Out, const char *NL = "\n", std::function<void(const LocationContext *)> printMoreInfoPerContext = [](const LocationContext *) {}) const; - void dumpStack() const; + + void printJson( + raw_ostream &Out, const char *NL = "\n", unsigned int Space = 0, + bool IsDot = false, + std::function<void(const LocationContext *)> printMoreInfoPerContext = + [](const LocationContext *) {}) const; + + void dump() const; public: static void ProfileCommon(llvm::FoldingSetNodeID &ID, @@ -460,6 +465,7 @@ public: bool addCXXNewAllocator = true, bool addRichCXXConstructors = true, bool markElidedCXXConstructors = true, + bool addVirtualBaseBranches = true, CodeInjector *injector = nullptr); AnalysisDeclContext *getContext(const Decl *D); diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h index 087ffdcde90c..fd5f2ffe6483 100644 --- a/include/clang/Analysis/AnalysisDiagnostic.h +++ b/include/clang/Analysis/AnalysisDiagnostic.h @@ -1,9 +1,8 @@ //===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Analysis/AnyCall.h b/include/clang/Analysis/AnyCall.h new file mode 100644 index 000000000000..97a94d299e64 --- /dev/null +++ b/include/clang/Analysis/AnyCall.h @@ -0,0 +1,209 @@ +//=== AnyCall.h - Abstraction over different callables --------*- C++ -*--// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// A utility class for performing generic operations over different callables. +// +//===----------------------------------------------------------------------===// +// +#ifndef LLVM_CLANG_ANALYSIS_ANY_CALL_H +#define LLVM_CLANG_ANALYSIS_ANY_CALL_H + +#include "clang/AST/Decl.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" + +namespace clang { + +/// An instance of this class corresponds to a call. +/// It might be a syntactically-concrete call, done as a part of evaluating an +/// expression, or it may be an abstract callee with no associated expression. +class AnyCall { +public: + enum Kind { + /// A function, function pointer, or a C++ method call + Function, + + /// A call to an Objective-C method + ObjCMethod, + + /// A call to an Objective-C block + Block, + + /// An implicit C++ destructor call (called implicitly + /// or by operator 'delete') + Destructor, + + /// An implicit or explicit C++ constructor call + Constructor, + + /// A C++ allocation function call (operator `new`), via C++ new-expression + Allocator, + + /// A C++ deallocation function call (operator `delete`), via C++ + /// delete-expression + Deallocator + }; + +private: + /// Either expression or declaration (but not both at the same time) + /// can be null. + + /// Call expression, is null when is not known (then declaration is non-null), + /// or for implicit destructor calls (when no expression exists.) + const Expr *E = nullptr; + + /// Corresponds to a statically known declaration of the called function, + /// or null if it is not known (e.g. for a function pointer). + const Decl *D = nullptr; + Kind K; + +public: + AnyCall(const CallExpr *CE) : E(CE) { + D = CE->getCalleeDecl(); + K = (CE->getCallee()->getType()->getAs<BlockPointerType>()) ? Block + : Function; + if (D && ((K == Function && !isa<FunctionDecl>(D)) || + (K == Block && !isa<BlockDecl>(D)))) + D = nullptr; + } + + AnyCall(const ObjCMessageExpr *ME) + : E(ME), D(ME->getMethodDecl()), K(ObjCMethod) {} + + AnyCall(const CXXNewExpr *NE) + : E(NE), D(NE->getOperatorNew()), K(Allocator) {} + + AnyCall(const CXXDeleteExpr *NE) + : E(NE), D(NE->getOperatorDelete()), K(Deallocator) {} + + AnyCall(const CXXConstructExpr *NE) + : E(NE), D(NE->getConstructor()), K(Constructor) {} + + AnyCall(const CXXDestructorDecl *D) : E(nullptr), D(D), K(Destructor) {} + + AnyCall(const CXXConstructorDecl *D) : E(nullptr), D(D), K(Constructor) {} + + AnyCall(const ObjCMethodDecl *D) : E(nullptr), D(D), K(ObjCMethod) {} + + AnyCall(const FunctionDecl *D) : E(nullptr), D(D) { + if (isa<CXXConstructorDecl>(D)) { + K = Constructor; + } else if (isa <CXXDestructorDecl>(D)) { + K = Destructor; + } else { + K = Function; + } + + } + + /// If {@code E} is a generic call (to ObjC method /function/block/etc), + /// return a constructed {@code AnyCall} object. Return None otherwise. + static Optional<AnyCall> forExpr(const Expr *E) { + if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) { + return AnyCall(ME); + } else if (const auto *CE = dyn_cast<CallExpr>(E)) { + return AnyCall(CE); + } else if (const auto *CXNE = dyn_cast<CXXNewExpr>(E)) { + return AnyCall(CXNE); + } else if (const auto *CXDE = dyn_cast<CXXDeleteExpr>(E)) { + return AnyCall(CXDE); + } else if (const auto *CXCE = dyn_cast<CXXConstructExpr>(E)) { + return AnyCall(CXCE); + } else { + return None; + } + } + + /// If {@code D} is a callable (Objective-C method or a function), return + /// a constructed {@code AnyCall} object. Return None otherwise. + // FIXME: block support. + static Optional<AnyCall> forDecl(const Decl *D) { + if (const auto *FD = dyn_cast<FunctionDecl>(D)) { + return AnyCall(FD); + } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) { + return AnyCall(MD); + } + return None; + } + + /// \returns formal parameters for direct calls (including virtual calls) + ArrayRef<ParmVarDecl *> parameters() const { + if (!D) + return None; + + if (const auto *FD = dyn_cast<FunctionDecl>(D)) { + return FD->parameters(); + } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) { + return MD->parameters(); + } else if (const auto *BD = dyn_cast<BlockDecl>(D)) { + return BD->parameters(); + } else { + return None; + } + } + + using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator; + param_const_iterator param_begin() const { return parameters().begin(); } + param_const_iterator param_end() const { return parameters().end(); } + size_t param_size() const { return parameters().size(); } + bool param_empty() const { return parameters().empty(); } + + QualType getReturnType(ASTContext &Ctx) const { + switch (K) { + case Function: + if (E) + return cast<CallExpr>(E)->getCallReturnType(Ctx); + return cast<FunctionDecl>(D)->getReturnType(); + case ObjCMethod: + if (E) + return cast<ObjCMessageExpr>(E)->getCallReturnType(Ctx); + return cast<ObjCMethodDecl>(D)->getReturnType(); + case Block: + // FIXME: BlockDecl does not know its return type, + // hence the asymmetry with the function and method cases above. + return cast<CallExpr>(E)->getCallReturnType(Ctx); + case Destructor: + case Constructor: + case Allocator: + case Deallocator: + return cast<FunctionDecl>(D)->getReturnType(); + } + llvm_unreachable("Unknown AnyCall::Kind"); + } + + /// \returns Function identifier if it is a named declaration, + /// {@code nullptr} otherwise. + const IdentifierInfo *getIdentifier() const { + if (const auto *ND = dyn_cast_or_null<NamedDecl>(D)) + return ND->getIdentifier(); + return nullptr; + } + + const Decl *getDecl() const { + return D; + } + + const Expr *getExpr() const { + return E; + } + + Kind getKind() const { + return K; + } + + void dump() const { + if (E) + E->dump(); + if (D) + D->dump(); + } +}; + +} + +#endif // LLVM_CLANG_ANALYSIS_ANY_CALL_H diff --git a/include/clang/Analysis/BodyFarm.h b/include/clang/Analysis/BodyFarm.h index ff0859bc662d..72607f8839f5 100644 --- a/include/clang/Analysis/BodyFarm.h +++ b/include/clang/Analysis/BodyFarm.h @@ -1,9 +1,8 @@ //== BodyFarm.h - Factory for conjuring up fake bodies -------------*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index bf81d8358a54..277b2292e5ea 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -1,9 +1,8 @@ //===- CFG.h - Classes for representing and building CFGs -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -495,33 +494,51 @@ private: /// Represents CFGBlock terminator statement. /// -/// TemporaryDtorsBranch bit is set to true if the terminator marks a branch -/// in control flow of destructors of temporaries. In this case terminator -/// statement is the same statement that branches control flow in evaluation -/// of matching full expression. class CFGTerminator { - llvm::PointerIntPair<Stmt *, 1> Data; +public: + enum Kind { + /// A branch that corresponds to a statement in the code, + /// such as an if-statement. + StmtBranch, + /// A branch in control flow of destructors of temporaries. In this case + /// terminator statement is the same statement that branches control flow + /// in evaluation of matching full expression. + TemporaryDtorsBranch, + /// A shortcut around virtual base initializers. It gets taken when + /// virtual base classes have already been initialized by the constructor + /// of the most derived class while we're in the base class. + VirtualBaseBranch, + + /// Number of different kinds, for sanity checks. We subtract 1 so that + /// to keep receiving compiler warnings when we don't cover all enum values + /// in a switch. + NumKindsMinusOne = VirtualBaseBranch + }; + +private: + static constexpr int KindBits = 2; + static_assert((1 << KindBits) > NumKindsMinusOne, + "Not enough room for kind!"); + llvm::PointerIntPair<Stmt *, KindBits> Data; public: - CFGTerminator() = default; - CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false) - : Data(S, TemporaryDtorsBranch) {} + CFGTerminator() { assert(!isValid()); } + CFGTerminator(Stmt *S, Kind K = StmtBranch) : Data(S, K) {} + bool isValid() const { return Data.getOpaqueValue() != nullptr; } Stmt *getStmt() { return Data.getPointer(); } const Stmt *getStmt() const { return Data.getPointer(); } + Kind getKind() const { return static_cast<Kind>(Data.getInt()); } - bool isTemporaryDtorsBranch() const { return Data.getInt(); } - - operator Stmt *() { return getStmt(); } - operator const Stmt *() const { return getStmt(); } - - Stmt *operator->() { return getStmt(); } - const Stmt *operator->() const { return getStmt(); } - - Stmt &operator*() { return *getStmt(); } - const Stmt &operator*() const { return *getStmt(); } - - explicit operator bool() const { return getStmt(); } + bool isStmtBranch() const { + return getKind() == StmtBranch; + } + bool isTemporaryDtorsBranch() const { + return getKind() == TemporaryDtorsBranch; + } + bool isVirtualBaseBranch() const { + return getKind() == VirtualBaseBranch; + } }; /// Represents a single basic block in a source-level CFG. @@ -542,11 +559,12 @@ public: /// Successors: the order in the set of successors is NOT arbitrary. We /// currently have the following orderings based on the terminator: /// -/// Terminator Successor Ordering -/// ----------------------------------------------------- -/// if Then Block; Else Block -/// ? operator LHS expression; RHS expression -/// &&, || expression that uses result of && or ||, RHS +/// Terminator | Successor Ordering +/// ------------------|------------------------------------ +/// if | Then Block; Else Block +/// ? operator | LHS expression; RHS expression +/// logical and/or | expression that consumes the op, RHS +/// vbase inits | already handled by the most derived class; not yet /// /// But note that any of that may be NULL in case of optimized-out edges. class CFGBlock { @@ -837,8 +855,18 @@ public: void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; } void setHasNoReturnElement() { HasNoReturnElement = true; } - CFGTerminator getTerminator() { return Terminator; } - const CFGTerminator getTerminator() const { return Terminator; } + CFGTerminator getTerminator() const { return Terminator; } + + Stmt *getTerminatorStmt() { return Terminator.getStmt(); } + const Stmt *getTerminatorStmt() const { return Terminator.getStmt(); } + + /// \returns the last (\c rbegin()) condition, e.g. observe the following code + /// snippet: + /// if (A && B && C) + /// A block would be created for \c A, \c B, and \c C. For the latter, + /// \c getTerminatorStmt() would retrieve the entire condition, rather than + /// C itself, while this method would only return C. + const Expr *getLastCondition() const; Stmt *getTerminatorCondition(bool StripParens = true); @@ -862,7 +890,11 @@ public: void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const; void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO, bool ShowColors) const; + void printTerminator(raw_ostream &OS, const LangOptions &LO) const; + void printTerminatorJson(raw_ostream &Out, const LangOptions &LO, + bool AddQuotes) const; + void printAsOperand(raw_ostream &OS, bool /*PrintType*/) { OS << "BB#" << getBlockID(); } @@ -1027,6 +1059,7 @@ public: bool AddCXXDefaultInitExprInCtors = false; bool AddRichCXXConstructors = false; bool MarkElidedCXXConstructors = false; + bool AddVirtualBaseBranches = false; BuildOptions() = default; @@ -1173,6 +1206,12 @@ public: /// implementation needs such an interface. unsigned size() const { return NumBlockIDs; } + /// Returns true if the CFG has no branches. Usually it boils down to the CFG + /// having exactly three blocks (entry, the actual code, exit), but sometimes + /// more blocks appear due to having control flow that can be fully + /// resolved in compile time. + bool isLinear() const; + //===--------------------------------------------------------------------===// // CFG Debugging: Pretty-Printing and Visualization. //===--------------------------------------------------------------------===// @@ -1246,6 +1285,9 @@ template <> struct GraphTraits< ::clang::CFGBlock *> { static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } }; +template <> struct GraphTraits<clang::CFGBlock> + : GraphTraits<clang::CFGBlock *> {}; + template <> struct GraphTraits< const ::clang::CFGBlock *> { using NodeRef = const ::clang::CFGBlock *; using ChildIteratorType = ::clang::CFGBlock::const_succ_iterator; @@ -1255,6 +1297,9 @@ template <> struct GraphTraits< const ::clang::CFGBlock *> { static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } }; +template <> struct GraphTraits<const clang::CFGBlock> + : GraphTraits<clang::CFGBlock *> {}; + template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> { using NodeRef = ::clang::CFGBlock *; using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator; @@ -1267,6 +1312,9 @@ template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> { static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); } }; +template <> struct GraphTraits<Inverse<clang::CFGBlock>> + : GraphTraits<clang::CFGBlock *> {}; + template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> { using NodeRef = const ::clang::CFGBlock *; using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator; @@ -1279,6 +1327,9 @@ template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> { static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); } }; +template <> struct GraphTraits<const Inverse<clang::CFGBlock>> + : GraphTraits<clang::CFGBlock *> {}; + // Traits for: CFG template <> struct GraphTraits< ::clang::CFG* > diff --git a/include/clang/Analysis/CFGStmtMap.h b/include/clang/Analysis/CFGStmtMap.h index 78e637daf379..8cf02372ff0f 100644 --- a/include/clang/Analysis/CFGStmtMap.h +++ b/include/clang/Analysis/CFGStmtMap.h @@ -1,9 +1,8 @@ //===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h index e230930b59e0..49c04490fed2 100644 --- a/include/clang/Analysis/CallGraph.h +++ b/include/clang/Analysis/CallGraph.h @@ -1,9 +1,8 @@ //===- CallGraph.h - AST-based Call graph -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h index fadca137b88d..db827c3a6d6f 100644 --- a/include/clang/Analysis/CloneDetection.h +++ b/include/clang/Analysis/CloneDetection.h @@ -1,9 +1,8 @@ //===--- CloneDetection.h - Finds code clones in an AST ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Analysis/CodeInjector.h b/include/clang/Analysis/CodeInjector.h index 2c87cde996f2..a59dc0a94159 100644 --- a/include/clang/Analysis/CodeInjector.h +++ b/include/clang/Analysis/CodeInjector.h @@ -1,9 +1,8 @@ //===-- CodeInjector.h ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Analysis/ConstructionContext.h b/include/clang/Analysis/ConstructionContext.h index 27c1d5b9f1a5..f1564f9fe740 100644 --- a/include/clang/Analysis/ConstructionContext.h +++ b/include/clang/Analysis/ConstructionContext.h @@ -1,9 +1,8 @@ //===- ConstructionContext.h - CFG constructor information ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/include/clang/Analysis/DomainSpecific/CocoaConventions.h index 9326d1abbac1..8531d17767ba 100644 --- a/include/clang/Analysis/DomainSpecific/CocoaConventions.h +++ b/include/clang/Analysis/DomainSpecific/CocoaConventions.h @@ -1,9 +1,8 @@ //===- CocoaConventions.h - Special handling of Cocoa conventions -*- C++ -*--// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h index e304d83615d4..80d7cb8e03a1 100644 --- a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h +++ b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h @@ -1,9 +1,8 @@ //= ObjCNoReturn.h - Handling of Cocoa APIs known not to return --*- C++ -*---// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/FlowSensitive/DataflowValues.h b/include/clang/Analysis/FlowSensitive/DataflowValues.h index f86b2b0bfea1..709753339eb5 100644 --- a/include/clang/Analysis/FlowSensitive/DataflowValues.h +++ b/include/clang/Analysis/FlowSensitive/DataflowValues.h @@ -1,9 +1,8 @@ //===--- DataflowValues.h - Data structure for dataflow values --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index d78174ecd70e..546224bfd58d 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -1,9 +1,8 @@ //==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -43,12 +42,11 @@ public: virtual ~ProgramPointTag(); virtual StringRef getTagDescription() const = 0; -protected: /// Used to implement 'isKind' in subclasses. - const void *getTagKind() { return TagKind; } + const void *getTagKind() const { return TagKind; } private: - const void *TagKind; + const void *const TagKind; }; class SimpleProgramPointTag : public ProgramPointTag { @@ -215,7 +213,7 @@ public: ID.AddPointer(getTag()); } - void print(StringRef CR, llvm::raw_ostream &Out) const; + void printJson(llvm::raw_ostream &Out, const char *NL = "\n") const; LLVM_DUMP_METHOD void dump() const; @@ -259,7 +257,7 @@ public: } const Stmt *getTerminator() const { - return getBlock()->getTerminator(); + return getBlock()->getTerminatorStmt(); } private: @@ -778,9 +776,6 @@ static bool isEqual(const clang::ProgramPoint &L, }; -template <> -struct isPodLike<clang::ProgramPoint> { static const bool value = true; }; - } // end namespace llvm #endif diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/Analysis/RetainSummaryManager.h index 4fcaa794c17b..6acefb563d8c 100644 --- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h +++ b/include/clang/Analysis/RetainSummaryManager.h @@ -1,9 +1,8 @@ //=== RetainSummaryManager.h - Summaries for reference counting ---*- C++ -*--// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -13,25 +12,21 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER -#define LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER +#ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H +#define LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/ImmutableMap.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ParentMap.h" +#include "clang/Analysis/AnyCall.h" #include "clang/Analysis/SelectorExtras.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "llvm/ADT/STLExtras.h" -//===----------------------------------------------------------------------===// -// Adapters for FoldingSet. -//===----------------------------------------------------------------------===// - using namespace clang; -using namespace ento; namespace clang { namespace ento { @@ -208,40 +203,6 @@ public: } }; -/// Encapsulates the retain count semantics on the arguments, return value, -/// and receiver (if any) of a function/method call. -/// -/// Note that construction of these objects is not highly efficient. That -/// is okay for clients where creating these objects isn't really a bottleneck. -/// The purpose of the API is to provide something simple. The actual -/// static analyzer checker that implements retain/release typestate -/// tracking uses something more efficient. -class CallEffects { - llvm::SmallVector<ArgEffect, 10> Args; - RetEffect Ret; - ArgEffect Receiver; - - CallEffects(const RetEffect &R, - ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj)) - : Ret(R), Receiver(Receiver) {} - -public: - /// Returns the argument effects for a call. - ArrayRef<ArgEffect> getArgs() const { return Args; } - - /// Returns the effects on the receiver. - ArgEffect getReceiver() const { return Receiver; } - - /// Returns the effect on the return value. - RetEffect getReturnValue() const { return Ret; } - - /// Return the CallEfect for a given Objective-C method. - static CallEffects getEffect(const ObjCMethodDecl *MD); - - /// Return the CallEfect for a given C/C++ function. - static CallEffects getEffect(const FunctionDecl *FD); -}; - /// A key identifying a summary. class ObjCSummaryKey { IdentifierInfo* II; @@ -263,9 +224,13 @@ public: } // end namespace ento } // end namespace clang +using namespace ento; namespace llvm { +//===----------------------------------------------------------------------===// +// Adapters for FoldingSet. +//===----------------------------------------------------------------------===// template <> struct FoldingSetTrait<ArgEffect> { static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) { ID.AddInteger((unsigned) X.getKind()); @@ -380,6 +345,8 @@ public: /// This is only meaningful if the summary applies to CXXMethodDecl*. ArgEffect getThisEffect() const { return This; } + ArgEffect getDefaultEffect() const { return DefaultArgEffect; } + /// Set the effect of the method on "this". void setThisEffect(ArgEffect e) { This = e; } @@ -654,19 +621,15 @@ class RetainSummaryManager { RetainSummaryTemplate &Template); public: - RetainSummaryManager(ASTContext &ctx, - bool usesARC, - bool trackObjCAndCFObjects, + RetainSummaryManager(ASTContext &ctx, bool trackObjCAndCFObjects, bool trackOSObjects) - : Ctx(ctx), - ARCEnabled(usesARC), - TrackObjCAndCFObjects(trackObjCAndCFObjects), - TrackOSObjects(trackOSObjects), - AF(BPAlloc), - ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC) - : RetEffect::MakeOwned(ObjKind::ObjC)), - ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC) - : RetEffect::MakeOwnedWhenTrackedReceiver()) { + : Ctx(ctx), ARCEnabled((bool)Ctx.getLangOpts().ObjCAutoRefCount), + TrackObjCAndCFObjects(trackObjCAndCFObjects), + TrackOSObjects(trackOSObjects), AF(BPAlloc), + ObjCAllocRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC) + : RetEffect::MakeOwned(ObjKind::ObjC)), + ObjCInitRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC) + : RetEffect::MakeOwnedWhenTrackedReceiver()) { InitializeClassMethodSummaries(); InitializeMethodSummaries(); } @@ -678,6 +641,9 @@ public: // Function returns the first argument. Identity, + // Function returns "this" argument. + IdentityThis, + // Function either returns zero, or the input parameter. IdentityOrZero }; @@ -685,10 +651,24 @@ public: Optional<BehaviorSummary> canEval(const CallExpr *CE, const FunctionDecl *FD, bool &hasTrustedImplementationAnnotation); - bool isTrustedReferenceCountImplementation(const FunctionDecl *FD); + /// \return Whether the type corresponds to a known smart pointer + /// implementation (that is, everything about it is inlineable). + static bool isKnownSmartPointer(QualType QT); + + bool isTrustedReferenceCountImplementation(const Decl *FD); + + const RetainSummary *getSummary(AnyCall C, + bool HasNonZeroCallbackArg=false, + bool IsReceiverUnconsumedSelf=false, + QualType ReceiverType={}); - const RetainSummary *getSummary(const CallEvent &Call, - QualType ReceiverType=QualType()); + RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; } + +private: + + /// getMethodSummary - This version of getMethodSummary is used to query + /// the summary for the current method being analyzed. + const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD); const RetainSummary *getFunctionSummary(const FunctionDecl *FD); @@ -698,32 +678,9 @@ public: ObjCMethodSummariesTy &CachedSummaries); const RetainSummary * - getInstanceMethodSummary(const ObjCMethodCall &M, - QualType ReceiverType); + getInstanceMethodSummary(const ObjCMessageExpr *ME, QualType ReceiverType); - const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) { - assert(!M.isInstanceMessage()); - const ObjCInterfaceDecl *Class = M.getReceiverInterface(); - - return getMethodSummary(M.getSelector(), Class, M.getDecl(), - M.getResultType(), ObjCClassMethodSummaries); - } - - /// getMethodSummary - This version of getMethodSummary is used to query - /// the summary for the current method being analyzed. - const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) { - const ObjCInterfaceDecl *ID = MD->getClassInterface(); - Selector S = MD->getSelector(); - QualType ResultTy = MD->getReturnType(); - - ObjCMethodSummariesTy *CachedSummaries; - if (MD->isInstanceMethod()) - CachedSummaries = &ObjCMethodSummaries; - else - CachedSummaries = &ObjCClassMethodSummaries; - - return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries); - } + const RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME); const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD, Selector S, QualType RetTy); @@ -738,13 +695,25 @@ public: void updateSummaryFromAnnotations(const RetainSummary *&Summ, const FunctionDecl *FD); + const RetainSummary *updateSummaryForNonZeroCallbackArg(const RetainSummary *S, + AnyCall &C); - void updateSummaryForCall(const RetainSummary *&Summ, - const CallEvent &Call); - - bool isARCEnabled() const { return ARCEnabled; } - - RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; } + /// Special case '[super init];' and '[self init];' + /// + /// Even though calling '[super init]' without assigning the result to self + /// and checking if the parent returns 'nil' is a bad pattern, it is common. + /// Additionally, our Self Init checker already warns about it. To avoid + /// overwhelming the user with messages from both checkers, we model the case + /// of '[super init]' in cases when it is not consumed by another expression + /// as if the call preserves the value of 'self'; essentially, assuming it can + /// never fail and return 'nil'. + /// Note, we don't want to just stop tracking the value since we want the + /// RetainCount checker to report leaks and use-after-free if SelfInit checker + /// is turned off. + void updateSummaryForReceiverUnconsumedSelf(const RetainSummary *&S); + + /// Set argument types for arguments which are not doing anything. + void updateSummaryForArgumentTypes(const AnyCall &C, const RetainSummary *&RS); /// Determine whether a declaration {@code D} of correspondent type (return /// type for functions/methods) {@code QT} has any of the given attributes, diff --git a/include/clang/Analysis/SelectorExtras.h b/include/clang/Analysis/SelectorExtras.h index 767063e835e4..d26e9159a937 100644 --- a/include/clang/Analysis/SelectorExtras.h +++ b/include/clang/Analysis/SelectorExtras.h @@ -1,9 +1,8 @@ //=== SelectorExtras.h - Helpers for checkers using selectors -----*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h index 00a7417e20f9..74092dabbfda 100644 --- a/include/clang/Analysis/Support/BumpVector.h +++ b/include/clang/Analysis/Support/BumpVector.h @@ -1,9 +1,8 @@ //===- BumpVector.h - Vector-like ADT that uses bump allocation -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h index dc0e49cded63..2401ffa20494 100644 --- a/include/clang/Basic/ABI.h +++ b/include/clang/Basic/ABI.h @@ -1,9 +1,8 @@ //===----- ABI.h - ABI related declarations ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h index 217fbd763ff2..2cc67474c121 100644 --- a/include/clang/Basic/AddressSpaces.h +++ b/include/clang/Basic/AddressSpaces.h @@ -1,9 +1,8 @@ //===- AddressSpaces.h - Language-specific address spaces -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/AlignedAllocation.h b/include/clang/Basic/AlignedAllocation.h index c995f47a7d74..88410c5cb51f 100644 --- a/include/clang/Basic/AlignedAllocation.h +++ b/include/clang/Basic/AlignedAllocation.h @@ -1,9 +1,8 @@ //===--- AlignedAllocation.h - Aligned Allocation ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h index 6c7f95658970..cc6aa631534a 100644 --- a/include/clang/Basic/AllDiagnostics.h +++ b/include/clang/Basic/AllDiagnostics.h @@ -1,9 +1,8 @@ //===--- AllDiagnostics.h - Aggregate Diagnostic headers --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 1fe1dd39948a..d39b16e62b7f 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -1,9 +1,8 @@ //==--- Attr.td - attribute definitions -----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -15,8 +14,11 @@ class DocumentationCategory<string name> { } def DocCatFunction : DocumentationCategory<"Function Attributes">; def DocCatVariable : DocumentationCategory<"Variable Attributes">; +def DocCatField : DocumentationCategory<"Field Attributes">; def DocCatType : DocumentationCategory<"Type Attributes">; def DocCatStmt : DocumentationCategory<"Statement Attributes">; +def DocCatDecl : DocumentationCategory<"Declaration Attributes">; + // Attributes listed under the Undocumented category do not generate any public // documentation. Ideally, this category should be used for internal-only // attributes which contain no spellings. @@ -103,13 +105,6 @@ def ObjCInstanceMethod : SubsetSubject<ObjCMethod, [{S->isInstanceMethod()}], "Objective-C instance methods">; -def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod, - [{S->getMethodFamily() == OMF_init && - (isa<ObjCInterfaceDecl>(S->getDeclContext()) || - (isa<ObjCCategoryDecl>(S->getDeclContext()) && - cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}], - "init methods of interface or class extension declarations">; - def Struct : SubsetSubject<Record, [{!S->isUnion()}], "structs">; @@ -190,6 +185,9 @@ class VariadicIdentifierArgument<string name> : Argument<name, 1>; // Like VariadicUnsignedArgument except values are ParamIdx. class VariadicParamIdxArgument<string name> : Argument<name, 1>; +// A list of identifiers matching parameters or ParamIdx indices. +class VariadicParamOrParamIdxArgument<string name> : Argument<name, 1>; + // Like VariadicParamIdxArgument but for a single function parameter index. class ParamIdxArgument<string name, bit opt = 0> : Argument<name, opt>; @@ -287,20 +285,29 @@ class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag, string CustomDiag = customDiag; } -class LangOpt<string name, bit negated = 0> { +class LangOpt<string name, code customCode = [{}]> { string Name = name; - bit Negated = negated; + + // A custom predicate, written as an expression evaluated in a context with + // "LangOpts" bound. + code CustomCode = customCode; } def MicrosoftExt : LangOpt<"MicrosoftExt">; def Borland : LangOpt<"Borland">; def CUDA : LangOpt<"CUDA">; -def COnly : LangOpt<"CPlusPlus", 1>; +def HIP : LangOpt<"HIP">; +def COnly : LangOpt<"COnly", "!LangOpts.CPlusPlus">; def CPlusPlus : LangOpt<"CPlusPlus">; def OpenCL : LangOpt<"OpenCL">; def RenderScript : LangOpt<"RenderScript">; def ObjC : LangOpt<"ObjC">; def BlocksSupported : LangOpt<"Blocks">; def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">; +def ObjCNonFragileRuntime : LangOpt<"ObjCNonFragileRuntime", + "LangOpts.ObjCRuntime.allowsClassStubs()">; + +// Language option for CMSE extensions +def Cmse : LangOpt<"Cmse">; // Defines targets for target-specific attributes. Empty lists are unchecked. class TargetSpec { @@ -310,12 +317,14 @@ class TargetSpec { // Specifies Operating Systems for which the target applies, based off the // OSType enumeration in Triple.h list<string> OSes; - // Specifies the C++ ABIs for which the target applies, based off the - // TargetCXXABI::Kind in TargetCXXABI.h. - list<string> CXXABIs; // Specifies Object Formats for which the target applies, based off the // ObjectFormatType enumeration in Triple.h list<string> ObjectFormats; + // A custom predicate, written as an expression evaluated in a context + // with the following declarations in scope: + // const clang::TargetInfo &Target; + // const llvm::Triple &T = Target.getTriple(); + code CustomCode = [{}]; } class TargetArch<list<string> arches> : TargetSpec { @@ -329,11 +338,15 @@ def TargetMSP430 : TargetArch<["msp430"]>; def TargetRISCV : TargetArch<["riscv32", "riscv64"]>; def TargetX86 : TargetArch<["x86"]>; def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; +def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>; def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { let OSes = ["Win32"]; } +def TargetItaniumCXXABI : TargetSpec { + let CustomCode = [{ Target.getCXXABI().isItaniumFamily() }]; +} def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { - let CXXABIs = ["Microsoft"]; + let CustomCode = [{ Target.getCXXABI().isMicrosoft() }]; } def TargetELF : TargetSpec { let ObjectFormats = ["ELF"]; @@ -421,6 +434,10 @@ def SubjectMatcherForObjCCategory : AttrSubjectMatcherRule<"objc_category", [ObjCCategory]> { let LangOpts = [ObjC]; } +def SubjectMatcherForObjCImplementation : + AttrSubjectMatcherRule<"objc_implementation", [ObjCImpl]> { + let LangOpts = [ObjC]; +} def SubjectMatcherForObjCMethod : AttrSubjectMatcherRule<"objc_method", [ObjCMethod], [ AttrSubjectMatcherSubRule<"is_instance", [ObjCInstanceMethod]> @@ -715,7 +732,8 @@ def Availability : InheritableAttr { let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">, VersionArgument<"deprecated">, VersionArgument<"obsoleted">, BoolArgument<"unavailable">, StringArgument<"message">, - BoolArgument<"strict">, StringArgument<"replacement">]; + BoolArgument<"strict">, StringArgument<"replacement">, + IntArgument<"priority">]; let AdditionalMembers = [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch<llvm::StringRef>(Platform) @@ -940,6 +958,13 @@ def CUDADevice : InheritableAttr { let Documentation = [Undocumented]; } +def HIPPinnedShadow : InheritableAttr { + let Spellings = [GNU<"hip_pinned_shadow">, Declspec<"__hip_pinned_shadow__">]; + let Subjects = SubjectList<[Var]>; + let LangOpts = [HIP]; + let Documentation = [HIPPinnedShadowDocs]; +} + def CUDADeviceBuiltin : IgnoredAttr { let Spellings = [GNU<"device_builtin">, Declspec<"__device_builtin__">]; let LangOpts = [CUDA]; @@ -1210,6 +1235,13 @@ def FormatArg : InheritableAttr { let Documentation = [Undocumented]; } +def Callback : InheritableAttr { + let Spellings = [Clang<"callback">]; + let Args = [VariadicParamOrParamIdxArgument<"Encoding">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [CallbackDocs]; +} + def GNUInline : InheritableAttr { let Spellings = [GCC<"gnu_inline">]; let Subjects = SubjectList<[Function]>; @@ -1296,6 +1328,12 @@ def MayAlias : InheritableAttr { let Documentation = [Undocumented]; } +def MIGServerRoutine : InheritableAttr { + let Spellings = [Clang<"mig_server_routine">]; + let Subjects = SubjectList<[Function, ObjCMethod, Block]>; + let Documentation = [MIGConventionDocs]; +} + def MSABI : DeclOrTypeAttr { let Spellings = [GCC<"ms_abi">]; // let Subjects = [Function, ObjCMethod]; @@ -1384,6 +1422,12 @@ def NeonVectorType : TypeAttr { let ASTNode = 0; } +def NoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetItaniumCXXABI> { + let Spellings = [CXX11<"", "no_unique_address", 201803>]; + let Subjects = SubjectList<[NonBitField], ErrorDiag>; + let Documentation = [NoUniqueAddressDocs]; +} + def ReturnsTwice : InheritableAttr { let Spellings = [GCC<"returns_twice">]; let Subjects = SubjectList<[Function]>; @@ -1410,7 +1454,7 @@ def NoCommon : InheritableAttr { def NoDebug : InheritableAttr { let Spellings = [GCC<"nodebug">]; - let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar]>; + let Subjects = SubjectList<[TypedefName, FunctionLike, ObjCMethod, NonParmVar]>; let Documentation = [NoDebugDocs]; } @@ -1474,14 +1518,14 @@ def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> { def AMDGPUFlatWorkGroupSize : InheritableAttr { let Spellings = [Clang<"amdgpu_flat_work_group_size", 0>]; - let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">]; + let Args = [ExprArgument<"Min">, ExprArgument<"Max">]; let Documentation = [AMDGPUFlatWorkGroupSizeDocs]; let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } def AMDGPUWavesPerEU : InheritableAttr { let Spellings = [Clang<"amdgpu_waves_per_eu", 0>]; - let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>]; + let Args = [ExprArgument<"Min">, ExprArgument<"Max", 1>]; let Documentation = [AMDGPUWavesPerEUDocs]; let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } @@ -1500,6 +1544,22 @@ def AMDGPUNumVGPR : InheritableAttr { let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } +def WebAssemblyImportModule : InheritableAttr, + TargetSpecificAttr<TargetWebAssembly> { + let Spellings = [Clang<"import_module">]; + let Args = [StringArgument<"ImportModule">]; + let Documentation = [WebAssemblyImportModuleDocs]; + let Subjects = SubjectList<[Function], ErrorDiag>; +} + +def WebAssemblyImportName : InheritableAttr, + TargetSpecificAttr<TargetWebAssembly> { + let Spellings = [Clang<"import_name">]; + let Args = [StringArgument<"ImportName">]; + let Documentation = [WebAssemblyImportNameDocs]; + let Subjects = SubjectList<[Function], ErrorDiag>; +} + def NoSplitStack : InheritableAttr { let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; @@ -1534,7 +1594,9 @@ def ReturnsNonNull : InheritableAttr { // pass_object_size(N) indicates that the parameter should have // __builtin_object_size with Type=N evaluated on the parameter at the callsite. def PassObjectSize : InheritableParamAttr { - let Spellings = [Clang<"pass_object_size">]; + let Spellings = [Clang<"pass_object_size">, + Clang<"pass_dynamic_object_size">]; + let Accessors = [Accessor<"isDynamic", [Clang<"pass_dynamic_object_size">]>]; let Args = [IntArgument<"Type">]; let Subjects = SubjectList<[ParmVar]>; let Documentation = [PassObjectSizeDocs]; @@ -1615,7 +1677,7 @@ def NoStackProtector : InheritableAttr { def NoThrow : InheritableAttr { let Spellings = [GCC<"nothrow">, Declspec<"nothrow">]; - let Subjects = SubjectList<[Function]>; + let Subjects = SubjectList<[FunctionLike]>; let Documentation = [NoThrowDocs]; } @@ -1731,6 +1793,13 @@ def ObjCRootClass : InheritableAttr { let Documentation = [Undocumented]; } +def ObjCNonLazyClass : Attr { + let Spellings = [Clang<"objc_nonlazy_class">]; + let Subjects = SubjectList<[ObjCInterface, ObjCImpl], ErrorDiag>; + let LangOpts = [ObjC]; + let Documentation = [ObjCNonLazyClassDocs]; +} + def ObjCSubclassingRestricted : InheritableAttr { let Spellings = [Clang<"objc_subclassing_restricted">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; @@ -1745,7 +1814,7 @@ def ObjCExplicitProtocolImpl : InheritableAttr { def ObjCDesignatedInitializer : Attr { let Spellings = [Clang<"objc_designated_initializer">]; - let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>; + let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; let Documentation = [Undocumented]; } @@ -1762,6 +1831,13 @@ def ObjCRuntimeVisible : Attr { let Documentation = [ObjCRuntimeVisibleDocs]; } +def ObjCClassStub : Attr { + let Spellings = [Clang<"objc_class_stub">]; + let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; + let Documentation = [ObjCClassStubDocs]; + let LangOpts = [ObjCNonFragileRuntime]; +} + def ObjCBoxable : Attr { let Spellings = [Clang<"objc_boxable">]; let Subjects = SubjectList<[Record], ErrorDiag>; @@ -1893,6 +1969,8 @@ def Section : InheritableAttr { let Documentation = [SectionDocs]; } +// This is used for `__declspec(code_seg("segname"))`, but not for +// `#pragma code_seg("segname")`. def CodeSeg : InheritableAttr { let Spellings = [Declspec<"code_seg">]; let Args = [StringArgument<"Name">]; @@ -2326,7 +2404,7 @@ def NoSanitize : InheritableAttr { let Documentation = [NoSanitizeDocs]; let AdditionalMembers = [{ SanitizerMask getMask() const { - SanitizerMask Mask = 0; + SanitizerMask Mask; for (auto SanitizerName : sanitizers()) { SanitizerMask ParsedMask = parseSanitizerValue(SanitizerName, /*AllowGroups=*/true); @@ -2722,6 +2800,12 @@ def : IgnoredAttr { let Spellings = [Declspec<"property">]; } +def MSAllocator : InheritableAttr { + let Spellings = [Declspec<"allocator">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [MSAllocatorDocs]; +} + def MSStruct : InheritableAttr { let Spellings = [GCC<"ms_struct">]; let Subjects = SubjectList<[Record]>; @@ -3112,6 +3196,29 @@ def OMPDeclareTargetDecl : InheritableAttr { }]; } +def OMPAllocateDecl : InheritableAttr { + // This attribute has no spellings as it is only ever created implicitly. + let Spellings = []; + let SemaHandler = 0; + let Args = [ + EnumArgument<"AllocatorType", "AllocatorTypeTy", + [ + "omp_default_mem_alloc", "omp_large_cap_mem_alloc", + "omp_const_mem_alloc", "omp_high_bw_mem_alloc", + "omp_low_lat_mem_alloc", "omp_cgroup_mem_alloc", + "omp_pteam_mem_alloc", "omp_thread_mem_alloc", "" + ], + [ + "OMPDefaultMemAlloc", "OMPLargeCapMemAlloc", + "OMPConstMemAlloc", "OMPHighBWMemAlloc", "OMPLowLatMemAlloc", + "OMPCGroupMemAlloc", "OMPPTeamMemAlloc", "OMPThreadMemAlloc", + "OMPUserDefinedMemAlloc" + ]>, + ExprArgument<"Allocator"> + ]; + let Documentation = [Undocumented]; +} + def InternalLinkage : InheritableAttr { let Spellings = [Clang<"internal_linkage">]; let Subjects = SubjectList<[Var, Function, CXXRecord]>; @@ -3149,6 +3256,12 @@ def SpeculativeLoadHardening : InheritableAttr { let Documentation = [SpeculativeLoadHardeningDocs]; } +def NoSpeculativeLoadHardening : InheritableAttr { + let Spellings = [Clang<"no_speculative_load_hardening">]; + let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>; + let Documentation = [NoSpeculativeLoadHardeningDocs]; +} + def Uninitialized : InheritableAttr { let Spellings = [Clang<"uninitialized", 0>]; let Subjects = SubjectList<[LocalVar]>; diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 5773a92c9c15..fac6116057dc 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -1,9 +1,8 @@ //==--- AttrDocs.td - Attribute documentation ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===---------------------------------------------------------------------===// @@ -607,6 +606,7 @@ Query for this feature with ``__has_attribute(diagnose_if)``. def PassObjectSizeDocs : Documentation { let Category = DocCatVariable; // Technically it's a parameter doc, but eh. + let Heading = "pass_object_size, pass_dynamic_object_size"; let Content = [{ .. Note:: The mangling of functions with parameters that are annotated with ``pass_object_size`` is subject to change. You can get around this by @@ -699,6 +699,15 @@ Currently, ``pass_object_size`` is a bit restricted in terms of its usage: * It is an error to apply the ``pass_object_size`` attribute to parameters that are not pointers. Additionally, any parameter that ``pass_object_size`` is applied to must be marked ``const`` at its function's definition. + +Clang also supports the ``pass_dynamic_object_size`` attribute, which behaves +identically to ``pass_object_size``, but evaluates a call to +``__builtin_dynamic_object_size`` at the callee instead of +``__builtin_object_size``. ``__builtin_dynamic_object_size`` provides some extra +runtime checks when the object size can't be determined at compile-time. You can +read more about ``__builtin_dynamic_object_size`` `here +<https://clang.llvm.org/docs/LanguageExtensions.html#evaluating-object-size-dynamically>`_. + }]; } @@ -912,8 +921,6 @@ and Objective-C methods. }]; } - - def NoDebugDocs : Documentation { let Category = DocCatVariable; let Content = [{ @@ -1002,6 +1009,32 @@ is not specified. }]; } +def NoUniqueAddressDocs : Documentation { + let Category = DocCatField; + let Content = [{ +The ``no_unique_address`` attribute allows tail padding in a non-static data +member to overlap other members of the enclosing class (and in the special +case when the type is empty, permits it to fully overlap other members). +The field is laid out as if a base class were encountered at the corresponding +point within the class (except that it does not share a vptr with the enclosing +object). + +Example usage: + +.. code-block:: c++ + + template<typename T, typename Alloc> struct my_vector { + T *p; + [[no_unique_address]] Alloc alloc; + // ... + }; + static_assert(sizeof(my_vector<int, std::allocator<int>>) == sizeof(int*)); + +``[[no_unique_address]]`` is a standard C++20 attribute. Clang supports its use +in C++11 onwards. + }]; +} + def ObjCRequiresSuperDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -1048,7 +1081,7 @@ implementation of an override in a subclass does not call super. For example: } def ObjCRuntimeNameDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; let Content = [{ By default, the Objective-C interface or protocol identifier is used in the metadata name for that object. The `objc_runtime_name` @@ -1069,14 +1102,36 @@ can only be placed before an @protocol or @interface declaration: } def ObjCRuntimeVisibleDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; + let Content = [{ +This attribute specifies that the Objective-C class to which it applies is +visible to the Objective-C runtime but not to the linker. Classes annotated +with this attribute cannot be subclassed and cannot have categories defined for +them. + }]; +} + +def ObjCClassStubDocs : Documentation { + let Category = DocCatType; let Content = [{ -This attribute specifies that the Objective-C class to which it applies is visible to the Objective-C runtime but not to the linker. Classes annotated with this attribute cannot be subclassed and cannot have categories defined for them. +This attribute specifies that the Objective-C class to which it applies is +instantiated at runtime. + +Unlike ``__attribute__((objc_runtime_visible))``, a class having this attribute +still has a "class stub" that is visible to the linker. This allows categories +to be defined. Static message sends with the class as a receiver use a special +access pattern to ensure the class is lazily instantiated from the class stub. + +Classes annotated with this attribute cannot be subclassed and cannot have +implementations defined for them. This attribute is intended for use in +Swift-generated headers for classes defined in Swift. + +Adding or removing this attribute to a class is an ABI-breaking change. }]; } def ObjCBoxableDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; let Content = [{ Structs and unions marked with the ``objc_boxable`` attribute can be used with the Objective-C boxed expression syntax, ``@(...)``. @@ -1153,11 +1208,14 @@ replacement=\ *string-literal* the deprecated declaration with the new declaration specified. Multiple availability attributes can be placed on a declaration, which may -correspond to different platforms. Only the availability attribute with the -platform corresponding to the target platform will be used; any others will be -ignored. If no availability attribute specifies availability for the current -target platform, the availability attributes are ignored. Supported platforms -are: +correspond to different platforms. For most platforms, the availability +attribute with the platform corresponding to the target platform will be used; +any others will be ignored. However, the availability for ``watchOS`` and +``tvOS`` can be implicitly inferred from an ``iOS`` availability attribute. +Any explicit availability attributes for those platforms are still prefered over +the implicitly inferred availability attributes. If no availability attribute +specifies availability for the current target platform, the availability +attributes are ignored. Supported platforms are: ``ios`` Apple's iOS operating system. The minimum deployment target is specified by @@ -1230,13 +1288,70 @@ Starting with the macOS 10.12 SDK, the ``API_AVAILABLE`` macro from - (id)otherMethod API_AVAILABLE(macos(10.11), ios(11.0)); @end +Availability attributes can also be applied using a ``#pragma clang attribute``. +Any explicit availability attribute whose platform corresponds to the target +platform is applied to a declaration regardless of the availability attributes +specified in the pragma. For example, in the code below, +``hasExplicitAvailabilityAttribute`` will use the ``macOS`` availability +attribute that is specified with the declaration, whereas +``getsThePragmaAvailabilityAttribute`` will use the ``macOS`` availability +attribute that is applied by the pragma. + +.. code-block:: c + + #pragma clang attribute push (__attribute__((availability(macOS, introduced=10.12))), apply_to=function) + void getsThePragmaAvailabilityAttribute(void); + void hasExplicitAvailabilityAttribute(void) __attribute__((availability(macos,introduced=10.4))); + #pragma clang attribute pop + +For platforms like ``watchOS`` and ``tvOS``, whose availability attributes can +be implicitly inferred from an ``iOS`` availability attribute, the logic is +slightly more complex. The explicit and the pragma-applied availability +attributes whose platform corresponds to the target platform are applied as +described in the previous paragraph. However, the implicitly inferred attributes +are applied to a declaration only when there is no explicit or pragma-applied +availability attribute whose platform corresponds to the target platform. For +example, the function below will receive the ``tvOS`` availability from the +pragma rather than using the inferred ``iOS`` availability from the declaration: + +.. code-block:: c + + #pragma clang attribute push (__attribute__((availability(tvOS, introduced=12.0))), apply_to=function) + void getsThePragmaTVOSAvailabilityAttribute(void) __attribute__((availability(iOS,introduced=11.0))); + #pragma clang attribute pop + +The compiler is also able to apply implicly inferred attributes from a pragma +as well. For example, when targeting ``tvOS``, the function below will receive +a ``tvOS`` availability attribute that is implicitly inferred from the ``iOS`` +availability attribute applied by the pragma: + +.. code-block:: c + + #pragma clang attribute push (__attribute__((availability(iOS, introduced=12.0))), apply_to=function) + void infersTVOSAvailabilityFromPragma(void); + #pragma clang attribute pop + +The implicit attributes that are inferred from explicitly specified attributes +whose platform corresponds to the target platform are applied to the declaration +even if there is an availability attribute that can be inferred from a pragma. +For example, the function below will receive the ``tvOS, introduced=11.0`` +availability that is inferred from the attribute on the declaration rather than +inferring availability from the pragma: + +.. code-block:: c + + #pragma clang attribute push (__attribute__((availability(iOS, unavailable))), apply_to=function) + void infersTVOSAvailabilityFromAttributeNextToDeclaration(void) + __attribute__((availability(iOS,introduced=11.0))); + #pragma clang attribute pop + Also see the documentation for `@available <http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-available>`_ }]; } def ExternalSourceSymbolDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; let Content = [{ The ``external_source_symbol`` attribute specifies that a declaration originates from an external source and describes the nature of that source. @@ -2380,7 +2495,7 @@ behavior of the program is undefined. } def FlagEnumDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ This attribute can be added to an enumerator to signal to the compiler that it is intended to be used as a flag type. This will cause the compiler to assume @@ -2390,7 +2505,7 @@ manipulating bits of the enumerator when issuing warnings. } def EnumExtensibilityDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; 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 @@ -2439,7 +2554,7 @@ standard and instructs clang to be more lenient when issuing warnings. } def EmptyBasesDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ The empty_bases attribute permits the compiler to utilize the empty-base-optimization more frequently. @@ -2449,7 +2564,7 @@ It is only supported when using the Microsoft C++ ABI. } def LayoutVersionDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ The layout_version attribute requests that the compiler utilize the class layout rules of a particular compiler version. @@ -2475,7 +2590,7 @@ changes. } def TrivialABIDocs : Documentation { - let Category = DocCatVariable; + let Category = DocCatDecl; let Content = [{ The ``trivial_abi`` attribute can be applied to a C++ class, struct, or union. It instructs the compiler to pass and return the type using the C ABI for the @@ -2517,7 +2632,7 @@ Attribute ``trivial_abi`` has no effect in the following cases: } def MSInheritanceDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance"; let Content = [{ This collection of keywords is enabled under ``-fms-extensions`` and controls @@ -2564,7 +2679,7 @@ an error: } def MSNoVTableDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ This attribute can be added to a class declaration or definition to signal to the compiler that constructors and destructors will not reference the virtual @@ -2705,8 +2820,6 @@ def PipelineHintDocs : Documentation { }]; } - - def OpenCLUnrollHintDocs : Documentation { let Category = DocCatStmt; let Content = [{ @@ -3276,7 +3389,7 @@ jumps from i386 arch code). }]; } -def AnyX86NoCfCheckDocs : Documentation{ +def AnyX86NoCfCheckDocs : Documentation { let Category = DocCatFunction; let Content = [{ Jump Oriented Programming attacks rely on tampering with addresses used by @@ -3544,7 +3657,7 @@ experimental at this time. } def DeprecatedDocs : Documentation { - let Category = DocCatFunction; + let Category = DocCatDecl; let Content = [{ The ``deprecated`` attribute can be applied to a function, a variable, or a type. This is useful when identifying functions, variables, or types that are @@ -3579,7 +3692,7 @@ Not all targets support this attribute. ELF target support depends on both the l } def LTOVisibilityDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ See :doc:`LTOVisibility`. }]; @@ -3615,7 +3728,7 @@ If a function has neither of these attributes, they become subject to the XRay h } def TransparentUnionDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ This attribute can be applied to a union to change the behaviour of calls to functions that have an argument with a transparent union type. The compiler @@ -3633,16 +3746,29 @@ Transparent unions are not supported in C++. } def ObjCSubclassingRestrictedDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ This attribute can be added to an Objective-C ``@interface`` declaration to ensure that this class cannot be subclassed. }]; } +def ObjCNonLazyClassDocs : Documentation { + let Category = DocCatDecl; + let Content = [{ +This attribute can be added to an Objective-C ``@interface`` or +``@implementation`` declaration to add the class to the list of non-lazily +initialized classes. A non-lazy class will be initialized eagerly when the +Objective-C runtime is loaded. This is required for certain system classes which +have instances allocated in non-standard ways, such as the classes for blocks +and constant strings. Adding this attribute is essentially equivalent to +providing a trivial `+load` method but avoids the (fairly small) load-time +overheads associated with defining and calling such a method. + }]; +} def SelectAnyDocs : Documentation { - let Category = DocCatType; + let Category = DocCatDecl; let Content = [{ This attribute appertains to a global symbol, causing it to have a weak definition ( @@ -3652,7 +3778,40 @@ definition ( For more information see `gcc documentation <https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Microsoft-Windows-Variable-Attributes.html>`_ or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_. -}]; +}]; } + +def WebAssemblyImportModuleDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the ``__attribute__((import_module(<module_name>)))`` +attribute for the WebAssembly target. This attribute may be attached to a +function declaration, where it modifies how the symbol is to be imported +within the WebAssembly linking environment. + +WebAssembly imports use a two-level namespace scheme, consisting of a module +name, which typically identifies a module from which to import, and a field +name, which typically identifies a field from that module to import. By +default, module names for C/C++ symbols are assigned automatically by the +linker. This attribute can be used to override the default behavior, and +reuqest a specific module name be used instead. + }]; +} + +def WebAssemblyImportNameDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the ``__attribute__((import_name(<name>)))`` +attribute for the WebAssembly target. This attribute may be attached to a +function declaration, where it modifies how the symbol is to be imported +within the WebAssembly linking environment. + +WebAssembly imports use a two-level namespace scheme, consisting of a module +name, which typically identifies a module from which to import, and a field +name, which typically identifies a field from that module to import. By +default, field names for C/C++ symbols are the same as their C/C++ symbol +names. This attribute can be used to override the default behavior, and +reuqest a specific field name be used instead. + }]; } def ArtificialDocs : Documentation { @@ -3766,6 +3925,39 @@ The ``no_destroy`` attribute specifies that a variable with static or thread storage duration shouldn't have its exit-time destructor run. Annotating every static and thread duration variable with this attribute is equivalent to invoking clang with -fno-c++-static-destructors. + +If a variable is declared with this attribute, clang doesn't access check or +generate the type's destructor. If you have a type that you only want to be +annotated with ``no_destroy``, you can therefore declare the destructor private: + +.. code-block:: c++ + + struct only_no_destroy { + only_no_destroy(); + private: + ~only_no_destroy(); + }; + + [[clang::no_destroy]] only_no_destroy global; // fine! + +Note that destructors are still required for subobjects of aggregates annotated +with this attribute. This is because previously constructed subobjects need to +be destroyed if an exception gets thrown before the initialization of the +complete object is complete. For instance: + +.. code-block::c++ + + void f() { + try { + [[clang::no_destroy]] + static only_no_destroy array[10]; // error, only_no_destroy has a private destructor. + } catch (...) { + // Handle the error + } + } + +Here, if the construction of `array[9]` fails with an exception, `array[0..8]` +will be destroyed, so the element's destructor needs to be accessible. }]; } @@ -3781,6 +3973,55 @@ it rather documents the programmer's intent. }]; } +def CallbackDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``callback`` attribute specifies that the annotated function may invoke the +specified callback zero or more times. The callback, as well as the passed +arguments, are identified by their parameter name or position (starting with +1!) in the annotated function. The first position in the attribute identifies +the callback callee, the following positions declare describe its arguments. +The callback callee is required to be callable with the number, and order, of +the specified arguments. The index `0`, or the identifier `this`, is used to +represent an implicit "this" pointer in class methods. If there is no implicit +"this" pointer it shall not be referenced. The index '-1', or the name "__", +represents an unknown callback callee argument. This can be a value which is +not present in the declared parameter list, or one that is, but is potentially +inspected, captured, or modified. Parameter names and indices can be mixed in +the callback attribute. + +The ``callback`` attribute, which is directly translated to ``callback`` +metadata <http://llvm.org/docs/LangRef.html#callback-metadata>, make the +connection between the call to the annotated function and the callback callee. +This can enable interprocedural optimizations which were otherwise impossible. +If a function parameter is mentioned in the ``callback`` attribute, through its +position, it is undefined if that parameter is used for anything other than the +actual callback. Inspected, captured, or modified parameters shall not be +listed in the ``callback`` metadata. + +Example encodings for the callback performed by `pthread_create` are shown +below. The explicit attribute annotation indicates that the third parameter +(`start_routine`) is called zero or more times by the `pthread_create` function, +and that the fourth parameter (`arg`) is passed along. Note that the callback +behavior of `pthread_create` is automatically recognized by Clang. In addition, +the declarations of `__kmpc_fork_teams` and `__kmpc_fork_call`, generated for +`#pragma omp target teams` and `#pragma omp parallel`, respectively, are also +automatically recognized as broker functions. Further functions might be added +in the future. + + .. code-block:: c + + __attribute__((callback (start_routine, arg))) + int pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine) (void *), void *arg); + + __attribute__((callback (3, 4))) + int pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine) (void *), void *arg); + + }]; +} + def GnuInlineDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -3788,13 +4029,13 @@ The ``gnu_inline`` changes the meaning of ``extern inline`` to use GNU inline semantics, meaning: * If any declaration that is declared ``inline`` is not declared ``extern``, -then the ``inline`` keyword is just a hint. In particular, an out-of-line -definition is still emitted for a function with external linkage, even if all -call sites are inlined, unlike in C99 and C++ inline semantics. + then the ``inline`` keyword is just a hint. In particular, an out-of-line + definition is still emitted for a function with external linkage, even if all + call sites are inlined, unlike in C99 and C++ inline semantics. * If all declarations that are declared ``inline`` are also declared -``extern``, then the function body is present only for inlining and no -out-of-line version is emitted. + ``extern``, then the function body is present only for inlining and no + out-of-line version is emitted. Some important consequences: ``static inline`` emits an out-of-line version if needed, a plain ``inline`` definition emits an out-of-line version @@ -3822,7 +4063,8 @@ def SpeculativeLoadHardeningDocs : Documentation { This attribute can be applied to a function declaration in order to indicate that `Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_ should be enabled for the function body. This can also be applied to a method - in Objective C. + in Objective C. This attribute will take precedence over the command line flag in + the case where `-mno-speculative-load-hardening <https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mspeculative-load-hardening>`_ is specified. Speculative Load Hardening is a best-effort mitigation against information leak attacks that make use of control flow @@ -3840,6 +4082,42 @@ def SpeculativeLoadHardeningDocs : Documentation { }]; } +def NoSpeculativeLoadHardeningDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ + This attribute can be applied to a function declaration in order to indicate + that `Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_ + is *not* needed for the function body. This can also be applied to a method + in Objective C. This attribute will take precedence over the command line flag in + the case where `-mspeculative-load-hardening <https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mspeculative-load-hardening>`_ is specified. + + Warning: This attribute may not prevent Speculative Load Hardening from being + enabled for a function which inlines a function that has the + 'speculative_load_hardening' attribute. This is intended to provide a + maximally conservative model where the code that is marked with the + 'speculative_load_hardening' attribute will always (even when inlined) + be hardened. A user of this attribute may want to mark functions called by + a function they do not want to be hardened with the 'noinline' attribute. + + For example: + + .. code-block:: c + + __attribute__((speculative_load_hardening)) + int foo(int i) { + return i; + } + + // Note: bar() may still have speculative load hardening enabled if + // foo() is inlined into bar(). Mark foo() with __attribute__((noinline)) + // to avoid this situation. + __attribute__((no_speculative_load_hardening)) + int bar(int i) { + return foo(i); + } + }]; +} + def ObjCExternallyRetainedDocs : Documentation { let Category = DocCatVariable; let Content = [{ @@ -3867,3 +4145,53 @@ Likewise, when applied to a strong local variable, that variable becomes When compiled without ``-fobjc-arc``, this attribute is ignored. }]; } + +def MIGConventionDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ + The Mach Interface Generator release-on-success convention dictates +functions that follow it to only release arguments passed to them when they +return "success" (a ``kern_return_t`` error code that indicates that +no errors have occured). Otherwise the release is performed by the MIG client +that called the function. The annotation ``__attribute__((mig_server_routine))`` +is applied in order to specify which functions are expected to follow the +convention. This allows the Static Analyzer to find bugs caused by violations of +that convention. The attribute would normally appear on the forward declaration +of the actual server routine in the MIG server header, but it may also be +added to arbitrary functions that need to follow the same convention - for +example, a user can add them to auxiliary functions called by the server routine +that have their return value of type ``kern_return_t`` unconditionally returned +from the routine. The attribute can be applied to C++ methods, and in this case +it will be automatically applied to overrides if the method is virtual. The +attribute can also be written using C++11 syntax: ``[[mig::server_routine]]``. +}]; +} + +def MSAllocatorDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``__declspec(allocator)`` attribute is applied to functions that allocate +memory, such as operator new in C++. When CodeView debug information is emitted +(enabled by ``clang -gcodeview`` or ``clang-cl /Z7``), Clang will attempt to +record the code offset of heap allocation call sites in the debug info. It will +also record the type being allocated using some local heuristics. The Visual +Studio debugger uses this information to `profile memory usage`_. + +.. _profile memory usage: https://docs.microsoft.com/en-us/visualstudio/profiling/memory-usage + +This attribute does not affect optimizations in any way, unlike GCC's +``__attribute__((malloc))``. +}]; +} + +def HIPPinnedShadowDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The GNU style attribute __attribute__((hip_pinned_shadow)) or MSVC style attribute +__declspec(hip_pinned_shadow) can be added to the definition of a global variable +to indicate it is a HIP pinned shadow variable. A HIP pinned shadow variable can +be accessed on both device side and host side. It has external linkage and is +not initialized on device side. It has internal linkage and is initialized by +the initializer on host side. + }]; +}
\ No newline at end of file diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h index d82dbb032be9..ec0052dfea35 100644 --- a/include/clang/Basic/AttrKinds.h +++ b/include/clang/Basic/AttrKinds.h @@ -1,9 +1,8 @@ //===----- Attr.h - Enum values for C Attribute Kinds ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/AttrSubjectMatchRules.h b/include/clang/Basic/AttrSubjectMatchRules.h index 81aa634dfeb8..010cefcaf340 100644 --- a/include/clang/Basic/AttrSubjectMatchRules.h +++ b/include/clang/Basic/AttrSubjectMatchRules.h @@ -1,9 +1,8 @@ //===-- AttrSubjectMatchRules.h - Attribute subject match rules -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h index 3152453694c9..c69633decd57 100644 --- a/include/clang/Basic/Attributes.h +++ b/include/clang/Basic/Attributes.h @@ -1,9 +1,8 @@ //===--- Attributes.h - Attributes header -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/BitmaskEnum.h b/include/clang/Basic/BitmaskEnum.h index 12ff3cf207be..34bfa1764e5e 100644 --- a/include/clang/Basic/BitmaskEnum.h +++ b/include/clang/Basic/BitmaskEnum.h @@ -1,9 +1,8 @@ //===--- BitmaskEnum.h - wrapper of LLVM's bitmask enum facility-*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index fa031ce09f6b..984e607a2fc4 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -1,9 +1,8 @@ //===--- Builtins.def - Builtin function info database ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -51,8 +50,10 @@ // L -> long (e.g. Li for 'long int', Ld for 'long double') // LL -> long long (e.g. LLi for 'long long int', LLd for __float128) // LLL -> __int128_t (e.g. LLLi) -// W -> int64_t +// Z -> int32_t (require a native 32-bit integer type on the target) +// W -> int64_t (require a native 64-bit integer type on the target) // N -> 'int' size if target is LP64, 'L' otherwise. +// O -> long for OpenCL targets, long long otherwise. // S -> signed // U -> unsigned // I -> Required to constant fold to an integer constant expression. @@ -93,6 +94,8 @@ // j -> returns_twice (like setjmp) // u -> arguments are not evaluated for their side-effects // V:N: -> requires vectors of at least N bits to be legal +// C<N,M_0,...,M_k> -> callback behavior: argument N is called with argument +// M_0, ..., M_k as payload // FIXME: gcc has nonnull #if defined(BUILTIN) && !defined(LIBBUILTIN) @@ -417,25 +420,27 @@ BUILTIN(__builtin_clrsb , "ii" , "nc") BUILTIN(__builtin_clrsbl , "iLi" , "nc") BUILTIN(__builtin_clrsbll, "iLLi", "nc") -// FIXME: These type signatures are not correct for targets with int != 32-bits -// or with ULL != 64-bits. +// The following builtins rely on that char == 8 bits, short == 16 bits and that +// there exists native types on the target that are 32- and 64-bits wide, unless +// these conditions are fulfilled these builtins will operate on a not intended +// bitwidth. BUILTIN(__builtin_bswap16, "UsUs", "nc") -BUILTIN(__builtin_bswap32, "UiUi", "nc") -BUILTIN(__builtin_bswap64, "ULLiULLi", "nc") +BUILTIN(__builtin_bswap32, "UZiUZi", "nc") +BUILTIN(__builtin_bswap64, "UWiUWi", "nc") BUILTIN(__builtin_bitreverse8, "UcUc", "nc") BUILTIN(__builtin_bitreverse16, "UsUs", "nc") -BUILTIN(__builtin_bitreverse32, "UiUi", "nc") -BUILTIN(__builtin_bitreverse64, "ULLiULLi", "nc") +BUILTIN(__builtin_bitreverse32, "UZiUZi", "nc") +BUILTIN(__builtin_bitreverse64, "UWiUWi", "nc") BUILTIN(__builtin_rotateleft8, "UcUcUc", "nc") BUILTIN(__builtin_rotateleft16, "UsUsUs", "nc") -BUILTIN(__builtin_rotateleft32, "UiUiUi", "nc") -BUILTIN(__builtin_rotateleft64, "ULLiULLiULLi", "nc") +BUILTIN(__builtin_rotateleft32, "UZiUZiUZi", "nc") +BUILTIN(__builtin_rotateleft64, "UWiUWiUWi", "nc") BUILTIN(__builtin_rotateright8, "UcUcUc", "nc") BUILTIN(__builtin_rotateright16, "UsUsUs", "nc") -BUILTIN(__builtin_rotateright32, "UiUiUi", "nc") -BUILTIN(__builtin_rotateright64, "ULLiULLiULLi", "nc") +BUILTIN(__builtin_rotateright32, "UZiUZiUZi", "nc") +BUILTIN(__builtin_rotateright64, "UWiUWiWi", "nc") // Random GCC builtins BUILTIN(__builtin_constant_p, "i.", "nctu") @@ -447,7 +452,7 @@ BUILTIN(__builtin_va_end, "vA", "n") BUILTIN(__builtin_va_copy, "vAA", "n") BUILTIN(__builtin_stdarg_start, "vA.", "n") BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc") -BUILTIN(__builtin_bcmp, "iv*v*z", "Fn") +BUILTIN(__builtin_bcmp, "ivC*vC*z", "Fn") BUILTIN(__builtin_bcopy, "vv*v*z", "n") BUILTIN(__builtin_bzero, "vv*z", "nF") BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:") @@ -499,6 +504,7 @@ BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:") BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:") BUILTIN(__builtin_thread_pointer, "v*", "nc") BUILTIN(__builtin_launder, "v*v*", "nt") +LANGBUILTIN(__builtin_is_constant_evaluated, "b", "n", CXX_LANG) // GCC exception builtins BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t! @@ -510,6 +516,7 @@ BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t // GCC Object size checking builtins BUILTIN(__builtin_object_size, "zvC*i", "nu") +BUILTIN(__builtin_dynamic_object_size, "zvC*i", "nu") // Clang only. BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF") BUILTIN(__builtin___memccpy_chk, "v*v*vC*izz", "nF") BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF") @@ -818,6 +825,14 @@ LANGBUILTIN(_interlockedbittestandset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_interlockedbittestandset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_interlockedbittestandset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_interlockedbittestandset_rel, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__lzcnt16, "UsUs", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__lzcnt, "UiUi", "nc", ALL_MS_LANGUAGES) @@ -829,12 +844,12 @@ LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_lrotl, "UNiUNii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_lrotl, "ULiULii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl64, "UWiUWii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotr8, "UcUcUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotr16, "UsUsUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_lrotr, "UNiUNii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotr64, "UWiUWii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES) LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES) @@ -951,6 +966,7 @@ LIBBUILTIN(strndup, "c*cC*z", "f", "string.h", ALL_GNU_LANGUAGES) LIBBUILTIN(index, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES) LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES) LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(bcmp, "ivC*vC*z", "f", "strings.h", ALL_GNU_LANGUAGES) // In some systems str[n]casejmp is a macro that expands to _str[n]icmp. // We undefine then here to avoid wrong name. #undef strcasecmp @@ -960,6 +976,9 @@ LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_GNU_LANGUAGES) // POSIX unistd.h LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_GNU_LANGUAGES) LIBBUILTIN(vfork, "p", "fj", "unistd.h", ALL_LANGUAGES) +// POSIX pthread.h +LIBBUILTIN(pthread_create, "", "fC<2,3>", "pthread.h", ALL_GNU_LANGUAGES) + // POSIX setjmp.h LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) @@ -1430,6 +1449,7 @@ BUILTIN(__builtin_operator_new, "v*z", "tc") BUILTIN(__builtin_operator_delete, "vv*", "tn") BUILTIN(__builtin_char_memchr, "c*cC*iz", "n") BUILTIN(__builtin_dump_struct, "ivC*v*", "tn") +BUILTIN(__builtin_preserve_access_index, "vC*vC*", "nU") // Safestack builtins BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn") @@ -1458,6 +1478,7 @@ BUILTIN(__builtin_coro_begin, "v*v*", "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. // We need the generic prototype, since the packet type could be anything. LANGBUILTIN(read_pipe, "i.", "tn", OCLC20_LANG) @@ -1493,6 +1514,8 @@ LANGBUILTIN(get_kernel_max_sub_group_size_for_ndrange, "Ui.", "tn", OCLC20_LANG) LANGBUILTIN(get_kernel_sub_group_count_for_ndrange, "Ui.", "tn", OCLC20_LANG) // OpenCL v2.0 s6.13.9 - Address space qualifier functions. +// FIXME: Pointer parameters of OpenCL builtins should have their address space +// requirement defined. LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG) LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG) LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG) diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h index fa2bcc4c7ab0..fed0dae20193 100644 --- a/include/clang/Basic/Builtins.h +++ b/include/clang/Basic/Builtins.h @@ -1,9 +1,8 @@ //===--- Builtins.h - Builtin function header -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -194,6 +193,12 @@ public: /// argument and whether this function as a va_list argument. bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg); + /// Determine whether this builtin has callback behavior (see + /// llvm::AbstractCallSites for details). If so, add the index to the + /// callback callee argument and the callback payload arguments. + bool performsCallback(unsigned ID, + llvm::SmallVectorImpl<int> &Encoding) const; + /// Return true if this function has no side effects and doesn't /// read memory, except for possibly errno. /// diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def index 1892ff11a31d..7701ad98f483 100644 --- a/include/clang/Basic/BuiltinsAArch64.def +++ b/include/clang/Basic/BuiltinsAArch64.def @@ -1,9 +1,8 @@ //==- BuiltinsAArch64.def - AArch64 Builtin function database ----*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -33,7 +32,7 @@ BUILTIN(__builtin_arm_clrex, "v", "") // Bit manipulation BUILTIN(__builtin_arm_rbit, "UiUi", "nc") -BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc") +BUILTIN(__builtin_arm_rbit64, "WUiWUi", "nc") // HINT BUILTIN(__builtin_arm_nop, "v", "") @@ -50,23 +49,33 @@ BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc") BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc") BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc") BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc") -BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc") -BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc") +BUILTIN(__builtin_arm_crc32d, "UiUiWUi", "nc") +BUILTIN(__builtin_arm_crc32cd, "UiUiWUi", "nc") + +// Memory Tagging Extensions (MTE) +BUILTIN(__builtin_arm_irg, "v*v*Ui", "t") +BUILTIN(__builtin_arm_addg, "v*v*Ui", "t") +BUILTIN(__builtin_arm_gmi, "Uiv*Ui", "t") +BUILTIN(__builtin_arm_ldg, "v*v*", "t") +BUILTIN(__builtin_arm_stg, "vv*", "t") +BUILTIN(__builtin_arm_subp, "Uiv*v*", "t") // Memory barrier BUILTIN(__builtin_arm_dmb, "vUi", "nc") BUILTIN(__builtin_arm_dsb, "vUi", "nc") BUILTIN(__builtin_arm_isb, "vUi", "nc") +BUILTIN(__builtin_arm_jcvt, "Zid", "nc") + // Prefetch BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc") // System Registers BUILTIN(__builtin_arm_rsr, "UicC*", "nc") -BUILTIN(__builtin_arm_rsr64, "LUicC*", "nc") +BUILTIN(__builtin_arm_rsr64, "WUicC*", "nc") BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc") BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc") -BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc") +BUILTIN(__builtin_arm_wsr64, "vcC*WUi", "nc") BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") // MSVC @@ -79,15 +88,8 @@ LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES) LANGBUILTIN(__sev, "v", "", ALL_MS_LANGUAGES) LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES) -// MSVC intrinsics for volatile but non-acquire/release loads and stores -LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES) +// Misc +BUILTIN(__builtin_sponentry, "v*", "c") TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") @@ -204,8 +206,8 @@ TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h", TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_ReadStatusReg, "ii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_WriteStatusReg, "vii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_ReadStatusReg, "LLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_WriteStatusReg, "viLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") #undef BUILTIN diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def index a25e45fe3fb8..2f8fb9000a76 100644 --- a/include/clang/Basic/BuiltinsAMDGPU.def +++ b/include/clang/Basic/BuiltinsAMDGPU.def @@ -1,9 +1,8 @@ //==- BuiltinsAMDGPU.def - AMDGPU Builtin function database ------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -34,6 +33,9 @@ BUILTIN(__builtin_amdgcn_workitem_id_x, "Ui", "nc") BUILTIN(__builtin_amdgcn_workitem_id_y, "Ui", "nc") BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc") +BUILTIN(__builtin_amdgcn_mbcnt_hi, "UiUiUi", "nc") +BUILTIN(__builtin_amdgcn_mbcnt_lo, "UiUiUi", "nc") + //===----------------------------------------------------------------------===// // Instruction builtins. //===----------------------------------------------------------------------===// @@ -46,6 +48,11 @@ 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_ds_gws_init, "vUiUi", "n") +BUILTIN(__builtin_amdgcn_ds_gws_barrier, "vUiUi", "n") +BUILTIN(__builtin_amdgcn_ds_gws_sema_v, "vUi", "n") +BUILTIN(__builtin_amdgcn_ds_gws_sema_br, "vUiUi", "n") +BUILTIN(__builtin_amdgcn_ds_gws_sema_p, "vUi", "n") // FIXME: Need to disallow constant address space. BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n") @@ -99,12 +106,34 @@ BUILTIN(__builtin_amdgcn_fmed3f, "ffff", "nc") BUILTIN(__builtin_amdgcn_ds_faddf, "ff*3fIiIiIb", "n") BUILTIN(__builtin_amdgcn_ds_fminf, "ff*3fIiIiIb", "n") BUILTIN(__builtin_amdgcn_ds_fmaxf, "ff*3fIiIiIb", "n") +BUILTIN(__builtin_amdgcn_ds_append, "ii*3", "n") +BUILTIN(__builtin_amdgcn_ds_consume, "ii*3", "n") +BUILTIN(__builtin_amdgcn_alignbit, "UiUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_alignbyte, "UiUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_ubfe, "UiUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_sbfe, "UiUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_cvt_pkrtz, "E2hff", "nc") +BUILTIN(__builtin_amdgcn_cvt_pknorm_i16, "E2sff", "nc") +BUILTIN(__builtin_amdgcn_cvt_pknorm_u16, "E2Usff", "nc") +BUILTIN(__builtin_amdgcn_cvt_pk_i16, "E2sii", "nc") +BUILTIN(__builtin_amdgcn_cvt_pk_u16, "E2UsUiUi", "nc") +BUILTIN(__builtin_amdgcn_cvt_pk_u8_f32, "UifUiUi", "nc") //===----------------------------------------------------------------------===// // CI+ only builtins. //===----------------------------------------------------------------------===// TARGET_BUILTIN(__builtin_amdgcn_s_dcache_inv_vol, "v", "n", "ci-insts") TARGET_BUILTIN(__builtin_amdgcn_buffer_wbinvl1_vol, "v", "n", "ci-insts") +TARGET_BUILTIN(__builtin_amdgcn_ds_gws_sema_release_all, "vUi", "n", "ci-insts") + +//===----------------------------------------------------------------------===// +// Interpolation builtins. +//===----------------------------------------------------------------------===// +BUILTIN(__builtin_amdgcn_interp_p1_f16, "ffUiUibUi", "nc") +BUILTIN(__builtin_amdgcn_interp_p2_f16, "hffUiUibUi", "nc") +BUILTIN(__builtin_amdgcn_interp_p1, "ffUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_interp_p2, "fffUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_interp_mov, "fUiUiUiUi", "nc") //===----------------------------------------------------------------------===// // VI+ only builtins. @@ -123,7 +152,7 @@ TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts") TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime") TARGET_BUILTIN(__builtin_amdgcn_mov_dpp, "iiIiIiIiIb", "nc", "dpp") TARGET_BUILTIN(__builtin_amdgcn_update_dpp, "iiiIiIiIiIb", "nc", "dpp") -TARGET_BUILTIN(__builtin_amdgcn_s_dcache_wb, "v", "n", "vi-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_dcache_wb, "v", "n", "gfx8-insts") //===----------------------------------------------------------------------===// // GFX9+ only builtins. @@ -135,13 +164,20 @@ TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts") // Deep learning builtins. //===----------------------------------------------------------------------===// -TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot-insts") -TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot-insts") +TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot1-insts") +TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot2-insts") +TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot1-insts") +TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot2-insts") + +//===----------------------------------------------------------------------===// +// GFX10+ only builtins. +//===----------------------------------------------------------------------===// +TARGET_BUILTIN(__builtin_amdgcn_permlane16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts") +TARGET_BUILTIN(__builtin_amdgcn_permlanex16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts") +TARGET_BUILTIN(__builtin_amdgcn_mov_dpp8, "UiUiIUi", "nc", "gfx10-insts") //===----------------------------------------------------------------------===// // Special builtins. diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def index ad778527b212..3f0765115b1c 100644 --- a/include/clang/Basic/BuiltinsARM.def +++ b/include/clang/Basic/BuiltinsARM.def @@ -1,9 +1,8 @@ //===--- BuiltinsARM.def - ARM Builtin function database ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -202,14 +201,6 @@ LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES) LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__ldrexd, "WiWiCD*", "", ALL_MS_LANGUAGES) LANGBUILTIN(_MoveFromCoprocessor, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES) LANGBUILTIN(_MoveFromCoprocessor2, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES) diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def index bb040c06fd07..18029af56ff7 100644 --- a/include/clang/Basic/BuiltinsHexagon.def +++ b/include/clang/Basic/BuiltinsHexagon.def @@ -1,9 +1,8 @@ //===-- BuiltinsHexagon.def - Hexagon Builtin function database --*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/BuiltinsLe64.def b/include/clang/Basic/BuiltinsLe64.def index 532860603c29..776492cd21b3 100644 --- a/include/clang/Basic/BuiltinsLe64.def +++ b/include/clang/Basic/BuiltinsLe64.def @@ -1,9 +1,8 @@ //==- BuiltinsLe64.def - Le64 Builtin function database ----------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/BuiltinsMips.def b/include/clang/Basic/BuiltinsMips.def index 2d217f736498..9ac75b7a174e 100644 --- a/include/clang/Basic/BuiltinsMips.def +++ b/include/clang/Basic/BuiltinsMips.def @@ -1,9 +1,8 @@ //===-- BuiltinsMips.def - Mips Builtin function database --------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/BuiltinsNEON.def b/include/clang/Basic/BuiltinsNEON.def index 241b93a915a9..b8eb5a7b6173 100644 --- a/include/clang/Basic/BuiltinsNEON.def +++ b/include/clang/Basic/BuiltinsNEON.def @@ -1,9 +1,8 @@ //===--- BuiltinsNEON.def - NEON Builtin function database ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def index 08c60979779b..70be6182c7ac 100644 --- a/include/clang/Basic/BuiltinsNVPTX.def +++ b/include/clang/Basic/BuiltinsNVPTX.def @@ -1,9 +1,8 @@ //===--- BuiltinsPTX.def - PTX Builtin function database ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,13 +18,22 @@ #endif #pragma push_macro("SM_70") -#define SM_70 "sm_70|sm_71" +#pragma push_macro("SM_72") +#pragma push_macro("SM_75") +#define SM_75 "sm_75" +#define SM_72 "sm_72|" SM_75 +#define SM_70 "sm_70|" SM_72 + #pragma push_macro("SM_60") #define SM_60 "sm_60|sm_61|sm_62|" SM_70 -#pragma push_macro("PTX61") -#define PTX61 "ptx61" #pragma push_macro("PTX60") +#pragma push_macro("PTX61") +#pragma push_macro("PTX63") +#pragma push_macro("PTX64") +#define PTX64 "ptx64" +#define PTX63 "ptx63|" PTX64 +#define PTX61 "ptx61|" PTX63 #define PTX60 "ptx60|" PTX61 #pragma push_macro("AND") @@ -667,10 +675,53 @@ TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", AND(SM_70,PTX61)) TARGET_BUILTIN(__hmma_m8n32k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX61)) +// Builtins to support integer and sub-integer WMMA instructions on sm_72/sm_75 +TARGET_BUILTIN(__bmma_m8n8k128_ld_a_b1, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__bmma_m8n8k128_ld_b_b1, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__bmma_m8n8k128_ld_c, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__bmma_m8n8k128_mma_xor_popc_b1, "vi*iC*iC*iC*Ii", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__bmma_m8n8k128_st_c_i32, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m16n16k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m32n8k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n32k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_a_s4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_a_u4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_b_s4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_b_u4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_ld_c, "vi*iC*UiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_mma_s4, "vi*iC*iC*iC*IiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_mma_u4, "vi*iC*iC*iC*IiIi", "", AND(SM_75,PTX63)) +TARGET_BUILTIN(__imma_m8n8k32_st_c_i32, "vi*iC*UiIi", "", AND(SM_75,PTX63)) + #undef BUILTIN #undef TARGET_BUILTIN #pragma pop_macro("AND") #pragma pop_macro("SM_60") #pragma pop_macro("SM_70") +#pragma pop_macro("SM_72") +#pragma pop_macro("SM_75") #pragma pop_macro("PTX60") #pragma pop_macro("PTX61") +#pragma pop_macro("PTX63") +#pragma pop_macro("PTX64") diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def index d31cb06f05f5..3b6348ad7d70 100644 --- a/include/clang/Basic/BuiltinsPPC.def +++ b/include/clang/Basic/BuiltinsPPC.def @@ -1,9 +1,8 @@ //===--- BuiltinsPPC.def - PowerPC Builtin function database ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -476,6 +475,12 @@ BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "") BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "") BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "") +// Set the floating point rounding mode +BUILTIN(__builtin_setrnd, "di", "") + +// Cache built-ins +BUILTIN(__builtin_dcbf, "vvC*", "") + // FIXME: Obviously incomplete. #undef BUILTIN diff --git a/include/clang/Basic/BuiltinsSystemZ.def b/include/clang/Basic/BuiltinsSystemZ.def index ac92286af0b5..5ea6671e623b 100644 --- a/include/clang/Basic/BuiltinsSystemZ.def +++ b/include/clang/Basic/BuiltinsSystemZ.def @@ -1,9 +1,8 @@ //===-- BuiltinsSystemZ.def - SystemZ Builtin function database -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -277,5 +276,20 @@ TARGET_BUILTIN(__builtin_s390_vfnmssb, "V4fV4fV4fV4f", "nc", "vector-enhancement TARGET_BUILTIN(__builtin_s390_vfsqsb, "V4fV4f", "nc", "vector-enhancements-1") TARGET_BUILTIN(__builtin_s390_vftcisb, "V4SiV4fIii*", "nc", "vector-enhancements-1") +// Vector-enhancements facility 2 intrinsics. +TARGET_BUILTIN(__builtin_s390_vsld, "V16UcV16UcV16UcIi", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vsrd, "V16UcV16UcV16UcIi", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrsb, "V16UcV16UcV16UcV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrsh, "V16UcV8UsV8UsV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrsf, "V16UcV4UiV4UiV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrszb, "V16UcV16UcV16UcV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrszh, "V16UcV8UsV8UsV16Uci*", "nc", "vector-enhancements-2") +TARGET_BUILTIN(__builtin_s390_vstrszf, "V16UcV4UiV4UiV16Uci*", "nc", "vector-enhancements-2") + +// Helpers to implement vec_revb. +TARGET_BUILTIN(__builtin_s390_vlbrh, "V8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vlbrf, "V4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vlbrg, "V2ULLiV2ULLi", "nc", "vector") + #undef BUILTIN #undef TARGET_BUILTIN diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def index 55931edc5ca3..63177f016ac7 100644 --- a/include/clang/Basic/BuiltinsWebAssembly.def +++ b/include/clang/Basic/BuiltinsWebAssembly.def @@ -1,9 +1,8 @@ // BuiltinsWebAssembly.def - WebAssembly builtin function database -*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -26,6 +25,13 @@ BUILTIN(__builtin_wasm_memory_size, "zIi", "n") BUILTIN(__builtin_wasm_memory_grow, "zIiz", "n") +// Bulk memory builtins +TARGET_BUILTIN(__builtin_wasm_memory_init, "vIUiIUiv*UiUi", "", "bulk-memory") +TARGET_BUILTIN(__builtin_wasm_data_drop, "vIUi", "", "bulk-memory") + +// Thread-local storage +TARGET_BUILTIN(__builtin_wasm_tls_size, "z", "nc", "bulk-memory") + // Floating point min/max BUILTIN(__builtin_wasm_min_f32, "fff", "nc") BUILTIN(__builtin_wasm_max_f32, "fff", "nc") @@ -33,8 +39,8 @@ BUILTIN(__builtin_wasm_min_f64, "ddd", "nc") BUILTIN(__builtin_wasm_max_f64, "ddd", "nc") // Exception handling builtins. -TARGET_BUILTIN(__builtin_wasm_throw, "vUiv*", "r", "exception-handling") -TARGET_BUILTIN(__builtin_wasm_rethrow, "v", "r", "exception-handling") +TARGET_BUILTIN(__builtin_wasm_throw, "vIUiv*", "r", "exception-handling") +TARGET_BUILTIN(__builtin_wasm_rethrow_in_catch, "v", "r", "exception-handling") // Atomic wait and notify. BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n") diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index b3564b957e99..a0ba0ecf36bb 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -1,9 +1,8 @@ //===--- BuiltinsX86.def - X86 Builtin function database --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -102,24 +101,24 @@ TARGET_BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_pand, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_pandn, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_por, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_pxor, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllq, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlq, "V1OiV1OiV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1Oi", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1Oi", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllqi, "V1OiV1Oii", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "ncV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "ncV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1OiV1Oii", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "ncV:64:", "mmx") @@ -138,7 +137,7 @@ TARGET_BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "nV:64:", "mmx") -TARGET_BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "nV:64:", "mmx") +TARGET_BUILTIN(__builtin_ia32_movntq, "vV1Oi*V1Oi", "nV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "ncV:64:", "mmx") TARGET_BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "ncV:64:", "mmx") @@ -165,9 +164,9 @@ TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4siIi", "ncV:64:", "mmx,sse") TARGET_BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2") TARGET_BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "ncV:64:", "mmx,sse2") TARGET_BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "ncV:64:", "mmx,sse2") -TARGET_BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "ncV:64:", "mmx,sse2") +TARGET_BUILTIN(__builtin_ia32_paddq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2") +TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1OiV2iV2i", "ncV:64:", "mmx,sse2") +TARGET_BUILTIN(__builtin_ia32_psubq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2") // MMX+SSSE3 TARGET_BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "ncV:64:", "mmx,ssse3") @@ -264,6 +263,8 @@ TARGET_BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "ncV:128:", "sse2") @@ -305,8 +306,6 @@ TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "n", "sse") TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "nh", "xmmintrin.h", ALL_LANGUAGES, "sse") TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "ncV:128:", "sse") -TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "nV:128:", "sse") -TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "nV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "nV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_sfence, "v", "n", "sse") TARGET_HEADER_BUILTIN(_mm_sfence, "v", "nh", "xmmintrin.h", ALL_LANGUAGES, "sse") @@ -325,11 +324,11 @@ TARGET_BUILTIN(__builtin_ia32_movnti, "vi*i", "n", "sse2") TARGET_BUILTIN(__builtin_ia32_pshufd, "V4iV4iIi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pshuflw, "V8sV8sIi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pshufhw, "V8sV8sIi", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psadbw128, "V2OiV16cV16c", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_shufpd, "V2dV2dV2dIi", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvtpd2dq, "V2OiV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "ncV:128:", "sse2") @@ -345,26 +344,26 @@ TARGET_BUILTIN(__builtin_ia32_mfence, "v", "n", "sse2") TARGET_HEADER_BUILTIN(_mm_mfence, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "sse2") TARGET_BUILTIN(__builtin_ia32_pause, "v", "n", "") TARGET_HEADER_BUILTIN(_mm_pause, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "") -TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2OiV4iV4i", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrlq128, "V2OiV2OiV2Oi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psllq128, "V2OiV2OiV2Oi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psllqi128, "V2OiV2Oii", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrlqi128, "V2OiV2Oii", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_pmaddwd128, "V4iV8sV8s", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_pslldqi128_byteshift, "V2LLiV2LLiIi", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_psrldqi128_byteshift, "V2LLiV2LLiIi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_pslldqi128_byteshift, "V2OiV2OiIi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrldqi128_byteshift, "V2OiV2OiIi", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "n", "sse3") TARGET_BUILTIN(__builtin_ia32_mwait, "vUiUi", "n", "sse3") @@ -389,16 +388,16 @@ TARGET_BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2OiV4iV4i", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundps, "V4fV4fIi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fIi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2dIi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundpd, "V2dV2dIi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fIc", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_dppd, "V2dV2dV2dIc", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_ptestz128, "iV2OiV2Oi", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_ptestc128, "iV2OiV2Oi", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_ptestnzc128, "iV2OiV2Oi", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16cIc", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_phminposuw128, "V8sV8s", "ncV:128:", "sse4.1") TARGET_BUILTIN(__builtin_ia32_vec_ext_v16qi, "cV16cIi", "ncV:128:", "sse4.1") @@ -427,30 +426,30 @@ TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "nc", "sse4.2") TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "nc", "sse4.2") // SSE4a -TARGET_BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "ncV:128:", "sse4a") -TARGET_BUILTIN(__builtin_ia32_extrq, "V2LLiV2LLiV16c", "ncV:128:", "sse4a") -TARGET_BUILTIN(__builtin_ia32_insertqi, "V2LLiV2LLiV2LLiIcIc", "ncV:128:", "sse4a") -TARGET_BUILTIN(__builtin_ia32_insertq, "V2LLiV2LLiV2LLi", "ncV:128:", "sse4a") +TARGET_BUILTIN(__builtin_ia32_extrqi, "V2OiV2OiIcIc", "ncV:128:", "sse4a") +TARGET_BUILTIN(__builtin_ia32_extrq, "V2OiV2OiV16c", "ncV:128:", "sse4a") +TARGET_BUILTIN(__builtin_ia32_insertqi, "V2OiV2OiV2OiIcIc", "ncV:128:", "sse4a") +TARGET_BUILTIN(__builtin_ia32_insertq, "V2OiV2OiV2Oi", "ncV:128:", "sse4a") TARGET_BUILTIN(__builtin_ia32_movntsd, "vd*V2d", "nV:128:", "sse4a") TARGET_BUILTIN(__builtin_ia32_movntss, "vf*V4f", "nV:128:", "sse4a") // AES -TARGET_BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "ncV:128:", "aes") -TARGET_BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLiIc", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesenc128, "V2OiV2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesenclast128, "V2OiV2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesdec128, "V2OiV2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesdeclast128, "V2OiV2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aesimc128, "V2OiV2Oi", "ncV:128:", "aes") +TARGET_BUILTIN(__builtin_ia32_aeskeygenassist128, "V2OiV2OiIc", "ncV:128:", "aes") // VAES -TARGET_BUILTIN(__builtin_ia32_aesenc256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes") -TARGET_BUILTIN(__builtin_ia32_aesenc512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes") -TARGET_BUILTIN(__builtin_ia32_aesenclast256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes") -TARGET_BUILTIN(__builtin_ia32_aesenclast512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes") -TARGET_BUILTIN(__builtin_ia32_aesdec256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes") -TARGET_BUILTIN(__builtin_ia32_aesdec512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes") -TARGET_BUILTIN(__builtin_ia32_aesdeclast256, "V4LLiV4LLiV4LLi", "ncV:256:", "vaes") -TARGET_BUILTIN(__builtin_ia32_aesdeclast512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f,vaes") +TARGET_BUILTIN(__builtin_ia32_aesenc256, "V4OiV4OiV4Oi", "ncV:256:", "vaes") +TARGET_BUILTIN(__builtin_ia32_aesenc512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes") +TARGET_BUILTIN(__builtin_ia32_aesenclast256, "V4OiV4OiV4Oi", "ncV:256:", "vaes") +TARGET_BUILTIN(__builtin_ia32_aesenclast512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes") +TARGET_BUILTIN(__builtin_ia32_aesdec256, "V4OiV4OiV4Oi", "ncV:256:", "vaes") +TARGET_BUILTIN(__builtin_ia32_aesdec512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes") +TARGET_BUILTIN(__builtin_ia32_aesdeclast256, "V4OiV4OiV4Oi", "ncV:256:", "vaes") +TARGET_BUILTIN(__builtin_ia32_aesdeclast512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes") // GFNI TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v16qi, "V16cV16cV16cIc", "ncV:128:", "gfni") @@ -464,11 +463,11 @@ TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v32qi, "V32cV32cV32c", "ncV:256:", "avx TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v64qi, "V64cV64cV64c", "ncV:512:", "avx512bw,gfni") // CLMUL -TARGET_BUILTIN(__builtin_ia32_pclmulqdq128, "V2LLiV2LLiV2LLiIc", "ncV:128:", "pclmul") +TARGET_BUILTIN(__builtin_ia32_pclmulqdq128, "V2OiV2OiV2OiIc", "ncV:128:", "pclmul") // VPCLMULQDQ -TARGET_BUILTIN(__builtin_ia32_pclmulqdq256, "V4LLiV4LLiV4LLiIc", "ncV:256:", "vpclmulqdq") -TARGET_BUILTIN(__builtin_ia32_pclmulqdq512, "V8LLiV8LLiV8LLiIc", "ncV:512:", "avx512f,vpclmulqdq") +TARGET_BUILTIN(__builtin_ia32_pclmulqdq256, "V4OiV4OiV4OiIc", "ncV:256:", "vpclmulqdq") +TARGET_BUILTIN(__builtin_ia32_pclmulqdq512, "V8OiV8OiV8OiIc", "ncV:512:", "avx512f,vpclmulqdq") // AVX TARGET_BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "ncV:256:", "avx") @@ -481,9 +480,9 @@ TARGET_BUILTIN(__builtin_ia32_maxpd256, "V4dV4dV4d", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_maxps256, "V8fV8fV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_minpd256, "V4dV4dV4d", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_minps256, "V8fV8fV8f", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2Oi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4Oi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_blendpd256, "V4dV4dV4dIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_blendps256, "V8fV8fV8fIi", "ncV:256:", "avx") @@ -534,21 +533,21 @@ TARGET_BUILTIN(__builtin_ia32_vtestnzcpd256, "iV4dV4d", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vtestzps256, "iV8fV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vtestcps256, "iV8fV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vtestnzcps256, "iV8fV8f", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_ptestz256, "iV4LLiV4LLi", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_ptestc256, "iV4LLiV4LLi", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_ptestnzc256, "iV4LLiV4LLi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_ptestz256, "iV4OiV4Oi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_ptestc256, "iV4OiV4Oi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_ptestnzc256, "iV4OiV4Oi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_movmskpd256, "iV4d", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_movmskps256, "iV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vzeroall, "v", "n", "avx") TARGET_BUILTIN(__builtin_ia32_vzeroupper, "v", "n", "avx") TARGET_BUILTIN(__builtin_ia32_lddqu256, "V32ccC*", "nV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2LLi", "nV:128:", "avx") +TARGET_BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2Oi", "nV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_maskloadps, "V4fV4fC*V4i", "nV:128:", "avx") -TARGET_BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4LLi", "nV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4Oi", "nV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_maskloadps256, "V8fV8fC*V8i", "nV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2LLiV2d", "nV:128:", "avx") +TARGET_BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2OiV2d", "nV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_maskstoreps, "vV4f*V4iV4f", "nV:128:", "avx") -TARGET_BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4LLiV4d", "nV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4OiV4d", "nV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_maskstoreps256, "vV8f*V8iV8f", "nV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vec_ext_v32qi, "cV32cIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vec_ext_v16hi, "sV16sIi", "ncV:256:", "avx") @@ -575,6 +574,8 @@ TARGET_BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pblendw256, "V16sV16sV16sIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "ncV:256:", "avx2") @@ -598,12 +599,12 @@ TARGET_BUILTIN(__builtin_ia32_pminsb256, "V32cV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pminsw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pminsd256, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmovmskb256, "iV32c", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmuldq256, "V4LLiV8iV8i", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmuldq256, "V4OiV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmulhrsw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmulhuw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pmulhw256, "V16sV16sV16s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmuludq256, "V4LLiV8iV8i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psadbw256, "V4LLiV32cV32c", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmuludq256, "V4OiV8iV8i", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psadbw256, "V4OiV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pshufb256, "V32cV32cV32c", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pshufd256, "V8iV8iIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pshuflw256, "V16sV16sIi", "ncV:256:", "avx2") @@ -613,68 +614,68 @@ TARGET_BUILTIN(__builtin_ia32_psignw256, "V16sV16sV16s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psignd256, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psllwi256, "V16sV16si", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psllw256, "V16sV16sV8s", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_pslldqi256_byteshift, "V4LLiV4LLiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_pslldqi256_byteshift, "V4OiV4OiIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pslldi256, "V8iV8ii", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pslld256, "V8iV8iV4i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psllqi256, "V4LLiV4LLii", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psllq256, "V4LLiV4LLiV2LLi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllqi256, "V4OiV4Oii", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllq256, "V4OiV4OiV2Oi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrawi256, "V16sV16si", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psraw256, "V16sV16sV8s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psradi256, "V8iV8ii", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrad256, "V8iV8iV4i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrldqi256_byteshift, "V4LLiV4LLiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrldqi256_byteshift, "V4OiV4OiIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlwi256, "V16sV16si", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlw256, "V16sV16sV8s", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrldi256, "V8iV8ii", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrld256, "V8iV8iV4i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrlqi256, "V4LLiV4LLii", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrlq256, "V4LLiV4LLiV2LLi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlqi256, "V4OiV4Oii", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlq256, "V4OiV4OiV2Oi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pblendd128, "V4iV4iV4iIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_pblendd256, "V8iV8iV8iIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_permdf256, "V4dV4dIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8i", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_permdi256, "V4LLiV4LLiIi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_extract128i256, "V2LLiV4LLiIi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_insert128i256, "V4LLiV4LLiV2LLiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_permti256, "V4OiV4OiV4OiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_permdi256, "V4OiV4OiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_extract128i256, "V2OiV4OiIi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_insert128i256, "V4OiV4OiV2OiIi", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_maskloadq256, "V4LLiV4LLiC*V4LLi", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskloadq256, "V4OiV4OiC*V4Oi", "nV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_maskloadd, "V4iV4iC*V4i", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_maskloadq, "V2LLiV2LLiC*V2LLi", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskloadq, "V2OiV2OiC*V2Oi", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_maskstored256, "vV8i*V8iV8i", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_maskstoreq256, "vV4LLi*V4LLiV4LLi", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskstoreq256, "vV4Oi*V4OiV4Oi", "nV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_maskstored, "vV4i*V4iV4i", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_maskstoreq, "vV2LLi*V2LLiV2LLi", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskstoreq, "vV2Oi*V2OiV2Oi", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_psllv8si, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psllv4si, "V4iV4iV4i", "ncV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psllv4di, "V4LLiV4LLiV4LLi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psllv2di, "V2LLiV2LLiV2LLi", "ncV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllv4di, "V4OiV4OiV4Oi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllv2di, "V2OiV2OiV2Oi", "ncV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrav8si, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrav4si, "V4iV4iV4i", "ncV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlv8si, "V8iV8iV8i", "ncV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlv4si, "V4iV4iV4i", "ncV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrlv4di, "V4LLiV4LLiV4LLi", "ncV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrlv2di, "V2LLiV2LLiV2LLi", "ncV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlv4di, "V4OiV4OiV4Oi", "ncV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlv2di, "V2OiV2OiV2Oi", "ncV:128:", "avx2") // GATHER TARGET_BUILTIN(__builtin_ia32_gatherd_pd, "V2dV2ddC*V4iV2dIc", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_pd256, "V4dV4ddC*V4iV4dIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_pd, "V2dV2ddC*V2LLiV2dIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_pd256, "V4dV4ddC*V4LLiV4dIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_pd, "V2dV2ddC*V2OiV2dIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_pd256, "V4dV4ddC*V4OiV4dIc", "nV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_ps, "V4fV4ffC*V4iV4fIc", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_ps256, "V8fV8ffC*V8iV8fIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_ps, "V4fV4ffC*V2LLiV4fIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_ps256, "V4fV4ffC*V4LLiV4fIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_ps, "V4fV4ffC*V2OiV4fIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_ps256, "V4fV4ffC*V4OiV4fIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherd_q, "V2LLiV2LLiLLiC*V4iV2LLiIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherd_q256, "V4LLiV4LLiLLiC*V4iV4LLiIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_q, "V2LLiV2LLiLLiC*V2LLiV2LLiIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_q256, "V4LLiV4LLiLLiC*V4LLiV4LLiIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_q, "V2OiV2OiOiC*V4iV2OiIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_q256, "V4OiV4OiOiC*V4iV4OiIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_q, "V2OiV2OiOiC*V2OiV2OiIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_q256, "V4OiV4OiOiC*V4OiV4OiIc", "nV:256:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_d, "V4iV4iiC*V4iV4iIc", "nV:128:", "avx2") TARGET_BUILTIN(__builtin_ia32_gatherd_d256, "V8iV8iiC*V8iV8iIc", "nV:256:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iiC*V2LLiV4iIc", "nV:128:", "avx2") -TARGET_BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iiC*V4LLiV4iIc", "nV:256:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iiC*V2OiV4iIc", "nV:128:", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iiC*V4OiV4iIc", "nV:256:", "avx2") // F16C TARGET_BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "ncV:128:", "f16c") @@ -691,12 +692,16 @@ TARGET_BUILTIN(__builtin_ia32_fxrstor, "vv*", "n", "fxsr") TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "n", "fxsr") // XSAVE -TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "n", "xsave") -TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "n", "xsave") -TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "n", "xsaveopt") -TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "n", "xsaves") -TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "n", "xsavec") -TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "n", "xsaves") +TARGET_BUILTIN(__builtin_ia32_xsave, "vv*UOi", "n", "xsave") +TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*UOi", "n", "xsave") +TARGET_BUILTIN(__builtin_ia32_xgetbv, "UOiUi", "n", "xsave") +TARGET_HEADER_BUILTIN(_xgetbv, "UWiUi", "nh", "immintrin.h", ALL_MS_LANGUAGES, "") +TARGET_BUILTIN(__builtin_ia32_xsetbv, "vUiUOi", "n", "xsave") +TARGET_HEADER_BUILTIN(_xsetbv, "vUiUWi", "nh", "immintrin.h", ALL_MS_LANGUAGES, "") +TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*UOi", "n", "xsaveopt") +TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*UOi", "n", "xsaves") +TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*UOi", "n", "xsavec") +TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*UOi", "n", "xsaves") // SHSTK TARGET_BUILTIN(__builtin_ia32_incsspd, "vUi", "n", "shstk") @@ -796,55 +801,55 @@ TARGET_BUILTIN(__builtin_ia32_vpmacsswd, "V4iV8sV8sV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmacswd, "V4iV8sV8sV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmacssdd, "V4iV4iV4iV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmacsdd, "V4iV4iV4iV4i", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpmacssdql, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpmacsdql, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpmacssdqh, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpmacsdqh, "V2LLiV4iV4iV2LLi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacssdql, "V2OiV4iV4iV2Oi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacsdql, "V2OiV4iV4iV2Oi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacssdqh, "V2OiV4iV4iV2Oi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacsdqh, "V2OiV4iV4iV2Oi", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmadcsswd, "V4iV8sV8sV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpmadcswd, "V4iV8sV8sV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddbw, "V8sV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddbd, "V4iV16c", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphaddbq, "V2LLiV16c", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddbq, "V2OiV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddwd, "V4iV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphaddwq, "V2LLiV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphadddq, "V2LLiV4i", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddwq, "V2OiV8s", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphadddq, "V2OiV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddubw, "V8sV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphaddubd, "V4iV16c", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphaddubq, "V2LLiV16c", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddubq, "V2OiV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphadduwd, "V4iV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphadduwq, "V2LLiV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphaddudq, "V2LLiV4i", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphadduwq, "V2OiV8s", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddudq, "V2OiV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2OiV4i", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotd, "V4iV4iV4i", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vprotq, "V2LLiV2LLiV2LLi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotq, "V2OiV2OiV2Oi", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotbi, "V16cV16cIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotwi, "V8sV8sIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vprotdi, "V4iV4iIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vprotqi, "V2LLiV2LLiIc", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotqi, "V2OiV2OiIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshlb, "V16cV16cV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshlw, "V8sV8sV8s", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshld, "V4iV4iV4i", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpshlq, "V2LLiV2LLiV2LLi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshlq, "V2OiV2OiV2Oi", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshab, "V16cV16cV16c", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshaw, "V8sV8sV8s", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpshad, "V4iV4iV4i", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpshaq, "V2LLiV2LLiV2LLi", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshaq, "V2OiV2OiV2Oi", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomub, "V16cV16cV16cIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomuw, "V8sV8sV8sIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomud, "V4iV4iV4iIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpcomuq, "V2LLiV2LLiV2LLiIc", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomuq, "V2OiV2OiV2OiIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomb, "V16cV16cV16cIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomw, "V8sV8sV8sIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpcomd, "V4iV4iV4iIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpcomq, "V2LLiV2LLiV2LLiIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpermil2pd, "V2dV2dV2dV2LLiIc", "ncV:128:", "xop") -TARGET_BUILTIN(__builtin_ia32_vpermil2pd256, "V4dV4dV4dV4LLiIc", "ncV:256:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomq, "V2OiV2OiV2OiIc", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpermil2pd, "V2dV2dV2dV2OiIc", "ncV:128:", "xop") +TARGET_BUILTIN(__builtin_ia32_vpermil2pd256, "V4dV4dV4dV4OiIc", "ncV:256:", "xop") TARGET_BUILTIN(__builtin_ia32_vpermil2ps, "V4fV4fV4fV4iIc", "ncV:128:", "xop") TARGET_BUILTIN(__builtin_ia32_vpermil2ps256, "V8fV8fV8fV8iIc", "ncV:256:", "xop") TARGET_BUILTIN(__builtin_ia32_vfrczss, "V4fV4f", "ncV:128:", "xop") @@ -859,10 +864,10 @@ TARGET_BUILTIN(__builtin_ia32_xend, "v", "n", "rtm") TARGET_BUILTIN(__builtin_ia32_xabort, "vIc", "n", "rtm") TARGET_BUILTIN(__builtin_ia32_xtest, "i", "n", "rtm") -BUILTIN(__builtin_ia32_rdpmc, "ULLii", "") -BUILTIN(__builtin_ia32_rdtsc, "ULLi", "") -BUILTIN(__rdtsc, "ULLi", "") -BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "") +BUILTIN(__builtin_ia32_rdpmc, "UOii", "") +BUILTIN(__builtin_ia32_rdtsc, "UOi", "") +BUILTIN(__rdtsc, "UOi", "") +BUILTIN(__builtin_ia32_rdtscp, "UOiUi*", "") TARGET_BUILTIN(__builtin_ia32_rdpid, "Ui", "n", "rdpid") @@ -923,35 +928,35 @@ TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "ncV:512:", "av TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pabsd512, "V16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pabsq512, "V8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pabsq512, "V8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmaxsd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmaxsq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmaxsq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmaxud512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmaxuq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmaxuq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pminsd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pminsq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pminsq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pminud512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pminuq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8LLiV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8LLiV16iV16i", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pminuq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8OiV16iV16i", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8OiV16iV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8OiOiC*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadaps512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadupd512_mask, "V8ddC*V8dUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadapd512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vLLi*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vOi*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storedqusi512_mask, "vi*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeupd512_mask, "vd*V8dUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeapd512_mask, "vV8d*V8dUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeups512_mask, "vf*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeaps512_mask, "vV16f*V16fUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_alignq512, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_alignq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_alignd512, "V16iV16iV16iIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_alignd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_alignd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_alignq128, "V2LLiV2LLiV2LLiIi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_alignq256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_alignq128, "V2OiV2OiV2OiIi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_alignq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "ncV:512:", "avx512f") @@ -968,76 +973,76 @@ TARGET_BUILTIN(__builtin_ia32_vpdpwssds128, "V4iV4iV4iV4i", "ncV:128:", "avx512v TARGET_BUILTIN(__builtin_ia32_vpdpwssds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni") TARGET_BUILTIN(__builtin_ia32_vpdpwssds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni") -TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2LLiUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2LLiV2LLivC*V2LLiUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4dvC*V4LLiUcIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4LLiV4LLivC*V4LLiUcIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4fvC*V2LLiUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4ivC*V2LLiUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4fvC*V4LLiUcIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4ivC*V4LLiUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2OiUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2OiV2OivC*V2OiUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4dvC*V4OiUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V4OiV4OivC*V4OiUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4fvC*V2OiUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4ivC*V2OiUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4fvC*V4OiUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4ivC*V4OiUcIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2dvC*V4iUcIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2LLiV2LLivC*V4iUcIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V2OiV2OivC*V4iUcIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4dvC*V4iUcIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4LLiV4LLivC*V4iUcIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V4OiV4OivC*V4iUcIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4fvC*V4iUcIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4ivC*V4iUcIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8fvC*V8iUcIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8ivC*V8iUcIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*V16iUsIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUcIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUcIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8OiUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8OiUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8OiV8OivC*V8iUcIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*V16iUsIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUcIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8OiV8OivC*V8OiUcIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8OiUcIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8dIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8OiV8dIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8OiV8fIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8OiIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiIi", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8OiV8OiIi", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8OiV8iIi", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "nV:512:", "avx512pf") TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "nV:512:", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLivC*IiIi", "nV:512:", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLivC*IiIi", "nV:512:", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8OivC*IiIi", "nV:512:", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8OivC*IiIi", "nV:512:", "avx512pf") TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "nV:512:", "avx512pf") TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "nV:512:", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*IiIi", "nV:512:", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf") TARGET_BUILTIN(__builtin_ia32_knotqi, "UcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_knotsi, "UiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_knotdi, "ULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_knotdi, "UOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2LLiV2LLiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2OiV2OiIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_cmpw128_mask, "UcV8sV8sIiUc", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIiUi", "ncV:256:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4LLiV4LLiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4OiV4OiIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIiUs", "ncV:256:", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_cmpb512_mask, "ULLiV64cV64cIiULLi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_cmpb512_mask, "UOiV64cV64cIiUOi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8LLiV8LLiIiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8OiV8OiIiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2LLiV2LLiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2OiV2OiIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_ucmpw128_mask, "UcV8sV8sIiUc", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIiUi", "ncV:256:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4LLiV4LLiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4OiV4OiIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIiUs", "ncV:256:", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_ucmpb512_mask, "ULLiV64cV64cIiULLi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_ucmpb512_mask, "UOiV64cV64cIiUOi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8OiV8OiIiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pabsb512, "V64cV64c", "ncV:512:", "avx512bw") @@ -1050,6 +1055,8 @@ TARGET_BUILTIN(__builtin_ia32_paddsb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_paddsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_paddusb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_paddusw512, "V32sV32sV32s", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgb512, "V64cV64cV64c", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaxsb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaxsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaxub512, "V64cV64cV64c", "ncV:512:", "avx512bw") @@ -1064,21 +1071,21 @@ TARGET_BUILTIN(__builtin_ia32_psubsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psubusb512, "V64cV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psubusw512, "V32sV32sV32s", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpconflictsi_128_mask, "V4iV4iV4iUc", "ncV:128:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpconflictsi_256_mask, "V8iV8iV8iUc", "ncV:256:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512cd") -TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512cd") +TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128, "V2OiV2Oi", "ncV:128:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256, "V4OiV4Oi", "ncV:256:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictsi_128, "V4iV4i", "ncV:128:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictsi_256, "V8iV8i", "ncV:256:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512, "V8OiV8Oi", "ncV:512:", "avx512cd") +TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512, "V16iV16i", "ncV:512:", "avx512cd") TARGET_BUILTIN(__builtin_ia32_vplzcntd_512, "V16iV16i", "ncV:512:", "avx512cd") -TARGET_BUILTIN(__builtin_ia32_vplzcntq_512, "V8LLiV8LLi", "ncV:512:", "avx512cd") +TARGET_BUILTIN(__builtin_ia32_vplzcntq_512, "V8OiV8Oi", "ncV:512:", "avx512cd") TARGET_BUILTIN(__builtin_ia32_vpopcntd_128, "V4iV4i", "ncV:128:", "avx512vpopcntdq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpopcntq_128, "V2LLiV2LLi", "ncV:128:", "avx512vpopcntdq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpopcntq_128, "V2OiV2Oi", "ncV:128:", "avx512vpopcntdq,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpopcntd_256, "V8iV8i", "ncV:256:", "avx512vpopcntdq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpopcntq_256, "V4LLiV4LLi", "ncV:256:", "avx512vpopcntdq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpopcntq_256, "V4OiV4Oi", "ncV:256:", "avx512vpopcntdq,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpopcntd_512, "V16iV16i", "ncV:512:", "avx512vpopcntdq") -TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8LLiV8LLi", "ncV:512:", "avx512vpopcntdq") +TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8OiV8Oi", "ncV:512:", "avx512vpopcntdq") TARGET_BUILTIN(__builtin_ia32_vpopcntb_128, "V16cV16c", "ncV:128:", "avx512vl,avx512bitalg") TARGET_BUILTIN(__builtin_ia32_vpopcntw_128, "V8sV8s", "ncV:128:", "avx512vl,avx512bitalg") @@ -1089,7 +1096,7 @@ TARGET_BUILTIN(__builtin_ia32_vpopcntw_512, "V32sV32s", "ncV:512:", "avx512bital TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb128_mask, "UsV16cV16cUs", "ncV:128:", "avx512vl,avx512bitalg") TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb256_mask, "UiV32cV32cUi", "ncV:256:", "avx512vl,avx512bitalg") -TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb512_mask, "ULLiV64cV64cULLi", "ncV:512:", "avx512bitalg") +TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb512_mask, "UOiV64cV64cUOi", "ncV:512:", "avx512bitalg") TARGET_BUILTIN(__builtin_ia32_pmulhrsw512, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmulhuw512, "V32sV32sV32s", "ncV:512:", "avx512bw") @@ -1122,8 +1129,8 @@ TARGET_BUILTIN(__builtin_ia32_minsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", TARGET_BUILTIN(__builtin_ia32_compressdf128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressdf256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_compressdi128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_compressdi256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressdi128_mask, "V2OiV2OiV2OiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressdi256_mask, "V4OiV4OiV4OiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compresshi128_mask, "V8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_compresshi256_mask, "V16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2") @@ -1136,8 +1143,8 @@ TARGET_BUILTIN(__builtin_ia32_compresssi128_mask, "V4iV4iV4iUc", "ncV:128:", "av TARGET_BUILTIN(__builtin_ia32_compresssi256_mask, "V8iV8iV8iUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressstoredf128_mask, "vV2d*V2dUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressstoredf256_mask, "vV4d*V4dUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_compressstoredi128_mask, "vV2LLi*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_compressstoredi256_mask, "vV4LLi*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoredi128_mask, "vV2Oi*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoredi256_mask, "vV4Oi*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressstorehi128_mask, "vV8s*V8sUc", "nV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_compressstorehi256_mask, "vV16s*V16sUs", "nV:256:", "avx512vl,avx512vbmi2") @@ -1161,8 +1168,8 @@ TARGET_BUILTIN(__builtin_ia32_cvttps2udq128_mask, "V4iV4fV4iUc", "ncV:128:", "av TARGET_BUILTIN(__builtin_ia32_cvttps2udq256_mask, "V8iV8fV8iUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expanddf128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expanddf256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_expanddi256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2OiV2OiV2OiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expanddi256_mask, "V4OiV4OiV4OiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expandhi128_mask, "V8sV8sV8sUc", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_expandhi256_mask, "V16sV16sV16sUs", "ncV:256:", "avx512vl,avx512vbmi2") @@ -1171,8 +1178,8 @@ TARGET_BUILTIN(__builtin_ia32_expandqi256_mask, "V32cV32cV32cUi", "ncV:256:", "a TARGET_BUILTIN(__builtin_ia32_expandloaddf128_mask, "V2dV2dC*V2dUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expandloaddf256_mask, "V4dV4dC*V4dUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_expandloaddi128_mask, "V4iV2LLiC*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_expandloaddi256_mask, "V4LLiV4LLiC*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloaddi128_mask, "V4iV2OiC*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloaddi256_mask, "V4OiV4OiC*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expandloadhi128_mask, "V8sV8sC*V8sUc", "nV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_expandloadhi256_mask, "V16sV16sC*V16sUs", "nV:256:", "avx512vl,avx512vbmi2") @@ -1191,16 +1198,16 @@ TARGET_BUILTIN(__builtin_ia32_getexppd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx5 TARGET_BUILTIN(__builtin_ia32_getexppd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_getexpps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_getexpps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pabsq128, "V2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pabsq256, "V4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxsq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxsq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxuq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmaxuq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminsq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminsq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminuq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pminuq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pabsq128, "V2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pabsq256, "V4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxsq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxsq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxuq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxuq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminsq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminsq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminuq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminuq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rndscalepd_128_mask, "V2dV2dIiV2dUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rndscalepd_256_mask, "V4dV4dIiV4dUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rndscaleps_128_mask, "V4fV4fIiV4fUc", "ncV:128:", "avx512vl") @@ -1210,18 +1217,18 @@ TARGET_BUILTIN(__builtin_ia32_scalefpd256_mask, "V4dV4dV4dV4dUc", "ncV:256:", "a TARGET_BUILTIN(__builtin_ia32_scalefps128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scalefps256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vv*UcV2LLiV2dIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vv*UcV2LLiV2LLiIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vv*UcV4LLiV4dIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vv*UcV4LLiV4LLiIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vv*UcV2LLiV4fIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vv*UcV2LLiV4iIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vv*UcV4LLiV4fIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vv*UcV4LLiV4iIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vv*UcV2OiV2dIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vv*UcV2OiV2OiIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vv*UcV4OiV4dIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vv*UcV4OiV4OiIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vv*UcV2OiV4fIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vv*UcV2OiV4iIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vv*UcV4OiV4fIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vv*UcV4OiV4iIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vv*UcV4iV2dIi", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vv*UcV4iV2LLiIi", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vv*UcV4iV2OiIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vv*UcV4iV4dIi", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vv*UcV4iV4LLiIi", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vv*UcV4iV4OiIi", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vv*UcV4iV4fIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vv*UcV4iV4iIi", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vv*UcV8iV8fIi", "nV:256:", "avx512vl") @@ -1230,15 +1237,15 @@ TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vv*UcV8iV8iIi", "nV:256:", "avx512 TARGET_BUILTIN(__builtin_ia32_vpermi2vard128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2vard256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2vard512, "V16iV16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128, "V2dV2dV2LLiV2d", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpermi2varpd256, "V4dV4dV4LLiV4d", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512, "V8dV8dV8LLiV8d", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128, "V2dV2dV2OiV2d", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varpd256, "V4dV4dV4OiV4d", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512, "V8dV8dV8OiV8d", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermi2varps128, "V4fV4fV4iV4f", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2varps256, "V8fV8fV8iV8f", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2varps512, "V16fV16fV16iV16f", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vpermi2varq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpermi2varq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpermi2varq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermi2varq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermi2varqi128, "V16cV16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2varqi256, "V32cV32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpermi2varqi512, "V64cV64cV64cV64c", "ncV:512:", "avx512vbmi") @@ -1249,9 +1256,9 @@ TARGET_BUILTIN(__builtin_ia32_vpermi2varhi512, "V32sV32sV32sV32s", "ncV:512:", " TARGET_BUILTIN(__builtin_ia32_vpshldd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldq128, "V2LLiV2LLiV2LLiIi", "ncV:128:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldq256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldq512, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldq128, "V2OiV2OiV2OiIi", "ncV:128:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2") @@ -1259,9 +1266,9 @@ TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512v TARGET_BUILTIN(__builtin_ia32_vpshldvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2") @@ -1269,9 +1276,9 @@ TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx5 TARGET_BUILTIN(__builtin_ia32_vpshrdvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2") @@ -1279,9 +1286,9 @@ TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx5 TARGET_BUILTIN(__builtin_ia32_vpshrdd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdq128, "V2LLiV2LLiV2LLiIi", "ncV:128:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdq256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl,avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_vpshrdq512, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdq128, "V2OiV2OiV2OiIi", "ncV:128:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl,avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_vpshrdq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_vpshrdw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2") @@ -1289,26 +1296,24 @@ TARGET_BUILTIN(__builtin_ia32_vpshrdw512, "V32sV32sV32sIi", "ncV:512:", "avx512v TARGET_BUILTIN(__builtin_ia32_pmovswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovuswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovwb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_cvtpd2qq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtpd2qq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2qq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2qq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2uqq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2uqq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2ps128_mask, "V4fV2LLiV4fUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2ps256_mask, "V4fV4LLiV4fUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2qq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2qq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2qq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2qq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2uqq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2uqq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps128_mask, "V4fV2LLiV4fUc", "ncV:128:", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps256_mask, "V4fV4LLiV4fUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2qq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2qq256_mask, "V4OiV4dV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq256_mask, "V4OiV4dV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2qq128_mask, "V2OiV4fV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2qq256_mask, "V4OiV4fV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2uqq128_mask, "V2OiV4fV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2uqq256_mask, "V4OiV4fV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2ps128_mask, "V4fV2OiV4fUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2qq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2qq256_mask, "V4OiV4dV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq256_mask, "V4OiV4dV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2qq128_mask, "V2OiV4fV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2qq256_mask, "V4OiV4fV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2uqq128_mask, "V2OiV4fV2OiUc", "ncV:128:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2uqq256_mask, "V4OiV4fV4OiUc", "ncV:256:", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps128_mask, "V4fV2OiV4fUc", "ncV:128:", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_rangepd128_mask, "V2dV2dV2dIiV2dUc", "ncV:128:", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_rangepd256_mask, "V4dV4dV4dIiV4dUc", "ncV:256:", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_rangeps128_mask, "V4fV4fV4fIiV4fUc", "ncV:128:", "avx512vl,avx512dq") @@ -1326,46 +1331,46 @@ TARGET_BUILTIN(__builtin_ia32_pmovswb256_mask, "V16cV16sV16cUs", "ncV:256:", "av TARGET_BUILTIN(__builtin_ia32_pmovuswb128_mask, "V16cV8sV16cUc", "ncV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovuswb256_mask, "V16cV16sV16cUs", "ncV:256:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovwb128_mask, "V16cV8sV16cUc", "ncV:128:", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2pd512_mask, "V8dV8LLiV8dUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2ps512_mask, "V8fV8LLiV8fUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2qq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvttps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd512_mask, "V8dV8LLiV8dUcIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps512_mask, "V8fV8LLiV8fUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2uqq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2pd512_mask, "V8dV8OiV8dUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2ps512_mask, "V8fV8OiV8fUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2qq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2qq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2uqq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd512_mask, "V8dV8OiV8dUcIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps512_mask, "V8fV8OiV8fUcIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_prold512, "V16iV16iIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_prolq512, "V8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_prolq512, "V8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_prold128, "V4iV4iIi", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prold256, "V8iV8iIi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prolq128, "V2LLiV2LLiIi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prolq256, "V4LLiV4LLiIi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolq128, "V2OiV2OiIi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolq256, "V4OiV4OiIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prolvd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_prolvq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_prolvq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_prord512, "V16iV16iIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_prorq512, "V8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_prorq512, "V8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_prolvd128, "V4iV4iV4i", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prolvd256, "V8iV8iV8i", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prolvq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prolvq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolvq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolvq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prord128, "V4iV4iIi", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prord256, "V8iV8iIi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prorq128, "V2LLiV2LLiIi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prorq256, "V4LLiV4LLiIi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorq128, "V2OiV2OiIi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorq256, "V4OiV4OiIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prorvd512, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_prorvq512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_prorvq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_prorvd128, "V4iV4iV4i", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_prorvd256, "V8iV8iV8i", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prorvq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_prorvq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorvq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorvq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pshufhw512, "V32sV32sIi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pshuflw512, "V32sV32sIi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psllv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw") @@ -1374,53 +1379,53 @@ TARGET_BUILTIN(__builtin_ia32_psllwi512, "V32sV32si", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psllv16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_psllv8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_pslldi512, "V16iV16ii", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8LLiV8LLii", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8OiV8Oii", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrlv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrlv16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_psrlv8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_psrldi512, "V16iV16ii", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8LLiV8LLii", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8OiV8Oii", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrav32hi, "V32sV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrav16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_psrav8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl") -TARGET_BUILTIN(__builtin_ia32_psravq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_psravq256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psravq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psravq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_psraw512, "V32sV32sV8s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrawi512, "V32sV32si", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrlw512, "V32sV32sV8s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psrlwi512, "V32sV32si", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pslldqi512_byteshift, "V8LLiV8LLiIi", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_psrldqi512_byteshift, "V8LLiV8LLiIi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pslldqi512_byteshift, "V8OiV8OiIi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_psrldqi512_byteshift, "V8OiV8OiIi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_movdqa32load128_mask, "V4iV4i*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_movdqa32load256_mask, "V8iV8i*V8iUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_movdqa32load512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_movdqa32store512_mask, "vV16i*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_movdqa64load512_mask, "V8LLiV8LLiC*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_movdqa64store512_mask, "vV8LLi*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa64load512_mask, "V8OiV8OiC*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa64store512_mask, "vV8Oi*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_movdqa32store128_mask, "vV4i*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_movdqa32store256_mask, "vV8i*V8iUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2LLiV2LLiC*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4LLiV4LLiC*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2LLi*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4LLi*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512ifma") -TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512, "V8LLiV8LLiV8LLiV8LLi", "ncV:512:", "avx512ifma") -TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512ifma,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512ifma,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128, "V2LLiV2LLiV2LLiV2LLi", "ncV:128:", "avx512ifma,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256, "V4LLiV4LLiV4LLiV4LLi", "ncV:256:", "avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2OiV2OiC*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4OiV4OiC*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2Oi*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4Oi*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512ifma") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512ifma") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512ifma,avx512vl") TARGET_BUILTIN(__builtin_ia32_vcomisd, "iV2dV2dIiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcomiss, "iV4fV4fIiIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_kunpckdi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kunpckdi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kunpcksi, "UiUiUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_loaddquhi512_mask, "V32sV32s*V32sUi", "nV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64c*V64cULLi", "nV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_mask, "V8dV8dV8dV8LLiIiUcIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_maskz, "V8dV8dV8dV8LLiIiUcIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64c*V64cUOi", "nV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_mask, "V8dV8dV8dV8OiIiUcIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_maskz, "V8dV8dV8dV8OiIiUcIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_fixupimmps512_mask, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_fixupimmps512_maskz, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_fixupimmsd_mask, "V2dV2dV2dV2LLiIiUcIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_fixupimmsd_maskz, "V2dV2dV2dV2LLiIiUcIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmsd_mask, "V2dV2dV2dV2OiIiUcIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmsd_maskz, "V2dV2dV2dV2OiIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_fixupimmss_mask, "V4fV4fV4fV4iIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_fixupimmss_maskz, "V4fV4fV4fV4iIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_getexpsd128_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f") @@ -1431,10 +1436,10 @@ TARGET_BUILTIN(__builtin_ia32_loaddquhi128_mask, "V8sV8s*V8sUc", "nV:128:", "avx TARGET_BUILTIN(__builtin_ia32_loaddquhi256_mask, "V16sV16s*V16sUs", "nV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_loaddquqi128_mask, "V16cV16c*V16cUs", "nV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_loaddquqi256_mask, "V32cV32c*V32cUi", "nV:256:", "avx512bw,avx512vl") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_mask, "V2dV2dV2dV2LLiIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_maskz, "V2dV2dV2dV2LLiIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_mask, "V4dV4dV4dV4LLiIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_maskz, "V4dV4dV4dV4LLiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_mask, "V2dV2dV2dV2OiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_maskz, "V2dV2dV2dV2OiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_mask, "V4dV4dV4dV4OiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_maskz, "V4dV4dV4dV4OiIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_fixupimmps128_mask, "V4fV4fV4fV4iIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_fixupimmps128_maskz, "V4fV4fV4fV4iIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_fixupimmps256_mask, "V8fV8fV8fV8iIiUc", "ncV:256:", "avx512vl") @@ -1445,8 +1450,8 @@ TARGET_BUILTIN(__builtin_ia32_loadapd256_mask, "V4dV4d*V4dUc", "nV:256:", "avx51 TARGET_BUILTIN(__builtin_ia32_loadaps128_mask, "V4fV4f*V4fUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loadss128_mask, "V4fV4f*V4fUc", "nV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_loadaps256_mask, "V8fV8f*V8fUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2LLiV2LLi*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4LLiV4LLi*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2OiV2Oi*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4OiV4Oi*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loaddqusi128_mask, "V4iV4i*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loaddqusi256_mask, "V8iV8i*V8iUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loadupd128_mask, "V2dV2d*V2dUc", "nV:128:", "avx512vl") @@ -1454,7 +1459,7 @@ TARGET_BUILTIN(__builtin_ia32_loadupd256_mask, "V4dV4d*V4dUc", "nV:256:", "avx51 TARGET_BUILTIN(__builtin_ia32_loadups128_mask, "V4fV4f*V4fUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_loadups256_mask, "V8fV8f*V8fUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storedquhi512_mask, "vV32s*V32sUi", "nV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_storedquqi512_mask, "vV64c*V64cULLi", "nV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_storedquqi512_mask, "vV64c*V64cUOi", "nV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_storedquhi128_mask, "vV8s*V8sUc", "nV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_storedquhi256_mask, "vV16s*V16sUs", "nV:256:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_storedquqi128_mask, "vV16c*V16cUs", "nV:128:", "avx512vl,avx512bw") @@ -1465,8 +1470,8 @@ TARGET_BUILTIN(__builtin_ia32_storeapd256_mask, "vV4d*V4dUc", "nV:256:", "avx512 TARGET_BUILTIN(__builtin_ia32_storeaps128_mask, "vV4f*V4fUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storess128_mask, "vV4f*V4fUc", "nV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_storeaps256_mask, "vV8f*V8fUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_storedqudi128_mask, "vV2LLi*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_storedqudi256_mask, "vV4LLi*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_storedqudi128_mask, "vV2Oi*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_storedqudi256_mask, "vV4Oi*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storedqusi128_mask, "vV4i*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storedqusi256_mask, "vV8i*V8iUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_storeupd128_mask, "vV2d*V2dUc", "nV:128:", "avx512vl") @@ -1479,8 +1484,8 @@ TARGET_BUILTIN(__builtin_ia32_rcp14ps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx51 TARGET_BUILTIN(__builtin_ia32_rcp14ps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_vplzcntd_128, "V4iV4i", "ncV:128:", "avx512cd,avx512vl") TARGET_BUILTIN(__builtin_ia32_vplzcntd_256, "V8iV8i", "ncV:256:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vplzcntq_128, "V2LLiV2LLi", "ncV:128:", "avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_vplzcntq_256, "V4LLiV4LLi", "ncV:256:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vplzcntq_128, "V2OiV2Oi", "ncV:128:", "avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vplzcntq_256, "V4OiV4Oi", "ncV:256:", "avx512cd,avx512vl") TARGET_BUILTIN(__builtin_ia32_vcvtsd2si32, "iV2dIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi32, "UiV2dIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtss2si32, "iV4fIi", "ncV:128:", "avx512f") @@ -1491,7 +1496,7 @@ TARGET_BUILTIN(__builtin_ia32_vcvttss2si32, "iV4fIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvttss2usi32, "UiV4fIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermilpd512, "V8dV8dIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermilps512, "V16fV16fIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermilvarps512, "V16fV16fV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rndscalesd_round_mask, "V2dV2dV2dV2dUcIiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi", "ncV:128:", "avx512f") @@ -1500,58 +1505,58 @@ TARGET_BUILTIN(__builtin_ia32_scalefps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512 TARGET_BUILTIN(__builtin_ia32_scalefsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_scalefss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psradi512, "V16iV16ii", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8LLiV8LLii", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psraq128, "V2LLiV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_psraq256, "V4LLiV4LLiV2LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_psraqi128, "V2LLiV2LLii", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_psraqi256, "V4LLiV4LLii", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8OiV8Oii", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psraq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraq256, "V4OiV4OiV2Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraqi128, "V2OiV2Oii", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraqi256, "V4OiV4Oii", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pslld512, "V16iV16iV4i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psllq512, "V8LLiV8LLiV2LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psllq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psllv16si, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrad512, "V16iV16iV4i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psraq512, "V8LLiV8LLiV2LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psraq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrav16si, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrld512, "V16iV16iV4i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8LLiV8LLiV2LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_psrlv16si, "V16iV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pternlogd512_mask, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pternlogd512_maskz, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8LLiV8LLiV8LLiV8LLiIiUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pternlogq512_maskz, "V8LLiV8LLiV8LLiV8LLiIiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8OiV8OiV8OiV8OiIiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pternlogq512_maskz, "V8OiV8OiV8OiV8OiIiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pternlogd128_mask, "V4iV4iV4iV4iIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pternlogd128_maskz, "V4iV4iV4iV4iIiUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pternlogd256_mask, "V8iV8iV8iV8iIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pternlogd256_maskz, "V8iV8iV8iV8iIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pternlogq128_mask, "V2LLiV2LLiV2LLiV2LLiIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pternlogq128_maskz, "V2LLiV2LLiV2LLiV2LLiIiUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pternlogq256_mask, "V4LLiV4LLiV4LLiV4LLiIiUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pternlogq256_maskz, "V4LLiV4LLiV4LLiV4LLiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq128_mask, "V2OiV2OiV2OiV2OiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq128_maskz, "V2OiV2OiV2OiV2OiIiUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq256_mask, "V4OiV4OiV4OiV4OiIiUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq256_maskz, "V4OiV4OiV4OiV4OiIiUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_shuf_f32x4, "V16fV16fV16fIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shuf_f64x2, "V8dV8dV8dIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shuf_i32x4, "V16iV16iV16iIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_shuf_i64x2, "V8LLiV8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_shuf_i64x2, "V8OiV8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shufpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shufps512, "V16fV16fV16fIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_shuf_f32x4_256, "V8fV8fV8fIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_shuf_f64x2_256, "V4dV4dV4dIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_shuf_i32x4_256, "V8iV8iV8iIi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_shuf_i64x2_256, "V4LLiV4LLiV4LLiIi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_shuf_i64x2_256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_sqrtsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_sqrtss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rsqrt14pd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rsqrt14pd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rsqrt14ps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_rsqrt14ps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtb2mask512, "ULLiV64c", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_cvtmask2b512, "V64cULLi", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_cvtb2mask512, "UOiV64c", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_cvtmask2b512, "V64cUOi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cvtmask2w512, "V32sUi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cvtd2mask512, "UsV16i", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtmask2d512, "V16iUs", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtmask2q512, "V8LLiUc", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtq2mask512, "UcV8LLi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtmask2q512, "V8OiUc", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtq2mask512, "UcV8Oi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtb2mask128, "UsV16c", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtb2mask256, "UiV32c", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtmask2b128, "V16cUs", "ncV:128:", "avx512bw,avx512vl") @@ -1562,21 +1567,21 @@ TARGET_BUILTIN(__builtin_ia32_cvtd2mask128, "UcV4i", "ncV:128:", "avx512dq,avx51 TARGET_BUILTIN(__builtin_ia32_cvtd2mask256, "UcV8i", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtmask2d128, "V4iUc", "ncV:128:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtmask2d256, "V8iUc", "ncV:256:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2LLiUc", "ncV:128:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4LLiUc", "ncV:256:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi", "ncV:128:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi", "ncV:256:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2OiUc", "ncV:128:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4OiUc", "ncV:256:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2Oi", "ncV:128:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4Oi", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovsdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovsdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovsdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqb512_mask, "V16cV8LLiV16cUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqb512mem_mask, "vV16c*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqd512_mask, "V8iV8LLiV8iUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqd512mem_mask, "vV8i*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqw512_mask, "V8sV8LLiV8sUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovsqw512mem_mask, "vV8s*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovsdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovsdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovswb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw") @@ -1587,29 +1592,29 @@ TARGET_BUILTIN(__builtin_ia32_pmovsdw128_mask, "V8sV4iV8sUc", "ncV:128:", "avx51 TARGET_BUILTIN(__builtin_ia32_pmovsdw128mem_mask, "vV8s*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovsdw256_mask, "V8sV8iV8sUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovsdw256mem_mask, "vV8s*V8iUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqb128_mask, "V16cV2LLiV16cUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqb128mem_mask, "vV16c*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqb256_mask, "V16cV4LLiV16cUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqb256mem_mask, "vV16c*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqd128_mask, "V4iV2LLiV4iUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqd128mem_mask, "vV4i*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqd256_mask, "V4iV4LLiV4iUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqd256mem_mask, "vV4i*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqw128_mask, "V8sV2LLiV8sUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqw128mem_mask, "vV8s*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqw256_mask, "V8sV4LLiV8sUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovsqw256mem_mask, "vV8s*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb128_mask, "V16cV2OiV16cUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb128mem_mask, "vV16c*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb256_mask, "V16cV4OiV16cUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb256mem_mask, "vV16c*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd128_mask, "V4iV2OiV4iUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd128mem_mask, "vV4i*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd256_mask, "V4iV4OiV4iUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd256mem_mask, "vV4i*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw128_mask, "V8sV2OiV8sUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw128mem_mask, "vV8s*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw256_mask, "V8sV4OiV8sUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw256mem_mask, "vV8s*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovusdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovuswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovusdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovusdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqb512_mask, "V16cV8LLiV16cUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqb512mem_mask, "vV16c*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqd512_mask, "V8iV8LLiV8iUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqd512mem_mask, "vV8i*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqw512_mask, "V8sV8LLiV8sUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovusqw512mem_mask, "vV8s*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovusdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovuswb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw") @@ -1620,29 +1625,29 @@ TARGET_BUILTIN(__builtin_ia32_pmovusdw128_mask, "V8sV4iV8sUc", "ncV:128:", "avx5 TARGET_BUILTIN(__builtin_ia32_pmovusdw128mem_mask, "vV8s*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusdw256_mask, "V8sV8iV8sUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusdw256mem_mask, "vV8s*V8iUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqb128_mask, "V16cV2LLiV16cUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqb128mem_mask, "vV16c*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqb256_mask, "V16cV4LLiV16cUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqb256mem_mask, "vV16c*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqd128_mask, "V4iV2LLiV4iUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqd128mem_mask, "vV4i*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqd256_mask, "V4iV4LLiV4iUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqd256mem_mask, "vV4i*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqw128_mask, "V8sV2LLiV8sUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqw128mem_mask, "vV8s*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqw256_mask, "V8sV4LLiV8sUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovusqw256mem_mask, "vV8s*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb128_mask, "V16cV2OiV16cUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb128mem_mask, "vV16c*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb256_mask, "V16cV4OiV16cUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb256mem_mask, "vV16c*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd128_mask, "V4iV2OiV4iUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd128mem_mask, "vV4i*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd256_mask, "V4iV4OiV4iUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd256mem_mask, "vV4i*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw128_mask, "V8sV2OiV8sUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw128mem_mask, "vV8s*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw256_mask, "V8sV4OiV8sUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw256mem_mask, "vV8s*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovwb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8LLiV16cUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8LLiV8iUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8LLiUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8LLiV8sUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovwb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl") @@ -1653,35 +1658,35 @@ TARGET_BUILTIN(__builtin_ia32_pmovdw128_mask, "V8sV4iV8sUc", "ncV:128:", "avx512 TARGET_BUILTIN(__builtin_ia32_pmovdw128mem_mask, "vV8s*V4iUc", "nV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovdw256_mask, "V8sV8iV8sUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovdw256mem_mask, "vV8s*V8iUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqb128_mask, "V16cV2LLiV16cUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqb128mem_mask, "vV16c*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqb256_mask, "V16cV4LLiV16cUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqb256mem_mask, "vV16c*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqd128_mask, "V4iV2LLiV4iUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqd128mem_mask, "vV4i*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqd256mem_mask, "vV4i*V4LLiUc", "nV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2LLiV8sUc", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2LLiUc", "nV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4LLiV8sUc", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4LLiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb128_mask, "V16cV2OiV16cUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb128mem_mask, "vV16c*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb256_mask, "V16cV4OiV16cUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb256mem_mask, "vV16c*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd128_mask, "V4iV2OiV4iUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd128mem_mask, "vV4i*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd256mem_mask, "vV4i*V4OiUc", "nV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2OiV8sUc", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2OiUc", "nV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4OiV8sUc", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4OiUc", "nV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_extractf32x8_mask, "V8fV16fIiV8fUc", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_extractf64x2_512_mask, "V2dV8dIiV2dUc", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_extracti32x8_mask, "V8iV16iIiV8iUc", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2LLiV8LLiIiV2LLiUc", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2OiV8OiIiV2OiUc", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_extracti32x4_mask, "V4iV16iIiV4iUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4LLiV8LLiIiV4LLiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4OiV8OiIiV4OiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_extractf64x2_256_mask, "V2dV4dIiV2dUc", "ncV:256:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_extracti64x2_256_mask, "V2LLiV4LLiIiV2LLiUc", "ncV:256:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_extracti64x2_256_mask, "V2OiV4OiIiV2OiUc", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_extractf32x4_256_mask, "V4fV8fIiV4fUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_extracti32x4_256_mask, "V4iV8iIiV4iUc", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_insertf32x8, "V16fV16fV8fIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_insertf64x2_512, "V8dV8dV2dIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_inserti32x8, "V16iV16iV8iIi", "ncV:512:", "avx512dq") -TARGET_BUILTIN(__builtin_ia32_inserti64x2_512, "V8LLiV8LLiV2LLiIi", "ncV:512:", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_inserti64x2_512, "V8OiV8OiV2OiIi", "ncV:512:", "avx512dq") TARGET_BUILTIN(__builtin_ia32_insertf64x4, "V8dV8dV4dIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_inserti64x4, "V8LLiV8LLiV4LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_inserti64x4, "V8OiV8OiV4OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_insertf64x2_256, "V4dV4dV2dIi", "ncV:256:", "avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_inserti64x2_256, "V4LLiV4LLiV2LLiIi", "ncV:256:", "avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_inserti64x2_256, "V4OiV4OiV2OiIi", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_insertf32x4_256, "V8fV8fV4fIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_inserti32x4_256, "V8iV8iV4iIi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_insertf32x4, "V16fV16fV4fIi", "ncV:512:", "avx512f") @@ -1703,10 +1708,10 @@ TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask3, "V2dV2dV2dV2dUcIi", "ncV:128:", " TARGET_BUILTIN(__builtin_ia32_vfmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vfmsubss3_mask3, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permdf512, "V8dV8dIi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_permdi512, "V8LLiV8LLiIi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_permdi512, "V8OiV8OiIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permvarhi512, "V32sV32sV32s", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_permvardf512, "V8dV8dV8LLi", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_permvardi512, "V8LLiV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_permvardf512, "V8dV8dV8Oi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_permvardi512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permvarsf512, "V16fV16fV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permvarsi512, "V16iV16iV16i", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_permvarqi512, "V64cV64cV64c", "ncV:512:", "avx512vbmi") @@ -1714,8 +1719,8 @@ TARGET_BUILTIN(__builtin_ia32_permvarqi128, "V16cV16cV16c", "ncV:128:", "avx512v TARGET_BUILTIN(__builtin_ia32_permvarqi256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl") TARGET_BUILTIN(__builtin_ia32_permvarhi128, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_permvarhi256, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl") -TARGET_BUILTIN(__builtin_ia32_permvardf256, "V4dV4dV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_permvardi256, "V4LLiV4LLiV4LLi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvardf256, "V4dV4dV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvardi256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_fpclasspd128_mask, "UcV2dIiUc", "ncV:128:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_fpclasspd256_mask, "UcV4dIiUc", "ncV:256:", "avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_fpclassps128_mask, "UcV4fIiUc", "ncV:128:", "avx512dq,avx512vl") @@ -1727,87 +1732,87 @@ TARGET_BUILTIN(__builtin_ia32_fpclassss_mask, "UcV4fIiUc", "ncV:128:", "avx512dq TARGET_BUILTIN(__builtin_ia32_kaddqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kaddhi, "UsUsUs", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kaddsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kadddi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kadddi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kandqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kandhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kandsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kanddi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kanddi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kandnqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kandnhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kandnsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kandndi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kandndi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_korqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_korhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_korsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kordi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kordi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kortestcqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kortestzqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kortestchi, "iUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kortestcsi, "iUiUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kortestzsi, "iUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kortestcdi, "iULLiULLi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kortestzdi, "iULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kortestcdi, "iUOiUOi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kortestzdi, "iUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ktestcqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestzqi, "iUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestchi, "iUsUs", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestzhi, "iUsUs", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_ktestcsi, "iUiUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_ktestzsi, "iUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_ktestcdi, "iULLiULLi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_ktestzdi, "iULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_ktestcdi, "iUOiUOi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_ktestzdi, "iUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kxnorqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kxnorsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kxnordi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kxnordi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kxorqi, "UcUcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kxorsi, "UiUiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kxordi, "ULLiULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kxordi, "UOiUOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kshiftliqi, "UcUcIUi", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kshiftlihi, "UsUsIUi", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kshiftlisi, "UiUiIUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kshiftlidi, "ULLiULLiIUi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kshiftlidi, "UOiUOiIUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kshiftriqi, "UcUcIUi", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kshiftrihi, "UsUsIUi", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kshiftrisi, "UiUiIUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kshiftridi, "ULLiULLiIUi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kshiftridi, "UOiUOiIUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_kmovb, "UcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_kmovw, "UsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_kmovd, "UiUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_kmovq, "ULLiULLi", "nc", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_kmovq, "UOiUOi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_palignr512, "V64cV64cV64cIi", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_dbpsadbw128, "V8sV16cV16cIi", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_dbpsadbw256, "V16sV32cV32cIi", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_dbpsadbw512, "V32sV64cV64cIi", "ncV:512:", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_psadbw512, "V8LLiV64cV64c", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_psadbw512, "V8OiV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_compressdf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_compressdi512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_compressdi512_mask, "V8OiV8OiV8OiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compresshi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_compressqi512_mask, "V64cV64cV64cULLi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_compressqi512_mask, "V64cV64cV64cUOi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_compresssf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compresssi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cmpsd_mask, "UcV2dV2dIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cmpss_mask, "UcV4fV4fIiUcIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_pshufd512, "V16iV16iIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expanddf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_expanddi512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_expanddi512_mask, "V8OiV8OiV8OiUc", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandhi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_expandqi512_mask, "V64cV64cV64cULLi", "ncV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_expandqi512_mask, "V64cV64cV64cUOi", "ncV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_expandloaddf512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_expandloaddi512_mask, "V8LLiV8LLiC*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_expandloaddi512_mask, "V8OiV8OiC*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandloadhi512_mask, "V32sV32sC*V32sUi", "nV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_expandloadqi512_mask, "V64cV64cC*V64cULLi", "nV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_expandloadqi512_mask, "V64cV64cC*V64cUOi", "nV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_expandloadsf512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandloadsi512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandsf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_expandsi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cvtps2pd512_mask, "V8dV8fV8dUcIi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compressstoredf512_mask, "vV8d*V8dUc", "nV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_compressstoredi512_mask, "vV8LLi*V8LLiUc", "nV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_compressstoredi512_mask, "vV8Oi*V8OiUc", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compressstorehi512_mask, "vV32s*V32sUi", "nV:512:", "avx512vbmi2") -TARGET_BUILTIN(__builtin_ia32_compressstoreqi512_mask, "vV64c*V64cULLi", "nV:512:", "avx512vbmi2") +TARGET_BUILTIN(__builtin_ia32_compressstoreqi512_mask, "vV64c*V64cUOi", "nV:512:", "avx512vbmi2") TARGET_BUILTIN(__builtin_ia32_compressstoresf512_mask, "vV16f*V16fUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_compressstoresi512_mask, "vV16i*V16iUs", "nV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtph2ps_mask, "V4fV8sV4fUc", "ncV:128:", "avx512vl") @@ -1825,19 +1830,38 @@ TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512, "V64cV64cV64c", "ncV:512:", "av TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128, "V16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl") +// bf16 intrinsics +TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_128, "V8sV4fV4f", "ncV:128:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_256, "V16sV8fV8f", "ncV:256:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_512, "V32sV16fV16f", "ncV:512:", "avx512bf16") +TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_128_mask, "V8sV4fV8sUc", "ncV:128:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_256_mask, "V8sV8fV8sUc", "ncV:256:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_512_mask, "V16sV16fV16sUs", "ncV:512:", "avx512bf16") +TARGET_BUILTIN(__builtin_ia32_dpbf16ps_128, "V4fV4fV4iV4i", "ncV:128:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_dpbf16ps_256, "V8fV8fV8iV8i", "ncV:256:", "avx512bf16,avx512vl") +TARGET_BUILTIN(__builtin_ia32_dpbf16ps_512, "V16fV16fV16iV16i", "ncV:512:", "avx512bf16") +TARGET_BUILTIN(__builtin_ia32_cvtsbf162ss_32, "fUs", "nc", "avx512bf16") + +TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_512, "vV8OiV8OiUc*Uc*", "nV:512:", "avx512vp2intersect") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_256, "vV4OiV4OiUc*Uc*", "nV:256:", "avx512vp2intersect,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_128, "vV2OiV2OiUc*Uc*", "nV:128:", "avx512vp2intersect,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_512, "vV16iV16iUs*Us*", "nV:512:", "avx512vp2intersect") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_256, "vV8iV8iUc*Uc*", "nV:256:", "avx512vp2intersect,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_128, "vV4iV4iUc*Uc*", "nV:128:", "avx512vp2intersect,avx512vl") + // generic select intrinsics TARGET_BUILTIN(__builtin_ia32_selectb_128, "V16cUsV16cV16c", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_selectb_256, "V32cUiV32cV32c", "ncV:256:", "avx512bw,avx512vl") -TARGET_BUILTIN(__builtin_ia32_selectb_512, "V64cULLiV64cV64c", "ncV:512:", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_selectb_512, "V64cUOiV64cV64c", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_selectw_128, "V8sUcV8sV8s", "ncV:128:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_selectw_256, "V16sUsV16sV16s", "ncV:256:", "avx512bw,avx512vl") TARGET_BUILTIN(__builtin_ia32_selectw_512, "V32sUiV32sV32s", "ncV:512:", "avx512bw") TARGET_BUILTIN(__builtin_ia32_selectd_128, "V4iUcV4iV4i", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_selectd_256, "V8iUcV8iV8i", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_selectd_512, "V16iUsV16iV16i", "ncV:512:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_selectq_128, "V2LLiUcV2LLiV2LLi", "ncV:128:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_selectq_256, "V4LLiUcV4LLiV4LLi", "ncV:256:", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_selectq_512, "V8LLiUcV8LLiV8LLi", "ncV:512:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_selectq_128, "V2OiUcV2OiV2Oi", "ncV:128:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_selectq_256, "V4OiUcV4OiV4Oi", "ncV:256:", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_selectq_512, "V8OiUcV8OiV8Oi", "ncV:512:", "avx512f") TARGET_BUILTIN(__builtin_ia32_selectps_128, "V4fUcV4fV4f", "ncV:128:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_selectps_256, "V8fUcV8fV8f", "ncV:256:", "avx512vl") TARGET_BUILTIN(__builtin_ia32_selectps_512, "V16fUsV16fV16f", "ncV:512:", "avx512f") @@ -1872,6 +1896,10 @@ TARGET_BUILTIN(__builtin_ia32_ptwrite32, "vUi", "n", "ptwrite") // INVPCID TARGET_BUILTIN(__builtin_ia32_invpcid, "vUiv*", "nc", "invpcid") +// ENQCMD +TARGET_BUILTIN(__builtin_ia32_enqcmd, "Ucv*vC*", "n", "enqcmd") +TARGET_BUILTIN(__builtin_ia32_enqcmds, "Ucv*vC*", "n", "enqcmd") + // MSVC TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") diff --git a/include/clang/Basic/BuiltinsX86_64.def b/include/clang/Basic/BuiltinsX86_64.def index 5e8cce5c6e5e..56051af55e7d 100644 --- a/include/clang/Basic/BuiltinsX86_64.def +++ b/include/clang/Basic/BuiltinsX86_64.def @@ -1,9 +1,8 @@ //===--- BuiltinsX86_64.def - X86-64 Builtin function database --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -44,65 +43,65 @@ TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h" TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "cx16") -TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "ULLi", "n", "") -TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vULLi", "n", "") -TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "ncV:128:", "sse") -TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "LLiV4f", "ncV:128:", "sse") -TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "LLiV2d", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_movnti64, "vLLi*LLi", "n", "sse2") -TARGET_BUILTIN(__builtin_ia32_vec_ext_v2di, "LLiV2LLiIi", "ncV:128:", "sse2") -TARGET_BUILTIN(__builtin_ia32_vec_set_v2di, "V2LLiV2LLiLLiIi", "ncV:128:", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "nc", "sse4.2") -TARGET_BUILTIN(__builtin_ia32_vec_ext_v4di, "LLiV4LLiIi", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_vec_set_v4di, "V4LLiV4LLiLLiIi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "UOi", "n", "") +TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vUOi", "n", "") +TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "OiV4f", "ncV:128:", "sse") +TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "OiV4f", "ncV:128:", "sse") +TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "OiV2d", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "OiV2d", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_movnti64, "vOi*Oi", "n", "sse2") +TARGET_BUILTIN(__builtin_ia32_vec_ext_v2di, "OiV2OiIi", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_vec_set_v2di, "V2OiV2OiOiIi", "ncV:128:", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_crc32di, "UOiUOiUOi", "nc", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_vec_ext_v4di, "OiV4OiIi", "ncV:256:", "avx") +TARGET_BUILTIN(__builtin_ia32_vec_set_v4di, "V4OiV4OiOiIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "n", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "n", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "UOi", "n", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "n", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "n", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "UOi", "n", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "n", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "n", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vUOi", "n", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "n", "fsgsbase") -TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "n", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vUOi", "n", "fsgsbase") TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "n", "fxsr") TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "n", "fxsr") -TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "n", "xsave") -TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "n", "xsave") -TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "n", "xsaveopt") -TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "n", "xsaves") -TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "n", "xsavec") -TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "n", "xsaves") -TARGET_BUILTIN(__builtin_ia32_incsspq, "vULLi", "n", "shstk") -TARGET_BUILTIN(__builtin_ia32_rdsspq, "ULLiULLi", "n", "shstk") -TARGET_BUILTIN(__builtin_ia32_wrssq, "vULLiv*", "n", "shstk") -TARGET_BUILTIN(__builtin_ia32_wrussq, "vULLiv*", "n", "shstk") -TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "n", "") -TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "n", "") -TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "n", "rdrnd") -TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "n", "rdseed") -TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "ULLiULLi", "nc", "lzcnt") -TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "nc", "bmi") -TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "ULLiULLi", "nc", "") -TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "nc", "bmi2") -TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "nc", "bmi2") -TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "nc", "bmi2") -TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "nc", "tbm") -TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcULLiUiUi", "n", "lwp") -TARGET_BUILTIN(__builtin_ia32_lwpval64, "vULLiUiUi", "n", "lwp") -TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "ULLiV4fIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "LLiV2dIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "ULLiV2dIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "LLiV4fIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "ULLiV4fIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dLLiIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fLLiIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi", "ncV:128:", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*UOi", "n", "xsave") +TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*UOi", "n", "xsave") +TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*UOi", "n", "xsaveopt") +TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*UOi", "n", "xsaves") +TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*UOi", "n", "xsavec") +TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*UOi", "n", "xsaves") +TARGET_BUILTIN(__builtin_ia32_incsspq, "vUOi", "n", "shstk") +TARGET_BUILTIN(__builtin_ia32_rdsspq, "UOiUOi", "n", "shstk") +TARGET_BUILTIN(__builtin_ia32_wrssq, "vUOiv*", "n", "shstk") +TARGET_BUILTIN(__builtin_ia32_wrussq, "vUOiv*", "n", "shstk") +TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcUOiUOiUOi*", "n", "") +TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcUOiUOiUOi*", "n", "") +TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiUOi*", "n", "rdrnd") +TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiUOi*", "n", "rdseed") +TARGET_BUILTIN(__builtin_ia32_lzcnt_u64, "UOiUOi", "nc", "lzcnt") +TARGET_BUILTIN(__builtin_ia32_bextr_u64, "UOiUOiUOi", "nc", "bmi") +TARGET_BUILTIN(__builtin_ia32_tzcnt_u64, "UOiUOi", "nc", "") +TARGET_BUILTIN(__builtin_ia32_bzhi_di, "UOiUOiUOi", "nc", "bmi2") +TARGET_BUILTIN(__builtin_ia32_pdep_di, "UOiUOiUOi", "nc", "bmi2") +TARGET_BUILTIN(__builtin_ia32_pext_di, "UOiUOiUOi", "nc", "bmi2") +TARGET_BUILTIN(__builtin_ia32_bextri_u64, "UOiUOiIUOi", "nc", "tbm") +TARGET_BUILTIN(__builtin_ia32_lwpins64, "UcUOiUiUi", "n", "lwp") +TARGET_BUILTIN(__builtin_ia32_lwpval64, "vUOiUiUi", "n", "lwp") +TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "OiV2dIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "UOiV2dIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "OiV4fIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "UOiV4fIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "OiV2dIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "UOiV2dIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "OiV4fIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "UOiV4fIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dOiIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fOiIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dUOiIi", "ncV:128:", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fUOiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_directstore_u64, "vULi*ULi", "n", "movdiri") -TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vULLi", "n", "ptwrite") +TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vUOi", "n", "ptwrite") #undef BUILTIN #undef TARGET_BUILTIN diff --git a/include/clang/Basic/BuiltinsXCore.def b/include/clang/Basic/BuiltinsXCore.def index 672d20578a63..c99b7ced1351 100644 --- a/include/clang/Basic/BuiltinsXCore.def +++ b/include/clang/Basic/BuiltinsXCore.def @@ -1,9 +1,8 @@ //===--- BuiltinsXCore.def - XCore Builtin function database ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/CapturedStmt.h b/include/clang/Basic/CapturedStmt.h index 324e1b1d3d09..029e1144eaf7 100644 --- a/include/clang/Basic/CapturedStmt.h +++ b/include/clang/Basic/CapturedStmt.h @@ -1,9 +1,8 @@ //===--- CapturedStmt.h - Types for CapturedStmts ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/CharInfo.h b/include/clang/Basic/CharInfo.h index e6c5e90d346c..8577475fab06 100644 --- a/include/clang/Basic/CharInfo.h +++ b/include/clang/Basic/CharInfo.h @@ -1,9 +1,8 @@ //===--- clang/Basic/CharInfo.h - Classifying ASCII Characters --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/CodeGenOptions.def b/include/clang/Basic/CodeGenOptions.def index ed2387b9a2e2..cd7a84548765 100644 --- a/include/clang/Basic/CodeGenOptions.def +++ b/include/clang/Basic/CodeGenOptions.def @@ -1,9 +1,8 @@ //===--- CodeGenOptions.def - Code generation option database ----- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -62,6 +61,7 @@ CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled. +CODEGENOPT(EnableDebugEntryValues, 1, 0) ///< Emit call site parameter dbg info CODEGENOPT(IndirectTlsSegRefs, 1, 0) ///< Set when -mno-tls-direct-seg-refs ///< is specified. CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls. @@ -225,6 +225,7 @@ CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition. CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled. +CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled. CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled. CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled. @@ -260,8 +261,6 @@ CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should ///< contain explicit imports for ///< anonymous namespaces -ENUM_CODEGENOPT(SplitDwarfMode, DwarfFissionKind, 2, NoFission) ///< DWARF fission mode to use. - CODEGENOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the ///< skeleton CU to allow for symbolication ///< of inline stack frames without .dwo files. diff --git a/include/clang/Basic/CodeGenOptions.h b/include/clang/Basic/CodeGenOptions.h index ec6eda7fb788..4e9025d2fea9 100644 --- a/include/clang/Basic/CodeGenOptions.h +++ b/include/clang/Basic/CodeGenOptions.h @@ -1,9 +1,8 @@ //===--- CodeGenOptions.h ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -54,6 +53,7 @@ public: enum VectorLibrary { NoLibrary, // Don't use any vector library. Accelerate, // Use the Accelerate framework. + MASSV, // IBM MASS vector library. SVML // Intel short vector math library. }; @@ -71,8 +71,6 @@ public: LocalExecTLSModel }; - enum DwarfFissionKind { NoFission, SplitFileFission, SingleFileFission }; - /// Clang versions with different platform ABI conformance. enum class ClangABI { /// Attempt to be ABI-compatible with code generated by Clang 3.8.x @@ -101,6 +99,7 @@ public: ProfileClangInstr, // Clang instrumentation to generate execution counts // to use with PGO. ProfileIRInstr, // IR level PGO instrumentation in LLVM. + ProfileCSIRInstr, // IR level PGO context sensitive instrumentation in LLVM. }; enum EmbedBitcodeKind { @@ -184,10 +183,13 @@ public: /// file, for example with -save-temps. std::string MainFileName; - /// The name for the split debug info file that we'll break out. This is used - /// in the backend for setting the name in the skeleton cu. + /// The name for the split debug info file used for the DW_AT_[GNU_]dwo_name + /// attribute in the skeleton CU. std::string SplitDwarfFile; + /// Output filename for the split debug info, not used in the skeleton CU. + std::string SplitDwarfOutput; + /// The name of the relocation model to use. llvm::Reloc::Model RelocationModel; @@ -204,8 +206,8 @@ public: /// A list of linker options to embed in the object file. std::vector<std::string> LinkerOptions; - /// Name of the profile file to use as output for -fprofile-instr-generate - /// and -fprofile-generate. + /// Name of the profile file to use as output for -fprofile-instr-generate, + /// -fprofile-generate, and -fcs-profile-generate. std::string InstrProfileOutput; /// Name of the profile file to use with -fprofile-sample-use. @@ -238,6 +240,17 @@ public: /// records. std::string OptRecordFile; + /// The regex that filters the passes that should be saved to the optimization + /// records. + std::string OptRecordPasses; + + /// The format used for serializing remarks (default: YAML) + std::string OptRecordFormat; + + /// The name of the partition that symbols are assigned to, specified with + /// -fsymbol-partition (see https://lld.llvm.org/Partitions.html). + std::string SymbolPartition; + /// Regular expression to select optimizations for which we should enable /// optimization remarks. Transformation passes whose name matches this /// expression (and support this feature), will emit a diagnostic @@ -288,6 +301,9 @@ public: std::vector<std::string> DefaultFunctionAttrs; + /// List of dynamic shared object files to be loaded as pass plugins. + std::vector<std::string> PassPlugins; + public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) @@ -316,6 +332,11 @@ public: return getProfileInstr() == ProfileIRInstr; } + /// Check if CS IR level profile instrumentation is on. + bool hasProfileCSIRInstr() const { + return getProfileInstr() == ProfileCSIRInstr; + } + /// Check if Clang profile use is on. bool hasProfileClangUse() const { return getProfileUse() == ProfileClangInstr; @@ -323,9 +344,12 @@ public: /// Check if IR level profile use is on. bool hasProfileIRUse() const { - return getProfileUse() == ProfileIRInstr; + return getProfileUse() == ProfileIRInstr || + getProfileUse() == ProfileCSIRInstr; } + /// Check if CSIR profile use is on. + bool hasProfileCSIRUse() const { return getProfileUse() == ProfileCSIRInstr; } }; } // end namespace clang diff --git a/include/clang/Basic/CommentOptions.h b/include/clang/Basic/CommentOptions.h index 6cc9cf6b199c..7d142fc32f51 100644 --- a/include/clang/Basic/CommentOptions.h +++ b/include/clang/Basic/CommentOptions.h @@ -1,9 +1,8 @@ //===- CommentOptions.h - Options for parsing comments ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/Cuda.h b/include/clang/Basic/Cuda.h index 0575e703338e..ef5d24dcf888 100644 --- a/include/clang/Basic/Cuda.h +++ b/include/clang/Basic/Cuda.h @@ -1,9 +1,8 @@ //===--- Cuda.h - Utilities for compiling CUDA code ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -12,6 +11,7 @@ namespace llvm { class StringRef; +class VersionTuple; } // namespace llvm namespace clang { @@ -25,12 +25,12 @@ enum class CudaVersion { CUDA_91, CUDA_92, CUDA_100, - LATEST = CUDA_100, + CUDA_101, + LATEST = CUDA_101, }; const char *CudaVersionToString(CudaVersion V); - -// No string -> CudaVersion conversion function because there's no canonical -// spelling of the various CUDA versions. +// Input is "Major.Minor" +CudaVersion CudaStringToVersion(llvm::StringRef S); enum class CudaArch { UNKNOWN, @@ -64,7 +64,11 @@ enum class CudaArch { GFX902, GFX904, GFX906, + GFX908, GFX909, + GFX1010, + GFX1011, + GFX1012, LAST, }; const char *CudaArchToString(CudaArch A); @@ -104,6 +108,17 @@ CudaVersion MinVersionForCudaArch(CudaArch A); /// Get the latest CudaVersion that supports the given CudaArch. CudaVersion MaxVersionForCudaArch(CudaArch A); +// Various SDK-dependent features that affect CUDA compilation +enum class CudaFeature { + // CUDA-9.2+ uses a new API for launching kernels. + CUDA_USES_NEW_LAUNCH, + // CUDA-10.1+ needs explicit end of GPU binary registration. + CUDA_USES_FATBIN_REGISTER_END, +}; + +bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature); +bool CudaFeatureEnabled(CudaVersion, CudaFeature); + } // namespace clang #endif diff --git a/include/clang/Basic/DebugInfoOptions.h b/include/clang/Basic/DebugInfoOptions.h index f3be0fe52d31..91d3332103e9 100644 --- a/include/clang/Basic/DebugInfoOptions.h +++ b/include/clang/Basic/DebugInfoOptions.h @@ -1,9 +1,8 @@ //===--- DebugInfoOptions.h - Debug Info Emission Types ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index a184b480f7c0..2d3fa6b6147f 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -41,6 +41,7 @@ def Named : Decl<"named declarations", 1>; def IndirectField : DDecl<Value>; def Binding : DDecl<Value>; def OMPDeclareReduction : DDecl<Value>, DeclContext; + def OMPDeclareMapper : DDecl<Value>, DeclContext; def Declarator : DDecl<Value, "declarators", 1>; def Field : DDecl<Declarator, "non-static data members">; def ObjCIvar : DDecl<Field>; @@ -69,6 +70,7 @@ def Named : Decl<"named declarations", 1>; def TypeAliasTemplate : DDecl<RedeclarableTemplate>; def TemplateTemplateParm : DDecl<Template>; def BuiltinTemplate : DDecl<Template>; + def Concept : DDecl<Template>; def Using : DDecl<Named>; def UsingPack : DDecl<Named>; def UsingShadow : DDecl<Named>; @@ -97,6 +99,7 @@ def Captured : Decl, DeclContext; def ClassScopeFunctionSpecialization : Decl; def Import : Decl; def OMPThreadPrivate : Decl; +def OMPAllocate : Decl; def OMPRequires : Decl; def Empty : Decl; diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index a516721ace6d..5a707007e463 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -1,9 +1,8 @@ //===- Diagnostic.h - C Language Family Diagnostic Handling -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -26,6 +25,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Error.h" #include <cassert> #include <cstdint> #include <limits> @@ -210,8 +210,8 @@ private: // Used by __extension__ unsigned char AllExtensionsSilenced = 0; - // Suppress diagnostics after a fatal error? - bool SuppressAfterFatalError = true; + // Treat fatal errors like errors. + bool FatalsAsError = false; // Suppress all diagnostics. bool SuppressAllDiagnostics = false; @@ -615,9 +615,11 @@ public: void setErrorsAsFatal(bool Val) { GetCurDiagState()->ErrorsAsFatal = Val; } bool getErrorsAsFatal() const { return GetCurDiagState()->ErrorsAsFatal; } - /// When set to true (the default), suppress further diagnostics after - /// a fatal error. - void setSuppressAfterFatalError(bool Val) { SuppressAfterFatalError = Val; } + /// \brief When set to true, any fatal error reported is made an error. + /// + /// This setting takes precedence over the setErrorsAsFatal setting above. + void setFatalsAsError(bool Val) { FatalsAsError = Val; } + bool getFatalsAsError() const { return FatalsAsError; } /// When set to true mask warnings that come from system headers. void setSuppressSystemWarnings(bool Val) { @@ -1302,6 +1304,12 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc, return DiagnosticBuilder(this); } +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + llvm::Error &&E) { + DB.AddString(toString(std::move(E))); + return DB; +} + inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) { return Report(SourceLocation(), DiagID); } diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td index 2a0f1e6385d3..48ba8c0f469f 100644 --- a/include/clang/Basic/Diagnostic.td +++ b/include/clang/Basic/Diagnostic.td @@ -1,9 +1,8 @@ //===--- Diagnostic.td - C Language Family Diagnostic Handling ------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/DiagnosticAST.h b/include/clang/Basic/DiagnosticAST.h index b0e9178d9b0b..afe5f62e2012 100644 --- a/include/clang/Basic/DiagnosticAST.h +++ b/include/clang/Basic/DiagnosticAST.h @@ -1,9 +1,8 @@ //===--- DiagnosticAST.h - Diagnostics for the AST library ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index c39673a44ac0..23502152b4ac 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticASTKinds.td - libast diagnostics ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -13,7 +12,8 @@ let Component = "AST" in { def note_expr_divide_by_zero : Note<"division by zero">; def note_constexpr_invalid_cast : Note< "%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of" - " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression">; + " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression" + "%select{| in C++ standards before C++2a||}0">; def note_constexpr_invalid_downcast : Note< "cannot cast object of dynamic type %0 to type %1">; def note_constexpr_overflow : Note< @@ -32,7 +32,19 @@ def note_constexpr_invalid_inhctor : Note< def note_constexpr_no_return : Note< "control reached end of constexpr function">; def note_constexpr_virtual_call : Note< - "cannot evaluate virtual function call in a constant expression">; + "cannot evaluate call to virtual function in a constant expression " + "in C++ standards before C++2a">; +def note_constexpr_pure_virtual_call : Note< + "pure virtual function %q0 called">; +def note_constexpr_polymorphic_unknown_dynamic_type : Note< + "%select{||||virtual function called on|dynamic_cast applied to|" + "typeid applied to}0 object '%1' whose dynamic type is not constant">; +def note_constexpr_dynamic_cast_to_reference_failed : Note< + "reference dynamic_cast failed: %select{" + "static type %1 of operand is a non-public base class of dynamic type %2|" + "dynamic type %2 of operand does not have a base class of type %3|" + "%3 is an ambiguous base class of dynamic type %2 of operand|" + "%3 is a non-public base class of dynamic type %2 of operand}0">; def note_constexpr_virtual_base : Note< "cannot construct object of type %0 with virtual base class " "in a constant expression">; @@ -43,6 +55,8 @@ def note_constexpr_non_global : Note< "%select{temporary|%3}2 is not a constant expression">; def note_constexpr_uninitialized : Note< "%select{|sub}0object of type %1 is not initialized">; +def note_constexpr_subobject_declared_here : Note< + "subobject declared here">; def note_constexpr_array_index : Note<"cannot refer to element %0 of " "%select{array of %2 element%plural{1:|:s}2|non-array object}1 " "in a constant expression">; @@ -68,19 +82,21 @@ def note_constexpr_past_end : Note< "%select{temporary|%2}1 is not a constant expression">; def note_constexpr_past_end_subobject : Note< "cannot %select{access base class of|access derived class of|access field of|" - "access array element of|ERROR|call member function on|" + "access array element of|ERROR|" "access real component of|access imaginary component of}0 " "pointer past the end of object">; +def note_non_null_attribute_failed : Note< + "null passed to a callee that requires a non-null argument">; def note_constexpr_null_subobject : Note< "cannot %select{access base class of|access derived class of|access field of|" "access array element of|perform pointer arithmetic on|" - "call member function on|access real component of|" + "access real component of|" "access imaginary component of}0 null pointer">; def note_constexpr_var_init_non_constant : Note< "initializer of %0 is not a constant expression">; def note_constexpr_typeid_polymorphic : Note< "typeid applied to expression of polymorphic type %0 is " - "not allowed in a constant expression">; + "not allowed in a constant expression in C++ standards before C++2a">; def note_constexpr_void_comparison : Note< "comparison between unequal pointers to void has unspecified result">; def note_constexpr_temporary_here : Note<"temporary created here">; @@ -97,11 +113,14 @@ def note_constexpr_this : Note< "%select{|implicit }0use of 'this' pointer is only allowed within the " "evaluation of a call to a 'constexpr' member function">; def note_constexpr_lifetime_ended : Note< - "%select{read of|assignment to|increment of|decrement of}0 " + "%select{read of|assignment to|increment of|decrement of|member call on|" + "dynamic_cast of|typeid applied to}0 " "%select{temporary|variable}1 whose lifetime has ended">; def note_constexpr_access_uninit : Note< - "%select{read of|assignment to|increment of|decrement of}0 " - "object outside its lifetime is not allowed in a constant expression">; + "%select{read of|assignment to|increment of|decrement of|member call on|" + "dynamic_cast of|typeid applied to}0 " + "%select{object outside its lifetime|uninitialized object}1 " + "is not allowed in a constant expression">; def note_constexpr_use_uninit_reference : Note< "use of reference outside its lifetime " "is not allowed in a constant expression">; @@ -109,12 +128,14 @@ def note_constexpr_modify_const_type : Note< "modification of object of const-qualified type %0 is not allowed " "in a constant expression">; def note_constexpr_access_volatile_type : Note< - "%select{read of|assignment to|increment of|decrement of}0 " + "%select{read of|assignment to|increment of|decrement of|<ERROR>|<ERROR>}0 " "volatile-qualified type %1 is not allowed in a constant expression">; def note_constexpr_access_volatile_obj : Note< - "%select{read of|assignment to|increment of|decrement of}0 volatile " - "%select{temporary|object %2|member %2}1 is not allowed in " + "%select{read of|assignment to|increment of|decrement of|<ERROR>|<ERROR>}0 " + "volatile %select{temporary|object %2|member %2}1 is not allowed in " "a constant expression">; +def note_constexpr_volatile_here : Note< + "volatile %select{temporary created|object declared|member declared}0 here">; def note_constexpr_ltor_mutable : Note< "read of mutable member %0 is not allowed in a constant expression">; def note_constexpr_ltor_non_const_int : Note< @@ -124,23 +145,31 @@ def note_constexpr_ltor_non_constexpr : Note< def note_constexpr_ltor_incomplete_type : Note< "read of incomplete type %0 is not allowed in a constant expression">; def note_constexpr_access_null : Note< - "%select{read of|assignment to|increment of|decrement of}0 " + "%select{read of|assignment to|increment of|decrement of|member call on|" + "dynamic_cast of|typeid applied to}0 " "dereferenced null pointer is not allowed in a constant expression">; def note_constexpr_access_past_end : Note< - "%select{read of|assignment to|increment of|decrement of}0 " + "%select{read of|assignment to|increment of|decrement of|member call on|" + "dynamic_cast of|typeid applied to}0 " "dereferenced one-past-the-end pointer is not allowed in a constant expression">; def note_constexpr_access_unsized_array : Note< - "%select{read of|assignment to|increment of|decrement of}0 " - "pointer to element of array without known bound " + "%select{read of|assignment to|increment of|decrement of|member call on|" + "dynamic_cast of|typeid applied to}0 " + "element of array without known bound " "is not allowed in a constant expression">; def note_constexpr_access_inactive_union_member : Note< - "%select{read of|assignment to|increment of|decrement of}0 " + "%select{read of|assignment to|increment of|decrement of|member call on|" + "dynamic_cast of|typeid applied to}0 " "member %1 of union with %select{active member %3|no active member}2 " "is not allowed in a constant expression">; def note_constexpr_access_static_temporary : Note< - "%select{read of|assignment to|increment of|decrement of}0 temporary " + "%select{read of|assignment to|increment of|decrement of|member call on|" + "dynamic_cast of|typeid applied to}0 temporary " "is not allowed in a constant expression outside the expression that " "created the temporary">; +def note_constexpr_access_unreadable_object : Note< + "%select{read of|assignment to|increment of|decrement of|member call on|" + "dynamic_cast of|typeid applied to}0 object '%1' whose value is not known">; def note_constexpr_modify_global : Note< "a constant expression cannot modify an object that is visible outside " "that expression">; @@ -186,6 +215,19 @@ def note_constexpr_memcpy_unsupported : Note< "size to copy (%4) is not a multiple of size of element type %3 (%5)|" "source is not a contiguous array of at least %4 elements of type %3|" "destination is not a contiguous array of at least %4 elements of type %3}2">; +def note_constexpr_bit_cast_unsupported_type : Note< + "constexpr bit_cast involving type %0 is not yet supported">; +def note_constexpr_bit_cast_unsupported_bitfield : Note< + "constexpr bit_cast involving bit-field is not yet supported">; +def note_constexpr_bit_cast_invalid_type : Note< + "bit_cast %select{from|to}0 a %select{|type with a }1" + "%select{union|pointer|member pointer|volatile|reference}2 " + "%select{type|member}1 is not allowed in a constant expression">; +def note_constexpr_bit_cast_invalid_subtype : Note< + "invalid type %0 is a %select{member|base}1 of %2">; +def note_constexpr_bit_cast_indet_dest : Note< + "indeterminate value can only initialize an object of type 'unsigned char'" + "%select{, 'char',|}1 or 'std::byte'; %0 is invalid">; def warn_integer_constant_overflow : Warning< "overflow in expression; result is %0 with type %1">, @@ -225,20 +267,31 @@ let CategoryName = "VTable ABI Issue" in { def err_odr_variable_type_inconsistent : Error< "external variable %0 declared with incompatible types in different " "translation units (%1 vs. %2)">; +def warn_odr_variable_type_inconsistent : Warning< + "external variable %0 declared with incompatible types in different " + "translation units (%1 vs. %2)">, + InGroup<ODR>; def err_odr_variable_multiple_def : Error< "external variable %0 defined in multiple translation units">; +def warn_odr_variable_multiple_def : Warning< + "external variable %0 defined in multiple translation units">, + InGroup<ODR>; def note_odr_value_here : Note<"declared here with type %0">; def note_odr_defined_here : Note<"also defined here">; def err_odr_function_type_inconsistent : Error< "external function %0 declared with incompatible types in different " "translation units (%1 vs. %2)">; -def warn_odr_tag_type_inconsistent - : Warning<"type %0 has incompatible definitions in different translation " - "units">, - InGroup<DiagGroup<"odr">>; +def warn_odr_function_type_inconsistent : Warning< + "external function %0 declared with incompatible types in different " + "translation units (%1 vs. %2)">, + InGroup<ODR>; def err_odr_tag_type_inconsistent : Error<"type %0 has incompatible definitions in different translation " "units">; +def warn_odr_tag_type_inconsistent + : Warning<"type %0 has incompatible definitions in different translation " + "units">, + InGroup<ODR>; def note_odr_tag_kind_here: Note< "%0 is a %select{struct|interface|union|class|enum}1 here">; def note_odr_field : Note<"field %0 has type %1 here">; @@ -254,44 +307,82 @@ def note_odr_number_of_bases : Note< "class has %0 base %plural{1:class|:classes}0">; def note_odr_enumerator : Note<"enumerator %0 with value %1 here">; def note_odr_missing_enumerator : Note<"no corresponding enumerator here">; - def err_odr_field_type_inconsistent : Error< "field %0 declared with incompatible types in different " "translation units (%1 vs. %2)">; +def warn_odr_field_type_inconsistent : Warning< + "field %0 declared with incompatible types in different " + "translation units (%1 vs. %2)">, + InGroup<ODR>; // Importing Objective-C ASTs def err_odr_ivar_type_inconsistent : Error< "instance variable %0 declared with incompatible types in different " "translation units (%1 vs. %2)">; +def warn_odr_ivar_type_inconsistent : Warning< + "instance variable %0 declared with incompatible types in different " + "translation units (%1 vs. %2)">, + InGroup<ODR>; def err_odr_objc_superclass_inconsistent : Error< "class %0 has incompatible superclasses">; +def warn_odr_objc_superclass_inconsistent : Warning< + "class %0 has incompatible superclasses">, + InGroup<ODR>; def note_odr_objc_superclass : Note<"inherits from superclass %0 here">; def note_odr_objc_missing_superclass : Note<"no corresponding superclass here">; def err_odr_objc_method_result_type_inconsistent : Error< "%select{class|instance}0 method %1 has incompatible result types in " "different translation units (%2 vs. %3)">; +def warn_odr_objc_method_result_type_inconsistent : Warning< + "%select{class|instance}0 method %1 has incompatible result types in " + "different translation units (%2 vs. %3)">, + InGroup<ODR>; def err_odr_objc_method_num_params_inconsistent : Error< "%select{class|instance}0 method %1 has a different number of parameters in " "different translation units (%2 vs. %3)">; +def warn_odr_objc_method_num_params_inconsistent : Warning< + "%select{class|instance}0 method %1 has a different number of parameters in " + "different translation units (%2 vs. %3)">, + InGroup<ODR>; def err_odr_objc_method_param_type_inconsistent : Error< "%select{class|instance}0 method %1 has a parameter with a different types " "in different translation units (%2 vs. %3)">; +def warn_odr_objc_method_param_type_inconsistent : Warning< + "%select{class|instance}0 method %1 has a parameter with a different types " + "in different translation units (%2 vs. %3)">, + InGroup<ODR>; def err_odr_objc_method_variadic_inconsistent : Error< "%select{class|instance}0 method %1 is variadic in one translation unit " "and not variadic in another">; +def warn_odr_objc_method_variadic_inconsistent : Warning< + "%select{class|instance}0 method %1 is variadic in one translation unit " + "and not variadic in another">, + InGroup<ODR>; def note_odr_objc_method_here : Note< "%select{class|instance}0 method %1 also declared here">; def err_odr_objc_property_type_inconsistent : Error< "property %0 declared with incompatible types in different " "translation units (%1 vs. %2)">; +def warn_odr_objc_property_type_inconsistent : Warning< + "property %0 declared with incompatible types in different " + "translation units (%1 vs. %2)">, + InGroup<ODR>; def err_odr_objc_property_impl_kind_inconsistent : Error< "property %0 is implemented with %select{@synthesize|@dynamic}1 in one " "translation but %select{@dynamic|@synthesize}1 in another translation unit">; +def warn_odr_objc_property_impl_kind_inconsistent : Warning< + "property %0 is implemented with %select{@synthesize|@dynamic}1 in one " + "translation but %select{@dynamic|@synthesize}1 in another translation unit">, + InGroup<ODR>; def note_odr_objc_property_impl_kind : Note< "property %0 is implemented with %select{@synthesize|@dynamic}1 here">; def err_odr_objc_synthesize_ivar_inconsistent : Error< "property %0 is synthesized to different ivars in different translation " "units (%1 vs. %2)">; +def warn_odr_objc_synthesize_ivar_inconsistent : Warning< + "property %0 is synthesized to different ivars in different translation " + "units (%1 vs. %2)">, + InGroup<ODR>; def note_odr_objc_synthesize_ivar_here : Note< "property is synthesized to ivar %0 here">; @@ -300,19 +391,32 @@ def note_odr_friend : Note<"friend declared here">; def note_odr_missing_friend : Note<"no corresponding friend here">; def err_odr_different_num_template_parameters : Error< "template parameter lists have a different number of parameters (%0 vs %1)">; +def warn_odr_different_num_template_parameters : Warning< + "template parameter lists have a different number of parameters (%0 vs %1)">, + InGroup<ODR>; def note_odr_template_parameter_list : Note< "template parameter list also declared here">; def err_odr_different_template_parameter_kind : Error< "template parameter has different kinds in different translation units">; +def warn_odr_different_template_parameter_kind : Warning< + "template parameter has different kinds in different translation units">, + InGroup<ODR>; def note_odr_template_parameter_here : Note< "template parameter declared here">; def err_odr_parameter_pack_non_pack : Error< "parameter kind mismatch; parameter is %select{not a|a}0 parameter pack">; +def warn_odr_parameter_pack_non_pack : Warning< + "parameter kind mismatch; parameter is %select{not a|a}0 parameter pack">, + InGroup<ODR>; def note_odr_parameter_pack_non_pack : Note< "%select{parameter|parameter pack}0 declared here">; def err_odr_non_type_parameter_type_inconsistent : Error< "non-type template parameter declared with incompatible types in different " "translation units (%0 vs. %1)">; +def warn_odr_non_type_parameter_type_inconsistent : Warning< + "non-type template parameter declared with incompatible types in different " + "translation units (%0 vs. %1)">, + InGroup<ODR>; def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">; def remark_sanitize_address_insert_extra_padding_accepted : Remark< diff --git a/include/clang/Basic/DiagnosticAnalysis.h b/include/clang/Basic/DiagnosticAnalysis.h index 3748b538d2d2..eea35a4d616e 100644 --- a/include/clang/Basic/DiagnosticAnalysis.h +++ b/include/clang/Basic/DiagnosticAnalysis.h @@ -1,9 +1,8 @@ //===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticAnalysisKinds.td b/include/clang/Basic/DiagnosticAnalysisKinds.td index 5461212cd238..20efd96b85fd 100644 --- a/include/clang/Basic/DiagnosticAnalysisKinds.td +++ b/include/clang/Basic/DiagnosticAnalysisKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticAnalysisKinds.td - libanalysis diagnostics --------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticCategories.h b/include/clang/Basic/DiagnosticCategories.h index 4dd067ba1e98..0decf15080a0 100644 --- a/include/clang/Basic/DiagnosticCategories.h +++ b/include/clang/Basic/DiagnosticCategories.h @@ -1,9 +1,8 @@ //===- DiagnosticCategories.h - Diagnostic Categories Enumerators-*- C++ -*===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticCategories.td b/include/clang/Basic/DiagnosticCategories.td index 37b856976d52..d7203173790e 100644 --- a/include/clang/Basic/DiagnosticCategories.td +++ b/include/clang/Basic/DiagnosticCategories.td @@ -1,9 +1,8 @@ //==--- DiagnosticCategories.td - Diagnostic Category Definitions ---------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticComment.h b/include/clang/Basic/DiagnosticComment.h index a6c5f182cb32..a87bafa8b3a5 100644 --- a/include/clang/Basic/DiagnosticComment.h +++ b/include/clang/Basic/DiagnosticComment.h @@ -1,9 +1,8 @@ //===--- DiagnosticComment.h - Diagnostics for the AST library --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td index ebe62e4738f0..fcda3f3a2113 100644 --- a/include/clang/Basic/DiagnosticCommentKinds.td +++ b/include/clang/Basic/DiagnosticCommentKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticCommentKinds.td - diagnostics related to comments -------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 34ce489e50b2..ca2faf59d70f 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticCommonKinds.td - common diagnostics ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -133,8 +132,8 @@ def err_nullability_conflicting : Error< // OpenCL Section 6.8.g def err_opencl_unknown_type_specifier : Error< - "OpenCL %select{C|C++}0 version %1 does not support the '%2' " - "%select{type qualifier|storage class specifier}3">; + "%select{OpenCL C|C++ for OpenCL}0 version %1 does not support the " + "'%2' %select{type qualifier|storage class specifier}3">; def warn_unknown_attribute_ignored : Warning< "unknown attribute %0 ignored">, InGroup<UnknownAttributes>; @@ -151,6 +150,8 @@ def ext_warn_duplicate_declspec : ExtWarn<"%sub{duplicate_declspec}0">, def warn_duplicate_declspec : Warning<"%sub{duplicate_declspec}0">, InGroup<DuplicateDeclSpecifier>; +def err_duplicate_declspec : Error<"%sub{duplicate_declspec}0">; + def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">; def err_invalid_member_in_interface : Error< @@ -171,6 +172,9 @@ def ext_cxx11_longlong : Extension< def warn_cxx98_compat_longlong : Warning< "'long long' is incompatible with C++98">, InGroup<CXX98CompatPedantic>, DefaultIgnore; +def warn_cxx20_compat_consteval : Warning< + "consteval is incompatible with C++ standards before C++20">, + InGroup<CXX2aCompat>, DefaultIgnore; def err_integer_literal_too_large : Error< "integer literal is too large to be represented in any %select{signed |}0" "integer type">; @@ -251,6 +255,8 @@ def err_target_unsupported_unaligned : Error< "the %0 sub-architecture does not support unaligned accesses">; def err_target_unsupported_execute_only : Error< "execute only is not supported for the %0 sub-architecture">; +def err_target_unsupported_mcmse : Error< + "-mcmse is not supported for %0">; def err_opt_not_valid_with_opt : Error< "option '%0' cannot be specified with '%1'">; def err_opt_not_valid_without_opt : Error< @@ -262,6 +268,8 @@ def err_opt_not_valid_on_target : Error< def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal; def err_file_modified : Error< "file '%0' modified since it was first processed">, DefaultFatal; +def err_file_too_large : Error< + "sorry, unsupported: file '%0' is too large for Clang to process">; def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but " "encoding is not supported">, DefaultFatal; def err_unable_to_rename_temp : Error< @@ -283,9 +291,9 @@ def note_mt_message : Note<"[rewriter] %0">; def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">; def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">; -// OpenCL C++. +// C++ for OpenCL. def err_openclcxx_not_supported : Error< - "'%0' is not supported in OpenCL C++">; + "'%0' is not supported in C++ for OpenCL">; // OpenMP def err_omp_more_one_clause : Error< @@ -293,7 +301,7 @@ def err_omp_more_one_clause : Error< // Static Analyzer Core def err_unknown_analyzer_checker : Error< - "no analyzer checkers are associated with '%0'">; + "no analyzer checkers or packages are associated with '%0'">; def note_suggest_disabling_all_checkers : Note< "use -analyzer-disable-all-checks to disable all static analyzer checkers">; } diff --git a/include/clang/Basic/DiagnosticCrossTU.h b/include/clang/Basic/DiagnosticCrossTU.h index 8cff33479f43..c1c582bd6ee4 100644 --- a/include/clang/Basic/DiagnosticCrossTU.h +++ b/include/clang/Basic/DiagnosticCrossTU.h @@ -1,9 +1,8 @@ //===--- DiagnosticCrossTU.h - Diagnostics for Cross TU ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticCrossTUKinds.td b/include/clang/Basic/DiagnosticCrossTUKinds.td index 89e261c84bc6..4277a3173203 100644 --- a/include/clang/Basic/DiagnosticCrossTUKinds.td +++ b/include/clang/Basic/DiagnosticCrossTUKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticCrossTUKinds.td - Cross Translation Unit diagnostics ----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticDocs.td b/include/clang/Basic/DiagnosticDocs.td index 0a3e1ce5f2f2..bf88d5d04567 100644 --- a/include/clang/Basic/DiagnosticDocs.td +++ b/include/clang/Basic/DiagnosticDocs.td @@ -1,9 +1,8 @@ //==--- DiagnosticDocs.td - Diagnostic documentation ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===---------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticDriver.h b/include/clang/Basic/DiagnosticDriver.h index 2ab9b3e08366..63913df4523b 100644 --- a/include/clang/Basic/DiagnosticDriver.h +++ b/include/clang/Basic/DiagnosticDriver.h @@ -1,9 +1,8 @@ //===--- DiagnosticDriver.h - Diagnostics for libdriver ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 5475e28ed754..eab453ee20ec 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -1,18 +1,19 @@ //==--- DiagnosticDriverKinds.td - libdriver diagnostics ------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// let Component = "Driver" in { def err_drv_no_such_file : Error<"no such file or directory: '%0'">; +def err_drv_no_such_file_with_suggestion : Error< + "no such file or directory: '%0'; did you mean '%1'?">; def err_drv_unsupported_opt : Error<"unsupported option '%0'">; -def err_drv_unsupported_opt_with_suggestion - : Error<"unsupported option '%0', did you mean '%1'?">; +def err_drv_unsupported_opt_with_suggestion : Error< + "unsupported option '%0'; did you mean '%1'?">; def err_drv_unsupported_opt_for_target : Error< "unsupported option '%0' for target '%1'">; def err_drv_unsupported_option_argument : Error< @@ -28,6 +29,25 @@ def err_drv_invalid_riscv_arch_name : Error< "invalid arch name '%0', %1">; def err_drv_invalid_riscv_ext_arch_name : Error< "invalid arch name '%0', %1 '%2'">; +def warn_drv_avr_mcu_not_specified : Warning< + "no target microcontroller specified on command line, cannot " + "link standard libraries, please pass -mmcu=<mcu name>">, + InGroup<AVRRtlibLinkingQuirks>; +def warn_drv_avr_gcc_not_found: Warning< + "no avr-gcc installation can be found on the system, " + "cannot link standard libraries">, + InGroup<AVRRtlibLinkingQuirks>; +def warn_drv_avr_libc_not_found: Warning< + "no avr-libc installation can be found on the system, " + "cannot link standard libraries">, + InGroup<AVRRtlibLinkingQuirks>; +def warn_drv_avr_family_linking_stdlibs_not_implemented: Warning< + "support for linking stdlibs for microcontroller '%0' is not implemented">, + InGroup<AVRRtlibLinkingQuirks>; +def warn_drv_avr_stdlib_not_linked: Warning< + "standard library not linked and so no interrupt vector table or " + "compiler runtime routines will be linked">, + InGroup<AVRRtlibLinkingQuirks>; def err_drv_cuda_bad_gpu_arch : Error<"Unsupported CUDA gpu architecture: %0">; def err_drv_no_cuda_installation : Error< "cannot find CUDA installation. Provide its path via --cuda-path, or pass " @@ -52,6 +72,10 @@ def err_drv_invalid_rtlib_name : Error< "invalid runtime library name in argument '%0'">; def err_drv_unsupported_rtlib_for_platform : Error< "unsupported runtime library '%0' for platform '%1'">; +def err_drv_invalid_unwindlib_name : Error< + "invalid unwind library name in argument '%0'">; +def err_drv_incompatible_unwindlib : Error< + "--rtlib=libgcc requires --unwindlib=libgcc">; def err_drv_invalid_stdlib_name : Error< "invalid library name in argument '%0'">; def err_drv_invalid_output_with_multiple_archs : Error< @@ -67,6 +91,8 @@ def err_no_external_assembler : Error< "there is no external assembler that can be used on this platform">; def err_drv_unable_to_remove_file : Error< "unable to remove file: %0">; +def err_drv_unable_to_set_working_directory : Error < + "unable to set working directory: %0">; def err_drv_command_failure : Error< "unable to execute command: %0">; def err_drv_invalid_darwin_version : Error< @@ -97,6 +123,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_pg_darwin: Error< + "the clang compiler does not support -pg option on %select{Darwin|versions of OS X 10.9 and later}0">; def err_drv_clang_unsupported_opt_faltivec : Error< "the clang compiler does not support '%0', %1">; def err_drv_command_failed : Error< @@ -131,6 +159,8 @@ def err_drv_cannot_read_config_file : Error< "cannot read configuration file '%0'">; def err_drv_nested_config_file: Error< "option '--config' is not allowed inside configuration file">; +def err_drv_arg_requires_bitcode_input: Error< + "option '%0' requires input to be LLVM bitcode">; def err_target_unsupported_arch : Error<"the target architecture '%0' is not supported by the target '%1'">; @@ -142,13 +172,13 @@ def err_arch_unsupported_isa def err_drv_I_dash_not_supported : Error< "'%0' not supported, please use -iquote instead">; def err_drv_unknown_argument : Error<"unknown argument: '%0'">; -def err_drv_unknown_argument_with_suggestion - : Error<"unknown argument '%0', did you mean '%1'?">; +def err_drv_unknown_argument_with_suggestion : Error< + "unknown argument '%0'; did you mean '%1'?">; def warn_drv_unknown_argument_clang_cl : Warning< "unknown argument ignored in clang-cl: '%0'">, InGroup<UnknownArgument>; def warn_drv_unknown_argument_clang_cl_with_suggestion : Warning< - "unknown argument ignored in clang-cl '%0' (did you mean '%1'?)">, + "unknown argument ignored in clang-cl '%0'; did you mean '%1'?">, InGroup<UnknownArgument>; def warn_drv_ycyu_different_arg_clang_cl : Warning< @@ -201,7 +231,9 @@ def err_drv_gnustep_objc_runtime_incompatible_binary : Error< def err_drv_emit_llvm_link : Error< "-emit-llvm cannot be used when linking">; def err_drv_optimization_remark_pattern : Error< - "%0 in '%1'">; + "in pattern '%1': %0">; +def err_drv_optimization_remark_format : Error< + "unknown remark serializer format: '%0'">; def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, please use [no]simd instead">; def err_drv_invalid_omp_target : Error<"OpenMP target is invalid: '%0'">; def err_drv_omp_host_ir_file_not_found : Error< @@ -302,6 +334,10 @@ def err_analyzer_config_multiple_values : Error< def err_analyzer_config_invalid_input : Error< "invalid input for analyzer-config option '%0', that expects %1 value">; def err_analyzer_config_unknown : Error<"unknown analyzer-config '%0'">; +def err_analyzer_checker_option_unknown : Error< + "checker '%0' has no option called '%1'">; +def err_analyzer_checker_option_invalid_input : Error< + "invalid input for checker option '%0', that expects %1">; def err_drv_invalid_hvx_length : Error< "-mhvx-length is not supported without a -mhvx/-mhvx= flag">; @@ -425,4 +461,10 @@ def warn_drv_msp430_hwmult_no_device : Warning<"no MCU device specified, but " "specify a MSP430 device, or -mhwmult to set hardware multiply type " "explicitly.">, InGroup<InvalidCommandLineArgument>; +def warn_drv_libstdcxx_not_found : Warning< + "include path for libstdc++ headers not found; pass '-stdlib=libc++' on the " + "command line to use the libc++ standard library instead">, + InGroup<DiagGroup<"stdlibcxx-not-found">>; + +def err_drv_cannot_mix_options : Error<"cannot specify '%1' along with '%0'">; } diff --git a/include/clang/Basic/DiagnosticError.h b/include/clang/Basic/DiagnosticError.h index 3f7be46c9505..430da6f724ed 100644 --- a/include/clang/Basic/DiagnosticError.h +++ b/include/clang/Basic/DiagnosticError.h @@ -1,9 +1,8 @@ //===--- DiagnosticError.h - Diagnostic payload for llvm::Error -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticFrontend.h b/include/clang/Basic/DiagnosticFrontend.h index 1f066cf491ae..57f00e73abb4 100644 --- a/include/clang/Basic/DiagnosticFrontend.h +++ b/include/clang/Basic/DiagnosticFrontend.h @@ -1,9 +1,8 @@ //===--- DiagnosticFrontend.h - Diagnostics for frontend --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 927b8cbc2477..7a990164b0d9 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticFrontendKinds.td - frontend diagnostics -----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -122,6 +121,12 @@ def err_verify_missing_file : Error< "file '%0' could not be located in expected %1">; def err_verify_invalid_range : Error< "invalid range following '-' in expected %0">; +def err_verify_ambiguous_marker : Error< + "reference to marker '%0' is ambiguous">; +def note_verify_ambiguous_marker : Note< + "ambiguous marker '%0' is defined here">; +def err_verify_no_such_marker : Error< + "use of undefined marker '%0'">; def err_verify_missing_start : Error< "cannot find start ('{{') of expected %0">; def err_verify_missing_end : Error< @@ -168,10 +173,11 @@ def note_incompatible_analyzer_plugin_api : Note< def err_module_build_requires_fmodules : Error< "module compilation requires '-fmodules'">; -def err_module_interface_requires_modules_ts : Error< - "module interface compilation requires '-fmodules-ts'">; +def err_module_interface_requires_cpp_modules : Error< + "module interface compilation requires '-std=c++2a' or '-fmodules-ts'">; def err_header_module_requires_modules : Error< - "header module compilation requires '-fmodules' or '-fmodules-ts'">; + "header module compilation requires '-fmodules', '-std=c++2a', or " + "'-fmodules-ts'">; def warn_module_config_mismatch : Warning< "module file %0 cannot be loaded due to a configuration mismatch with the current " "compilation">, InGroup<DiagGroup<"module-file-config-mismatch">>, DefaultError; @@ -214,6 +220,8 @@ def err_module_header_file_not_found : def err_module_header_file_invalid : Error<"unexpected module header file input '%0'">, DefaultFatal; +def err_interface_stubs : Error<"clang-ifs (-emit-iterface-stubs): %0">; + def err_test_module_file_extension_version : Error< "test module file extension '%0' has different version (%1.%2) than expected " "(%3.%4)">; @@ -226,11 +234,6 @@ def err_invalid_vfs_overlay : Error< def warn_option_invalid_ocl_version : Warning< "OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>; -def warn_stdlibcxx_not_found : Warning< - "include path for stdlibc++ headers not found; pass '-stdlib=libc++' on the " - "command line to use the libc++ standard library instead">, - InGroup<DiagGroup<"stdlibcxx-not-found">>; - def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 19e187cc5d93..56f2ecfe8e4a 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -1,9 +1,8 @@ //==--- DiagnosticGroups.td - Diagnostic Group Definitions ----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -17,6 +16,7 @@ def Implicit : DiagGroup<"implicit", [ ]>; // Empty DiagGroups are recognized by clang but ignored. +def ODR : DiagGroup<"odr">; def : DiagGroup<"abi">; def AbsoluteValue : DiagGroup<"absolute-value">; def AddressOfTemporary : DiagGroup<"address-of-temporary">; @@ -48,8 +48,10 @@ def BitFieldWidth : DiagGroup<"bitfield-width">; def CoroutineMissingUnhandledException : DiagGroup<"coroutine-missing-unhandled-exception">; def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException]>; -def ConstantConversion : - DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >; +def ObjCBoolConstantConversion : DiagGroup<"objc-bool-constant-conversion">; +def ConstantConversion : DiagGroup<"constant-conversion", + [BitFieldConstantConversion, + ObjCBoolConstantConversion]>; def LiteralConversion : DiagGroup<"literal-conversion">; def StringConversion : DiagGroup<"string-conversion">; def SignConversion : DiagGroup<"sign-conversion">; @@ -61,6 +63,7 @@ def IntConversion : DiagGroup<"int-conversion">; def EnumConversion : DiagGroup<"enum-conversion">; def ImplicitIntConversion : DiagGroup<"implicit-int-conversion">; def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion">; +def ImplicitFixedPointConversion : DiagGroup<"implicit-fixed-point-conversion">; def FloatOverflowConversion : DiagGroup<"float-overflow-conversion">; def FloatZeroConversion : DiagGroup<"float-zero-conversion">; @@ -167,6 +170,7 @@ def ExtraTokens : DiagGroup<"extra-tokens">; def CXX98CompatExtraSemi : DiagGroup<"c++98-compat-extra-semi">; def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">; def EmptyInitStatement : DiagGroup<"empty-init-stmt">; +def ExportUnnamed : DiagGroup<"export-unnamed">; def ExtraSemiStmt : DiagGroup<"extra-semi-stmt", [EmptyInitStatement]>; def ExtraSemi : DiagGroup<"extra-semi", [CXX98CompatExtraSemi, CXX11ExtraSemi]>; @@ -351,6 +355,7 @@ def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">; def MismatchedTags : DiagGroup<"mismatched-tags">; def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; def ModuleBuild : DiagGroup<"module-build">; +def ModuleImport : DiagGroup<"module-import">; def ModuleConflict : DiagGroup<"module-conflict">; def ModuleFileExtension : DiagGroup<"module-file-extension">; def NewlineEOF : DiagGroup<"newline-eof">; @@ -403,7 +408,9 @@ def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-in def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>; def ObjCMultipleMethodNames : DiagGroup<"objc-multiple-method-names">; def ObjCFlexibleArray : DiagGroup<"objc-flexible-array">; +def ObjCBoxing : DiagGroup<"objc-boxing">; def OpenCLUnsupportedRGBA: DiagGroup<"opencl-unsupported-rgba">; +def UnderalignedExceptionObject : DiagGroup<"underaligned-exception-object">; def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">; def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">; def Packed : DiagGroup<"packed">; @@ -481,17 +488,21 @@ def TautologicalInRangeCompare : DiagGroup<"tautological-constant-in-range-compa [TautologicalTypeLimitCompare, TautologicalUnsignedZeroCompare, TautologicalUnsignedEnumZeroCompare]>; +// For compatibility with GCC; -Wtype-limits = -Wtautological-constant-in-range-compare +def TypeLimits : DiagGroup<"type-limits", [TautologicalInRangeCompare]>; def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">; def TautologicalConstantCompare : DiagGroup<"tautological-constant-compare", [TautologicalOutOfRangeCompare]>; def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">; def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">; def TautologicalUndefinedCompare : DiagGroup<"tautological-undefined-compare">; +def TautologicalObjCBoolCompare : DiagGroup<"tautological-objc-bool-compare">; def TautologicalCompare : DiagGroup<"tautological-compare", [TautologicalConstantCompare, TautologicalPointerCompare, TautologicalOverlapCompare, - TautologicalUndefinedCompare]>; + TautologicalUndefinedCompare, + TautologicalObjCBoolCompare]>; def HeaderHygiene : DiagGroup<"header-hygiene">; def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">; def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">; @@ -916,6 +927,7 @@ def GccCompat : DiagGroup<"gcc-compat">; // Warnings for Microsoft extensions. def MicrosoftCharize : DiagGroup<"microsoft-charize">; +def MicrosoftDrectveSection : DiagGroup<"microsoft-drectve-section">; def MicrosoftInclude : DiagGroup<"microsoft-include">; def MicrosoftCppMacro : DiagGroup<"microsoft-cpp-macro">; def MicrosoftFixedEnum : DiagGroup<"microsoft-fixed-enum">; @@ -953,9 +965,10 @@ def : DiagGroup<"msvc-include", [MicrosoftInclude]>; // Warnings group for warnings about Microsoft extensions. def Microsoft : DiagGroup<"microsoft", - [MicrosoftCharize, MicrosoftInclude, MicrosoftCppMacro, MicrosoftFixedEnum, - MicrosoftSealed, MicrosoftUnqualifiedFriend, MicrosoftExceptionSpec, - MicrosoftUsingDecl, MicrosoftMutableReference, MicrosoftPureDefinition, + [MicrosoftCharize, MicrosoftDrectveSection, MicrosoftInclude, + MicrosoftCppMacro, MicrosoftFixedEnum, MicrosoftSealed, + MicrosoftUnqualifiedFriend, MicrosoftExceptionSpec, MicrosoftUsingDecl, + MicrosoftMutableReference, MicrosoftPureDefinition, MicrosoftUnionMemberReference, MicrosoftExplicitConstructorCall, MicrosoftEnumValue, MicrosoftDefaultArgRedefinition, MicrosoftTemplate, MicrosoftRedeclareStatic, MicrosoftEnumForwardReference, MicrosoftGoto, @@ -1026,6 +1039,10 @@ def SerializedDiagnostics : DiagGroup<"serialized-diagnostics">; // compiling CUDA C/C++ but which is not compatible with the CUDA spec. def CudaCompat : DiagGroup<"cuda-compat">; +// Warnings which cause linking of the runtime libraries like +// libc and the CRT to be skipped. +def AVRRtlibLinkingQuirks : DiagGroup<"avr-rtlib-linking-quirks">; + // A warning group for things that will change semantics in the future. def FutureCompat : DiagGroup<"future-compat">; @@ -1050,3 +1067,7 @@ def NoDeref : DiagGroup<"noderef">; // A group for cross translation unit static analysis related warnings. def CrossTU : DiagGroup<"ctu">; + +def CTADMaybeUnsupported : DiagGroup<"ctad-maybe-unsupported">; + +def FortifySource : DiagGroup<"fortify-source">; diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index 876629f373a1..5b9391b5a452 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -1,9 +1,8 @@ //===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -33,11 +32,11 @@ namespace clang { DIAG_SIZE_FRONTEND = 150, DIAG_SIZE_SERIALIZATION = 120, DIAG_SIZE_LEX = 400, - DIAG_SIZE_PARSE = 500, - DIAG_SIZE_AST = 150, + DIAG_SIZE_PARSE = 600, + DIAG_SIZE_AST = 200, DIAG_SIZE_COMMENT = 100, DIAG_SIZE_CROSSTU = 100, - DIAG_SIZE_SEMA = 3500, + DIAG_SIZE_SEMA = 4000, DIAG_SIZE_ANALYSIS = 100, DIAG_SIZE_REFACTORING = 1000, }; @@ -51,8 +50,8 @@ namespace clang { DIAG_START_PARSE = DIAG_START_LEX + DIAG_SIZE_LEX, DIAG_START_AST = DIAG_START_PARSE + DIAG_SIZE_PARSE, DIAG_START_COMMENT = DIAG_START_AST + DIAG_SIZE_AST, - DIAG_START_CROSSTU = DIAG_START_COMMENT + DIAG_SIZE_CROSSTU, - DIAG_START_SEMA = DIAG_START_CROSSTU + DIAG_SIZE_COMMENT, + DIAG_START_CROSSTU = DIAG_START_COMMENT + DIAG_SIZE_COMMENT, + DIAG_START_SEMA = DIAG_START_CROSSTU + DIAG_SIZE_CROSSTU, DIAG_START_ANALYSIS = DIAG_START_SEMA + DIAG_SIZE_SEMA, DIAG_START_REFACTORING = DIAG_START_ANALYSIS + DIAG_SIZE_ANALYSIS, DIAG_UPPER_LIMIT = DIAG_START_REFACTORING + DIAG_SIZE_REFACTORING @@ -170,7 +169,7 @@ public: private: /// Information for uniquing and looking up custom diags. - diag::CustomDiagInfo *CustomDiagInfo; + std::unique_ptr<diag::CustomDiagInfo> CustomDiagInfo; public: DiagnosticIDs(); diff --git a/include/clang/Basic/DiagnosticLex.h b/include/clang/Basic/DiagnosticLex.h index 6ec4da80338f..33789051b286 100644 --- a/include/clang/Basic/DiagnosticLex.h +++ b/include/clang/Basic/DiagnosticLex.h @@ -1,9 +1,8 @@ //===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 14e306246ba3..b64cbc23f810 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticLexKinds.td - liblex diagnostics ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -269,12 +268,14 @@ def err_pp_hash_error : Error<"%0">; } def pp_include_next_in_primary : Warning< - "#include_next in primary source file">, + "#include_next in primary source file; " + "will search from start of include path">, InGroup<DiagGroup<"include-next-outside-header">>; def pp_include_macros_out_of_predefines : Error< "the #__include_macros directive is only for internal use by -imacros">; def pp_include_next_absolute_path : Warning< - "#include_next with absolute path">, + "#include_next in file found relative to primary source file or found by " + "absolute path; will search from start of include path">, InGroup<DiagGroup<"include-next-absolute-path">>; def ext_c99_whitespace_required_after_macro_name : ExtWarn< "ISO C99 requires whitespace after the macro name">, InGroup<C99>; @@ -392,9 +393,10 @@ def warn_cxx98_compat_empty_fnmacro_arg : Warning< "empty macro arguments are incompatible with C++98">, InGroup<CXX98CompatPedantic>, DefaultIgnore; def note_macro_here : Note<"macro %0 defined here">; +def note_macro_expansion_here : Note<"expansion of macro %0 requested here">; -def err_pp_opencl_variadic_macros : - Error<"variadic macros not supported in OpenCL">; +def ext_pp_opencl_variadic_macros : Extension< + "variadic macros are a Clang extension in OpenCL">; def err_pp_invalid_directive : Error<"invalid preprocessing directive">; def err_pp_directive_required : Error< @@ -416,11 +418,16 @@ def warn_pp_hdrstop_filename_ignored : Warning< "/Fp can be used to specify precompiled header filename">, InGroup<ClangClPch>; def err_pp_file_not_found_angled_include_not_fatal : Error< - "'%0' file not found with <angled> include; use \"quotes\" instead">; + "'%0' file not found with <angled> %select{include|import}1; " + "use \"quotes\" instead">; def err_pp_file_not_found_typo_not_fatal : Error<"'%0' file not found, did you mean '%1'?">; +def note_pp_framework_without_header : Note< + "did not find header '%0' in framework '%1' (loaded from '%2')">; def err_pp_error_opening_file : Error< "error opening file '%0': %1">, DefaultFatal; +def err_pp_including_mainfile_in_preamble : Error< + "main file cannot be included recursively when building a preamble">; def err_pp_empty_filename : Error<"empty filename">; def err_pp_include_too_deep : Error<"#include nested too deeply">; def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">; @@ -504,6 +511,17 @@ def warn_pragma_warning_expected_number : ExtWarn<"#pragma warning expected a warning number">, InGroup<UnknownPragmas>; +// - #pragma execution_character_set(...) +def warn_pragma_exec_charset_expected : + ExtWarn<"#pragma execution_character_set expected '%0'">, + InGroup<UnknownPragmas>; +def warn_pragma_exec_charset_spec_invalid : + ExtWarn<"#pragma execution_character_set expected 'push' or 'pop'">, + InGroup<UnknownPragmas>; +def warn_pragma_exec_charset_push_invalid : + ExtWarn<"#pragma execution_character_set invalid value '%0', only 'UTF-8' is supported">, + InGroup<UnknownPragmas>; + def err__Pragma_malformed : Error< "_Pragma takes a parenthesized string literal">; def err_pragma_message_malformed : Error< @@ -545,6 +563,8 @@ def warn_pragma_debug_unexpected_command : Warning< "unexpected debug command '%0'">, InGroup<IgnoredPragmas>; def warn_pragma_debug_missing_argument : Warning< "missing argument to debug command '%0'">, InGroup<IgnoredPragmas>; +def warn_pragma_debug_unknown_module : Warning< + "unknown module '%0'">, InGroup<IgnoredPragmas>; // #pragma module def err_pp_expected_module_name : Error< "expected %select{identifier after '.' in |}0module name">; @@ -627,7 +647,8 @@ def err_pp_double_begin_of_arc_cf_code_audited : Error< def err_pp_unmatched_end_of_arc_cf_code_audited : Error< "not currently inside '#pragma clang arc_cf_code_audited'">; def err_pp_include_in_arc_cf_code_audited : Error< - "cannot #include files inside '#pragma clang arc_cf_code_audited'">; + "cannot %select{#include files|import headers}0 " + "inside '#pragma clang arc_cf_code_audited'">; def err_pp_eof_in_arc_cf_code_audited : Error< "'#pragma clang arc_cf_code_audited' was not ended within this file">; @@ -761,6 +782,14 @@ def warn_module_conflict : Warning< "module '%0' conflicts with already-imported module '%1': %2">, InGroup<ModuleConflict>; +// C++20 modules +def err_header_import_semi_in_macro : Error< + "semicolon terminating header import declaration cannot be produced " + "by a macro">; +def err_header_import_not_header_unit : Error< + "header file %0 (aka '%1') cannot be imported because " + "it is not known to be a header unit">; + def warn_header_guard : Warning< "%0 is used as a header guard here, followed by #define of a different macro">, InGroup<DiagGroup<"header-guard">>; @@ -782,10 +811,20 @@ def err_pp_double_begin_of_assume_nonnull : Error< def err_pp_unmatched_end_of_assume_nonnull : Error< "not currently inside '#pragma clang assume_nonnull'">; def err_pp_include_in_assume_nonnull : Error< - "cannot #include files inside '#pragma clang assume_nonnull'">; + "cannot %select{#include files|import headers}0 " + "inside '#pragma clang assume_nonnull'">; def err_pp_eof_in_assume_nonnull : Error< "'#pragma clang assume_nonnull' was not ended within this file">; } +let CategoryName = "Dependency Directive Source Minimization Issue" in { + +def err_dep_source_minimizer_missing_sema_after_at_import : Error< + "could not find ';' after @import">; +def err_dep_source_minimizer_unexpected_tokens_at_import : Error< + "unexpected extra tokens at end of @import declaration">; + +} + } diff --git a/include/clang/Basic/DiagnosticOptions.def b/include/clang/Basic/DiagnosticOptions.def index 22645654afd8..baafd7ac723f 100644 --- a/include/clang/Basic/DiagnosticOptions.def +++ b/include/clang/Basic/DiagnosticOptions.def @@ -1,9 +1,8 @@ //===--- DiagOptions.def - Diagnostic option database ------------- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h index 4c5bcb4e8793..3e3c4e50a9e0 100644 --- a/include/clang/Basic/DiagnosticOptions.h +++ b/include/clang/Basic/DiagnosticOptions.h @@ -1,9 +1,8 @@ //===- DiagnosticOptions.h --------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticParse.h b/include/clang/Basic/DiagnosticParse.h index 2113b03262d7..0c21ff93c5fa 100644 --- a/include/clang/Basic/DiagnosticParse.h +++ b/include/clang/Basic/DiagnosticParse.h @@ -1,9 +1,8 @@ //===--- DiagnosticParse.h - Diagnostics for libparse -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 06281e2904c7..8e6ced0dea54 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticParseKinds.td - libparse diagnostics --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -28,12 +27,16 @@ def err_msasm_unable_to_create_target : Error< "MS-style inline assembly is not available: %0">; def err_gnu_inline_asm_disabled : Error< "GNU-style inline assembly is disabled">; -def err_asm_goto_not_supported_yet : Error< - "'asm goto' constructs are not supported yet">; +def err_asm_goto_cannot_have_output : Error< + "'asm goto' cannot have output constraints">; } let CategoryName = "Parse Issue" in { +def warn_cxx2a_compat_explicit_bool : Warning< + "this expression will be parsed as explicit(bool) in C++2a">, + InGroup<CXX2aCompat>, DefaultIgnore; + def ext_empty_translation_unit : Extension< "ISO C requires a translation unit to contain at least one declaration">, InGroup<DiagGroup<"empty-translation-unit">>; @@ -106,6 +109,8 @@ def warn_cxx98_compat_alignof : Warning< InGroup<CXX98Compat>, DefaultIgnore; def ext_alignof_expr : ExtWarn< "%0 applied to an expression is a GNU extension">, InGroup<GNUAlignofExpression>; +def err_lambda_after_delete : Error< + "'[]' after delete interpreted as 'delete[]'; add parentheses to treat this as a lambda-expression">; def warn_microsoft_dependent_exists : Warning< "dependent %select{__if_not_exists|__if_exists}0 declarations are ignored">, @@ -355,7 +360,7 @@ def err_typename_invalid_storageclass : Error< def err_typename_invalid_functionspec : Error< "type name does not allow function specifier to be specified">; def err_typename_invalid_constexpr : Error< - "type name does not allow constexpr specifier to be specified">; + "type name does not allow %select{constexpr|consteval}0 specifier to be specified">; def err_typename_identifiers_only : Error< "typename is allowed for identifiers only">; @@ -434,7 +439,7 @@ def err_objc_expected_property_attr : Error<"unknown property attribute %0">; def err_objc_properties_require_objc2 : Error< "properties are an Objective-C 2 feature">; def err_objc_unexpected_attr : Error< - "prefix attribute must be followed by an interface or protocol">; + "prefix attribute must be followed by an interface, protocol, or implementation">; def err_objc_postfix_attribute : Error < "postfix attributes are not allowed on Objective-C directives">; def err_objc_postfix_attribute_hint : Error < @@ -679,11 +684,13 @@ def warn_cxx14_compat_template_template_param_typename : Warning< def err_template_spec_syntax_non_template : Error< "identifier followed by '<' indicates a class template specialization but " "%0 %select{does not refer to a template|refers to a function template|" - "<unused>|refers to a variable template|<unused>}1">; + "<unused>|refers to a variable template|<unused>|refers to a concept}1">; def err_id_after_template_in_nested_name_spec : Error< "expected template name after 'template' keyword in nested name specifier">; def err_unexpected_template_in_unqualified_id : Error< "'template' keyword not permitted here">; +def err_unexpected_template_after_using : Error< + "'template' keyword not permitted after 'using' keyword">; def err_two_right_angle_brackets_need_space : Error< "a space is required between consecutive right angle brackets (use '> >')">; def err_right_angle_bracket_equal_needs_space : Error< @@ -743,7 +750,8 @@ def err_typename_refers_to_non_type_template : Error< def err_expected_type_name_after_typename : Error< "expected an identifier or template-id after '::'">; def err_explicit_spec_non_template : Error< - "explicit %select{specialization|instantiation}0 of non-template %1 %2">; + "explicit %select{specialization|instantiation}0 of " + "%select{non-|undeclared }3template %1 %2">; def err_default_template_template_parameter_not_template : Error< "default template argument for a template template parameter must be a class " @@ -867,9 +875,14 @@ def warn_cxx98_compat_lambda : Warning< InGroup<CXX98Compat>, DefaultIgnore; def err_lambda_missing_parens : Error< "lambda requires '()' before %select{'mutable'|return type|" - "attribute specifier|'constexpr'}0">; + "attribute specifier|'constexpr'|'consteval'}0">; def err_lambda_decl_specifier_repeated : Error< - "%select{'mutable'|'constexpr'}0 cannot appear multiple times in a lambda declarator">; + "%select{'mutable'|'constexpr'|'consteval'}0 cannot appear multiple times in a lambda declarator">; +def err_lambda_capture_misplaced_ellipsis : Error< + "ellipsis in pack %select{|init-}0capture must appear %select{after|before}0 " + "the name of the capture">; +def err_lambda_capture_multiple_ellipses : Error< + "multiple ellipses in pack capture">; // C++17 lambda expressions def err_expected_star_this_capture : Error< "expected 'this' following '*' in lambda capture list">; @@ -881,6 +894,16 @@ def warn_cxx14_compat_constexpr_on_lambda : Warning< def ext_constexpr_on_lambda_cxx17 : ExtWarn< "'constexpr' on lambda expressions is a C++17 extension">, InGroup<CXX17>; +// C++2a template lambdas +def ext_lambda_template_parameter_list: ExtWarn< + "explicit template parameter list for lambdas is a C++2a extension">, + InGroup<CXX2a>; +def warn_cxx17_compat_lambda_template_parameter_list: Warning< + "explicit template parameter list for lambdas is incompatible with " + "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; +def err_lambda_template_parameter_list_empty : Error< + "lambda template parameter list cannot be empty">; + // Availability attribute def err_expected_version : Error< "expected a version of the form 'major[.minor[.subminor]]'">; @@ -1131,11 +1154,9 @@ def err_opencl_taking_function_address_parser : Error< def err_opencl_logical_exclusive_or : Error< "^^ is a reserved operator in OpenCL">; -// OpenCL C++. +// C++ for OpenCL. def err_openclcxx_virtual_function : Error< - "virtual functions are not supported in OpenCL C++">; -def err_openclcxx_reserved : Error< - "'%0' is a reserved keyword in OpenCL C++">; + "virtual functions are not supported in C++ for OpenCL">; // OpenMP support. def warn_pragma_omp_ignored : Warning< @@ -1164,7 +1185,7 @@ def err_omp_decl_in_declare_simd : Error< def err_omp_unknown_map_type : Error< "incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">; def err_omp_unknown_map_type_modifier : Error< - "incorrect map type modifier, expected 'always' or 'close'">; + "incorrect map type modifier, expected 'always', 'close', or 'mapper'">; def err_omp_map_type_missing : Error< "missing map type">; def err_omp_map_type_modifier_missing : Error< @@ -1177,6 +1198,10 @@ def err_omp_declare_target_unexpected_clause: Error< "unexpected '%0' clause, only 'to' or 'link' clauses expected">; def err_omp_expected_clause: Error< "expected at least one clause on '#pragma omp %0' directive">; +def err_omp_mapper_illegal_identifier : Error< + "illegal OpenMP user-defined mapper identifier">; +def err_omp_mapper_expected_declarator : Error< + "expected declarator on 'omp declare mapper' directive">; // Pragma loop support. def err_pragma_loop_missing_argument : Error< @@ -1222,15 +1247,22 @@ def err_unexpected_module_decl : Error< "module declaration can only appear at the top level">; def err_module_expected_ident : Error< "expected a module name after '%select{module|import}0'">; -def err_module_implementation_partition : Error< - "module partition must be declared 'export'">; def err_attribute_not_module_attr : Error< "%0 attribute cannot be applied to a module">; def err_attribute_not_import_attr : Error< "%0 attribute cannot be applied to a module import">; def err_module_expected_semi : Error< "expected ';' after module name">; +def err_global_module_introducer_not_at_start : Error< + "'module;' introducing a global module fragment can appear only " + "at the start of the translation unit">; +def err_module_fragment_exported : Error< + "%select{global|private}0 module fragment cannot be exported">; +def err_private_module_fragment_expected_semi : Error< + "expected ';' after private module fragment declaration">; def err_missing_before_module_end : Error<"expected %0 at end of module">; +def err_unsupported_module_partition : Error< + "sorry, module partitions are not yet supported">; def err_export_empty : Error<"export declaration cannot be empty">; } @@ -1255,4 +1287,12 @@ def err_for_co_await_not_range_for : Error< "'co_await' modifier can only be applied to range-based for loop">; } +let CategoryName = "Concepts Issue" in { +def err_concept_definition_not_identifier : Error< + "name defined in concept definition must be an identifier">; +def ext_concept_legacy_bool_keyword : ExtWarn< + "ISO C++2a does not permit the 'bool' keyword after 'concept'">, + InGroup<DiagGroup<"concepts-ts-compat">>; +} + } // end of Parser diagnostics diff --git a/include/clang/Basic/DiagnosticRefactoring.h b/include/clang/Basic/DiagnosticRefactoring.h index 8d3914f25289..aded0162ab33 100644 --- a/include/clang/Basic/DiagnosticRefactoring.h +++ b/include/clang/Basic/DiagnosticRefactoring.h @@ -1,9 +1,8 @@ //===--- DiagnosticRefactoring.h - ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticRefactoringKinds.td b/include/clang/Basic/DiagnosticRefactoringKinds.td index ee396b930729..5446b32efbdd 100644 --- a/include/clang/Basic/DiagnosticRefactoringKinds.td +++ b/include/clang/Basic/DiagnosticRefactoringKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticRefactoringKinds.td - refactoring diagnostics -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticSema.h b/include/clang/Basic/DiagnosticSema.h index b05b24db5609..72a6b9753893 100644 --- a/include/clang/Basic/DiagnosticSema.h +++ b/include/clang/Basic/DiagnosticSema.h @@ -1,9 +1,8 @@ //===--- DiagnosticSema.h - Diagnostics for libsema -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5feb877e46c5..effcbad78b23 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticSemaKinds.td - libsema diagnostics ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -84,11 +83,11 @@ def err_typecheck_converted_constant_expression_indirect : Error< "bind reference to a temporary">; def err_expr_not_cce : Error< "%select{case value|enumerator value|non-type template argument|" - "array size|constexpr if condition}0 " + "array size|constexpr if condition|explicit specifier argument}0 " "is not a constant expression">; def ext_cce_narrowing : ExtWarn< "%select{case value|enumerator value|non-type template argument|" - "array size|constexpr if condition}0 " + "array size|constexpr if condition|explicit specifier argument}0 " "%select{cannot be narrowed from type %2 to %3|" "evaluates to %2, which cannot be narrowed to type %3}1">, InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure; @@ -251,6 +250,8 @@ def err_bad_variable_name : Error< "%0 cannot be the name of a variable or data member">; def err_bad_parameter_name : Error< "%0 cannot be the name of a parameter">; +def err_bad_parameter_name_template_id : Error< + "parameter name cannot have template arguments">; def err_parameter_name_omitted : Error<"parameter name omitted">; def err_anyx86_interrupt_attribute : Error< "%select{x86|x86-64}0 'interrupt' attribute only applies to functions that " @@ -262,18 +263,14 @@ def err_anyx86_interrupt_called : Error< 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">, +def warn_interrupt_attribute_invalid : Warning< + "%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to " + "functions that have %select{no parameters|a 'void' return type}1">, InGroup<IgnoredAttributes>; def warn_riscv_repeated_interrupt_attribute : Warning< "repeated RISC-V 'interrupt' attribute">, InGroup<IgnoredAttributes>; def note_riscv_repeated_interrupt_attribute : Note< "repeated RISC-V 'interrupt' attribute is here">; -def warn_riscv_interrupt_attribute : Warning< - "RISC-V 'interrupt' attribute only applies to functions that have " - "%select{no parameters|a 'void' return type}0">, - InGroup<IgnoredAttributes>; def warn_unused_parameter : Warning<"unused parameter %0">, InGroup<UnusedParameter>, DefaultIgnore; def warn_unused_variable : Warning<"unused variable %0">, @@ -422,6 +419,15 @@ def ext_decomp_decl_cond : ExtWarn< def err_decomp_decl_spec : Error< "decomposition declaration cannot be declared " "%plural{1:'%1'|:with '%1' specifiers}0">; +def ext_decomp_decl_spec : ExtWarn< + "decomposition declaration declared " + "%plural{1:'%1'|:with '%1' specifiers}0 is a C++2a extension">, + InGroup<CXX2a>; +def warn_cxx17_compat_decomp_decl_spec : Warning< + "decomposition declaration declared " + "%plural{1:'%1'|:with '%1' specifiers}0 " + "is incompatible with C++ standards before C++2a">, + InGroup<CXXPre2aCompat>, DefaultIgnore; def err_decomp_decl_type : Error< "decomposition declaration cannot be declared with type %0; " "declared type must be 'auto' or reference to 'auto'">; @@ -614,6 +620,23 @@ def warn_cstruct_memaccess : Warning< InGroup<NonTrivialMemaccess>; def note_nontrivial_field : Note< "field is non-trivial to %select{copy|default-initialize}0">; +def err_non_trivial_c_union_in_invalid_context : Error< + "cannot %select{" + "use type %1 for a function/method parameter|" + "use type %1 for function/method return|" + "default-initialize an object of type %1|" + "declare an automatic variable of type %1|" + "copy-initialize an object of type %1|" + "assign to a variable of type %1|" + "construct an automatic compound literal of type %1|" + "capture a variable of type %1|" + "cannot use volatile type %1 where it causes an lvalue-to-rvalue conversion" + "}3 " + "since it %select{contains|is}2 a union that is non-trivial to " + "%select{default-initialize|destruct|copy}0">; +def note_non_trivial_c_union : Note< + "%select{%2 has subobjects that are|%3 has type %2 that is}0 " + "non-trivial to %select{default-initialize|destruct|copy}1">; def warn_dyn_class_memaccess : Warning< "%select{destination for|source of|first operand of|second operand of}0 this " "%1 call is a pointer to %select{|class containing a }2dynamic class %3; " @@ -675,11 +698,17 @@ def warn_assume_side_effects : Warning< "the argument to %0 has side effects that will be discarded">, InGroup<DiagGroup<"assume">>; -def warn_memcpy_chk_overflow : Warning< +def warn_builtin_chk_overflow : Warning< "'%0' will always overflow; destination buffer has size %1," " but size argument is %2">, InGroup<DiagGroup<"builtin-memcpy-chk-size">>; +def warn_fortify_source_overflow + : Warning<warn_builtin_chk_overflow.Text>, InGroup<FortifySource>; +def warn_fortify_source_size_mismatch : Warning< + "'%0' size argument is too large; destination buffer has size %1," + " but size argument is %2">, InGroup<FortifySource>; + /// main() // static main() is not an error in C, just in C++. def warn_static_main : Warning<"'main' should not be declared static">, @@ -692,7 +721,7 @@ def ext_noreturn_main : ExtWarn< "'main' is not allowed to be declared _Noreturn">, InGroup<Main>; def note_main_remove_noreturn : Note<"remove '_Noreturn'">; def err_constexpr_main : Error< - "'main' is not allowed to be declared constexpr">; + "'main' is not allowed to be declared %select{constexpr|consteval}0">; def err_deleted_main : Error<"'main' is not allowed to be deleted">; def err_mainlike_template_decl : Error<"%0 cannot be a template">; def err_main_returns_nonint : Error<"'main' must return 'int'">; @@ -892,6 +921,12 @@ def err_objc_root_class_subclass : Error< def err_restricted_superclass_mismatch : Error< "cannot subclass a class that was declared with the " "'objc_subclassing_restricted' attribute">; +def err_class_stub_subclassing_mismatch : Error< + "'objc_class_stub' attribute cannot be specified on a class that does not " + "have the 'objc_subclassing_restricted' attribute">; +def err_implementation_of_class_stub : Error< + "cannot declare implementation of a class declared with the " + "'objc_class_stub' attribute">; def warn_objc_root_class_missing : Warning< "class %0 defined without specifying a base class">, InGroup<ObjCRootClass>; @@ -921,6 +956,9 @@ def err_inconsistent_ivar_count : Error< "inconsistent number of instance variables specified">; def warn_undef_method_impl : Warning<"method definition for %0 not found">, InGroup<DiagGroup<"incomplete-implementation">>; +def warn_objc_boxing_invalid_utf8_string : Warning< + "string is ill-formed as UTF-8 and will become a null %0 when boxed">, + InGroup<ObjCBoxing>; def warn_conflicting_overriding_ret_types : Warning< "conflicting return type in " @@ -1590,6 +1628,9 @@ def err_explicit_non_ctor_or_conv_function : Error< def err_static_not_bitfield : Error<"static member %0 cannot be a bit-field">; def err_static_out_of_line : Error< "'static' can only be specified inside the class definition">; +def ext_static_out_of_line : ExtWarn< + err_static_out_of_line.Text>, + InGroup<MicrosoftTemplate>; def err_storage_class_for_static_member : Error< "static data member definition cannot specify a storage class">; def err_typedef_not_bitfield : Error<"typedef member %0 cannot be a bit-field">; @@ -1825,13 +1866,15 @@ def err_lvalue_reference_bind_to_unrelated : Error< "%diff{to type $ cannot bind to a value of unrelated type $|" "cannot bind to a value of unrelated type}1,2">; def err_reference_bind_drops_quals : Error< - "binding value %diff{of type $ to reference to type $|to reference}0,1 " - "drops %select{<<ERROR>>|'const'|'restrict'|'const' and 'restrict'|" - "'volatile'|'const' and 'volatile'|'restrict' and 'volatile'|" - "'const', 'restrict', and 'volatile'}2 qualifier%plural{1:|2:|4:|:s}2">; + "binding reference %diff{of type $ to value of type $|to value}0,1 " + "%select{drops %3 qualifier%plural{1:|2:|4:|:s}4|changes address space}2">; def err_reference_bind_failed : Error< - "reference %diff{to type $ could not bind to an %select{rvalue|lvalue}1 of " - "type $|could not bind to %select{rvalue|lvalue}1 of incompatible type}0,2">; + "reference %diff{to %select{type|incomplete type}1 $ could not bind to an " + "%select{rvalue|lvalue}2 of type $|could not bind to %select{rvalue|lvalue}2 of " + "incompatible type}0,3">; +def err_reference_bind_temporary_addrspace : Error< + "reference of type %0 cannot bind to a temporary object because of " + "address space mismatch">; def err_reference_bind_init_list : Error< "reference to type %0 cannot bind to an initializer list">; def err_init_list_bad_dest_type : Error< @@ -1901,8 +1944,8 @@ def note_var_declared_here : Note<"variable %0 is declared here">; def note_uninit_var_use : Note< "%select{uninitialized use occurs|variable is captured by block}0 here">; def warn_uninit_byref_blockvar_captured_by_block : Warning< - "block pointer variable %0 is uninitialized when captured by block">, - InGroup<Uninitialized>, DefaultIgnore; + "block pointer variable %0 is %select{uninitialized|null}1 when captured by " + "block">, InGroup<Uninitialized>, DefaultIgnore; def note_block_var_fixit_add_initialization : Note< "did you mean to use __block %0?">; def note_in_omitted_aggregate_initializer : Note< @@ -1982,8 +2025,8 @@ def err_auto_not_allowed : Error< "%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 " + "template template parameter|concept|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" @@ -2072,8 +2115,8 @@ def err_deduced_class_template_compound_type : Error< "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">; + "template template parameter|concept|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< @@ -2100,14 +2143,13 @@ def err_deduction_guide_invalid_specifier : Error< 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">; + "template template parameter|concept|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_redeclared : Error< + "redeclaration of deduction guide">; def err_deduction_guide_specialized : Error<"deduction guide cannot be " "%select{explicitly instantiated|explicitly specialized}0">; def err_deduction_guide_template_not_deducible : Error< @@ -2125,6 +2167,12 @@ def warn_cxx14_compat_class_template_argument_deduction : Warning< "class template argument deduction is incompatible with C++ standards " "before C++17%select{|; for compatibility, use explicit type name %1}0">, InGroup<CXXPre17Compat>, DefaultIgnore; +def warn_ctad_maybe_unsupported : Warning< + "%0 may not intend to support class template argument deduction">, + InGroup<CTADMaybeUnsupported>, DefaultIgnore; +def note_suppress_ctad_maybe_unsupported : Note< + "add a deduction guide to suppress this warning">; + // C++14 deduced return types def err_auto_fn_deduction_failure : Error< @@ -2279,14 +2327,17 @@ def warn_cxx14_compat_constexpr_not_const : Warning< InGroup<DiagGroup<"constexpr-not-const">>; def err_invalid_constexpr : Error< "%select{function parameter|typedef|non-static data member}0 " - "cannot be constexpr">; + "cannot be %select{constexpr|consteval}1">; def err_invalid_constexpr_member : Error<"non-static data member cannot be " "constexpr%select{; did you intend to make it %select{const|static}0?|}1">; def err_constexpr_tag : Error< - "%select{class|struct|interface|union|enum}0 cannot be marked constexpr">; -def err_constexpr_dtor : Error<"destructor cannot be marked constexpr">; -def err_constexpr_no_declarators : Error< - "constexpr can only be used in variable and function declarations">; + "%select{class|struct|interface|union|enum}0 " + "cannot be marked %select{constexpr|consteval}1">; +def err_constexpr_dtor : Error< + "destructor cannot be marked %select{constexpr|consteval}0">; +def err_constexpr_wrong_decl_kind : Error< + "%select{constexpr|consteval}0 can only be used " + "in %select{variable and |}0function declarations">; def err_invalid_constexpr_var_decl : Error< "constexpr variable declaration must be a definition">; def err_constexpr_static_mem_var_requires_init : Error< @@ -2296,9 +2347,12 @@ def err_constexpr_var_non_literal : Error< def err_constexpr_var_requires_const_init : Error< "constexpr variable %0 must be initialized by a constant expression">; def err_constexpr_redecl_mismatch : Error< - "%select{non-constexpr declaration of %0 follows constexpr declaration" - "|constexpr declaration of %0 follows non-constexpr declaration}1">; + "%select{non-constexpr|constexpr|consteval}1 declaration of %0" + " follows %select{non-constexpr|constexpr|consteval}2 declaration">; def err_constexpr_virtual : Error<"virtual function cannot be constexpr">; +def warn_cxx17_compat_constexpr_virtual : Warning< + "virtual constexpr functions are incompatible with " + "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; def err_constexpr_virtual_base : Error< "constexpr %select{member function|constructor}0 not allowed in " "%select{struct|interface|class}1 with virtual base " @@ -2309,12 +2363,12 @@ def note_non_literal_virtual_base : Note<"%select{struct|interface|class}0 " "with virtual base %plural{1:class|:classes}1 is not a literal type">; def note_constexpr_virtual_base_here : Note<"virtual base class declared here">; def err_constexpr_non_literal_return : Error< - "constexpr function's return type %0 is not a literal type">; + "%select{constexpr|consteval}0 function's return type %1 is not a literal type">; def err_constexpr_non_literal_param : Error< - "constexpr %select{function|constructor}1's %ordinal0 parameter type %2 is " + "%select{constexpr|consteval}2 %select{function|constructor}1's %ordinal0 parameter type %3 is " "not a literal type">; def err_constexpr_body_invalid_stmt : Error< - "statement not allowed in constexpr %select{function|constructor}0">; + "statement not allowed in %select{constexpr|consteval}1 %select{function|constructor}0">; def ext_constexpr_body_invalid_stmt : ExtWarn< "use of this statement in a constexpr %select{function|constructor}0 " "is a C++14 extension">, InGroup<CXX14>; @@ -2364,9 +2418,9 @@ def err_diagnose_if_invalid_diagnostic_type : Error< "invalid diagnostic type for 'diagnose_if'; use \"error\" or \"warning\" " "instead">; def err_constexpr_body_no_return : Error< - "no return statement in constexpr function">; + "no return statement in %select{constexpr|consteval}0 function">; def err_constexpr_return_missing_expr : Error< - "non-void constexpr function %0 should return a value">; + "non-void %select{constexpr|consteval}1 function %0 should return a value">; def warn_cxx11_compat_constexpr_body_no_return : Warning< "constexpr function with no return statements is incompatible with C++ " "standards before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore; @@ -2417,32 +2471,20 @@ def warn_private_extern : Warning< def note_private_extern : Note< "use __attribute__((visibility(\"hidden\"))) attribute instead">; -// C++ Concepts TS -def err_concept_wrong_decl_kind : Error< - "'concept' can only appear on the definition of a function template or variable template">; -def err_concept_decls_may_only_appear_in_namespace_scope : Error< - "concept declarations may only appear in namespace scope">; -def err_function_concept_not_defined : Error< - "function concept declaration must be a definition">; -def err_var_concept_not_initialized : Error< - "variable concept declaration must be initialized">; -def err_function_concept_exception_spec : Error< - "function concept cannot have exception specification">; -def err_concept_decl_invalid_specifiers : Error< - "%select{variable|function}0 concept cannot be declared " - "'%select{thread_local|inline|friend|constexpr}1'">; -def err_function_concept_with_params : Error< - "function concept cannot have any parameters">; -def err_function_concept_bool_ret : Error< - "declared return type of function concept must be 'bool'">; -def err_variable_concept_bool_decl : Error< - "declared type of variable concept must be 'bool'">; -def err_concept_specified_specialization : Error< - "'concept' cannot be applied on an " - "%select{explicit instantiation|explicit specialization|partial specialization}0">; -def err_concept_specialized : Error< - "%select{function|variable}0 concept cannot be " - "%select{explicitly instantiated|explicitly specialized|partially specialized}1">; +// C++ Concepts +def err_concept_initialized_with_non_bool_type : Error< + "constraint expression must be of type 'bool' but is of type %0">; +def err_concept_decls_may_only_appear_in_global_namespace_scope : Error< + "concept declarations may only appear in global or namespace scope">; +def err_concept_no_parameters : Error< + "concept template parameter list must have at least one parameter; explicit " + "specialization of concepts is not allowed">; +def err_concept_extra_headers : Error< + "extraneous template parameter list in concept definition">; +def err_concept_no_associated_constraints : Error< + "concept cannot have associated constraints">; +def err_concept_not_implemented : Error< + "sorry, unimplemented concepts feature %0 used">; def err_template_different_associated_constraints : Error< "associated constraints differ in template redeclaration">; @@ -2520,7 +2562,7 @@ def err_attribute_argument_n_type : Error< def err_attribute_argument_type : Error< "%0 attribute requires %select{int or bool|an integer " "constant|a string|an identifier}1">; -def err_attribute_argument_outof_range : Error< +def err_attribute_argument_out_of_range : Error< "%0 attribute requires integer constant between %1 and %2 inclusive">; def err_init_priority_object_attr : Error< "can only use 'init_priority' attribute on file-scope definitions " @@ -2568,6 +2610,20 @@ def err_format_attribute_result_not : Error<"function does not return %0">; def err_format_attribute_implicit_this_format_string : Error< "format attribute cannot specify the implicit this argument as the format " "string">; +def err_callback_attribute_no_callee : Error< + "'callback' attribute specifies no callback callee">; +def err_callback_attribute_invalid_callee : Error< + "'callback' attribute specifies invalid callback callee">; +def err_callback_attribute_multiple : Error< + "multiple 'callback' attributes specified">; +def err_callback_attribute_argument_unknown : Error< + "'callback' attribute argument %0 is not a known function parameter">; +def err_callback_callee_no_function_type : Error< + "'callback' attribute callee does not have function type">; +def err_callback_callee_is_variadic : Error< + "'callback' attribute callee may not be variadic">; +def err_callback_implicit_this_not_available : Error< + "'callback' argument at position %0 references unavailable implicit 'this'">; def err_init_method_bad_return_type : Error< "init methods must return an object pointer type, not %0">; def err_attribute_invalid_size : Error< @@ -2697,6 +2753,9 @@ def err_only_annotate_after_access_spec : Error< def err_attribute_section_invalid_for_target : Error< "argument to %select{'code_seg'|'section'}1 attribute is not valid for this target: %0">; +def warn_attribute_section_drectve : Warning< + "#pragma %0(\".drectve\") has undefined behavior, " + "use #pragma comment(linker, ...) instead">, InGroup<MicrosoftDrectveSection>; def warn_mismatched_section : Warning< "%select{codeseg|section}0 does not match previous declaration">, InGroup<Section>; def warn_attribute_section_on_redeclaration : Warning< @@ -2745,6 +2804,9 @@ def warn_dllimport_dropped_from_inline_function : Warning< InGroup<IgnoredAttributes>; def warn_attribute_ignored : Warning<"%0 attribute ignored">, InGroup<IgnoredAttributes>; +def warn_nothrow_attribute_ignored : Warning<"'nothrow' attribute conflicts with" + " exception specification; attribute ignored">, + InGroup<IgnoredAttributes>; def warn_attribute_ignored_on_inline : Warning<"%0 attribute ignored on inline function">, InGroup<IgnoredAttributes>; @@ -2833,6 +2895,9 @@ def warn_attribute_dllimport_static_field_definition : Warning< def warn_attribute_dllexport_explicit_instantiation_decl : Warning< "explicit instantiation declaration should not be 'dllexport'">, InGroup<DiagGroup<"dllexport-explicit-instantiation-decl">>; +def warn_attribute_dllexport_explicit_instantiation_def : Warning< + "'dllexport' attribute ignored on explicit instantiation definition">, + InGroup<IgnoredAttributes>; def warn_invalid_initializer_from_system_header : Warning< "invalid constructor form class in system header, should not be explicit">, InGroup<DiagGroup<"invalid-initializer-from-system-header">>; @@ -2892,8 +2957,15 @@ def err_attribute_vecreturn_only_pod_record : Error< def err_cconv_change : Error< "function declared '%0' here was previously declared " "%select{'%2'|without calling convention}1">; -def warn_cconv_ignored : Warning< - "calling convention %0 ignored for this target">, InGroup<IgnoredAttributes>; +def warn_cconv_unsupported : Warning< + "%0 calling convention is not supported %select{" + // Use CallingConventionIgnoredReason Enum to specify these. + "for this target" + "|on variadic function" + "|on constructor/destructor" + "|on builtin function" + "}1">, + InGroup<IgnoredAttributes>; def err_cconv_knr : Error< "function with no prototype cannot use the %0 calling convention">; def warn_cconv_knr : Warning< @@ -2901,12 +2973,6 @@ def warn_cconv_knr : Warning< InGroup<DiagGroup<"missing-prototype-for-cc">>; def err_cconv_varargs : Error< "variadic function cannot use %0 calling convention">; -def warn_cconv_varargs : Warning< - "%0 calling convention ignored on variadic function">, - InGroup<IgnoredAttributes>; -def warn_cconv_structors : Warning< - "%0 calling convention ignored on constructor/destructor">, - InGroup<IgnoredAttributes>; def err_regparm_mismatch : Error<"function declared with regparm(%0) " "attribute was previously declared " "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">; @@ -2925,6 +2991,12 @@ def err_base_specifier_attribute : Error< "%0 attribute cannot be applied to a base specifier">; def err_invalid_attribute_on_virtual_function : Error< "%0 attribute cannot be applied to virtual functions">; +def warn_declspec_allocator_nonpointer : Warning< + "ignoring __declspec(allocator) because the function return type %0 is not " + "a pointer or reference type">, InGroup<IgnoredAttributes>; +def err_cconv_incomplete_param_type : Error< + "parameter %0 must have a complete type to use function %1 with the %2 " + "calling convention">; def ext_cannot_use_trivial_abi : ExtWarn< "'trivial_abi' cannot be applied to %0">, InGroup<IgnoredAttributes>; @@ -3002,7 +3074,7 @@ def warn_thread_attribute_decl_not_lockable : Warning< def warn_thread_attribute_decl_not_pointer : Warning< "%0 only applies to pointer types; type here is %1">, InGroup<ThreadSafetyAttributes>, DefaultIgnore; -def err_attribute_argument_out_of_range : Error< +def err_attribute_argument_out_of_bounds_extra_info : Error< "%0 attribute parameter %1 is out of bounds: " "%plural{0:no parameters to index into|" "1:can only be 1, since there is one parameter|" @@ -3179,6 +3251,14 @@ def warn_impcast_integer_precision_constant : Warning< def warn_impcast_bitfield_precision_constant : Warning< "implicit truncation from %2 to bit-field changes value from %0 to %1">, InGroup<BitFieldConstantConversion>; +def warn_impcast_constant_int_to_objc_bool : Warning< + "implicit conversion from constant value %0 to BOOL; " + "the only well defined values for BOOL are YES and NO">, + InGroup<ObjCBoolConstantConversion>; + +def warn_impcast_fixed_point_range : Warning< + "implicit conversion from %0 cannot fit within the range of values for %1">, + InGroup<ImplicitFixedPointConversion>; def warn_impcast_literal_float_to_integer : Warning< "implicit conversion from %0 to %1 changes value from %2 to %3">, @@ -3456,6 +3536,9 @@ def warn_objc_secondary_init_missing_init_call : Warning< def warn_objc_implementation_missing_designated_init_override : Warning< "method override for the designated initializer of the superclass %objcinstance0 not found">, InGroup<ObjCDesignatedInit>; +def err_designated_init_attr_non_init : Error< + "'objc_designated_initializer' attribute only applies to init methods " + "of interface or class extension declarations">; // objc_bridge attribute diagnostics. def err_objc_attr_not_id : Error< @@ -3568,12 +3651,11 @@ def err_ovl_no_viable_member_function_in_call : Error< "no matching member function for call to %0">; def err_ovl_ambiguous_call : Error< "call to %0 is ambiguous">; -def err_ovl_deleted_call : Error< - "call to %select{unavailable|deleted}0 function %1%2">; +def err_ovl_deleted_call : Error<"call to deleted function %0">; def err_ovl_ambiguous_member_call : Error< "call to member function %0 is ambiguous">; def err_ovl_deleted_member_call : Error< - "call to %select{unavailable|deleted}0 member function %1%2">; + "call to deleted member function %0">; def note_ovl_too_many_candidates : Note< "remaining %0 candidate%s0 omitted; " "pass -fshow-overloads=all to show them">; @@ -3597,6 +3679,10 @@ def note_ovl_candidate : Note< "| has different qualifiers (expected %5 but found %6)" "| has different exception specification}4">; +def note_ovl_candidate_explicit_forbidden : Note< + "candidate %0 ignored: cannot be explicit">; +def note_explicit_bool_resolved_to_true : Note< + "explicit(bool) specifier resolved to true">; def note_ovl_candidate_inherited_constructor : Note< "constructor from base class %0 inherited here">; def note_ovl_candidate_inherited_constructor_slice : Note< @@ -3605,6 +3691,9 @@ def note_ovl_candidate_inherited_constructor_slice : Note< def note_ovl_candidate_illegal_constructor : Note< "candidate %select{constructor|template}0 ignored: " "instantiation %select{takes|would take}0 its own class type by value">; +def note_ovl_candidate_illegal_constructor_adrspace_mismatch : Note< + "candidate constructor ignored: cannot be used to construct an object " + "in address space %0">; def note_ovl_candidate_bad_deduction : Note< "candidate template ignored: failed template argument deduction">; def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored: " @@ -3787,7 +3876,7 @@ def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">; def err_ref_init_ambiguous : Error< "reference initialization of type %0 with initializer of type %1 is ambiguous">; def err_ovl_deleted_init : Error< - "call to %select{unavailable|deleted}0 constructor of %1">; + "call to deleted constructor of %0">; def err_ovl_deleted_special_init : Error< "call to implicitly-deleted %select{default constructor|copy constructor|" "move constructor|copy assignment operator|move assignment operator|" @@ -3799,7 +3888,7 @@ def err_ovl_ambiguous_oper_binary : Error< def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">; def note_assign_lhs_incomplete : Note<"type %0 is incomplete">; def err_ovl_deleted_oper : Error< - "overload resolution selected %select{unavailable|deleted}0 operator '%1'%2">; + "overload resolution selected deleted operator '%0'">; def err_ovl_deleted_special_oper : Error< "object of type %0 cannot be %select{constructed|copied|moved|assigned|" "assigned|destroyed}1 because its %sub{select_special_member_kind}1 is implicitly deleted">; @@ -3820,7 +3909,7 @@ def err_ovl_no_viable_object_call : Error< def err_ovl_ambiguous_object_call : Error< "call to object of type %0 is ambiguous">; def err_ovl_deleted_object_call : Error< - "call to %select{unavailable|deleted}0 function call operator in type %1%2">; + "call to deleted function call operator in type %0">; def note_ovl_surrogate_cand : Note<"conversion candidate of type %0">; def err_member_call_without_object : Error< "call to non-static member function without an object argument">; @@ -3920,15 +4009,25 @@ def err_template_member_noparams : Error< def err_template_tag_noparams : Error< "extraneous 'template<>' in declaration of %0 %1">; +def warn_cxx17_compat_adl_only_template_id : Warning< + "use of function template name with no prior function template " + "declaration in function call with explicit template arguments " + "is incompatible with C++ standards before C++2a">, + InGroup<CXXPre2aCompat>, DefaultIgnore; +def ext_adl_only_template_id : ExtWarn< + "use of function template name with no prior declaration in function call " + "with explicit template arguments is a C++2a extension">, InGroup<CXX2a>; + // C++ Template Argument Lists def err_template_missing_args : Error< "use of " "%select{class template|function template|variable template|alias template|" - "template template parameter|template}0 %1 requires template arguments">; + "template template parameter|concept|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|variable template|alias template|" - "template template parameter|template}1 %2">; + "template template parameter|concept|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">; @@ -4344,6 +4443,8 @@ def err_explicit_instantiation_of_typedef : Error< "explicit instantiation of typedef %0">; def err_explicit_instantiation_storage_class : Error< "explicit instantiation cannot have a storage class">; +def err_explicit_instantiation_internal_linkage : Error< + "explicit instantiation declaration of %0 with internal linkage">; def err_explicit_instantiation_not_known : Error< "explicit instantiation of %0 does not refer to a function template, " "variable template, member function, member class, or static data member">; @@ -4583,7 +4684,8 @@ def warn_missing_prototype : Warning< "no previous prototype for function %0">, InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore; def note_declaration_not_a_prototype : Note< - "this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function">; + "this declaration is not a prototype; add %select{'void'|parameter declarations}0 " + "to make it %select{a prototype for a zero-parameter function|one}0">; def warn_strict_prototypes : Warning< "this %select{function declaration is not|block declaration is not|" "old-style function definition is not preceded by}0 a prototype">, @@ -4591,6 +4693,9 @@ def warn_strict_prototypes : Warning< def warn_missing_variable_declarations : Warning< "no previous extern declaration for non-static variable %0">, InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore; +def note_static_for_internal_linkage : Note< + "declare 'static' if the %select{variable|function}0 is not intended to be " + "used outside of this translation unit">; def err_static_data_member_reinitialization : Error<"static data member %0 already has an initializer">; def err_redefinition : Error<"redefinition of %0">; @@ -4626,13 +4731,15 @@ def note_deleted_special_member_class_subobject : Note< "copy assignment operator of|move assignment operator of|destructor of|" "constructor inherited by}0 " "%1 is implicitly deleted because " - "%select{base class %3|%select{||||variant }4field %3}2 has " + "%select{base class %3|%select{||||variant }4field %3}2 " + "%select{has " "%select{no|a deleted|multiple|an inaccessible|a non-trivial}4 " "%select{%select{default constructor|copy constructor|move constructor|copy " "assignment operator|move assignment operator|destructor|" "%select{default|corresponding|default|default|default}4 constructor}0|" "destructor}5" - "%select{||s||}4">; + "%select{||s||}4" + "|is an ObjC pointer}6">; def note_deleted_default_ctor_uninit_field : Note< "%select{default constructor of|constructor inherited by}0 " "%1 is implicitly deleted because field %2 of " @@ -4993,12 +5100,12 @@ def warn_cxx98_compat_switch_into_protected_scope : Warning< def err_indirect_goto_without_addrlabel : Error< "indirect goto in function with no address-of-label expressions">; def err_indirect_goto_in_protected_scope : Error< - "cannot jump from this indirect goto statement to one of its possible targets">; + "cannot jump from this %select{indirect|asm}0 goto statement to one of its possible targets">; def warn_cxx98_compat_indirect_goto_in_protected_scope : Warning< - "jump from this indirect goto statement to one of its possible targets " + "jump from this %select{indirect|asm}0 goto statement to one of its possible targets " "is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; def note_indirect_goto_target : Note< - "possible target of indirect goto statement">; + "possible target of %select{indirect|asm}0 goto statement">; def note_protected_by_variable_init : Note< "jump bypasses variable initialization">; def note_protected_by_variable_nontriv_destructor : Note< @@ -5930,6 +6037,10 @@ def warn_tautological_constant_compare : Warning< "result of comparison %select{%3|%1}0 %2 " "%select{%1|%3}0 is always %4">, InGroup<TautologicalTypeLimitCompare>, DefaultIgnore; +def warn_tautological_compare_objc_bool : Warning< + "result of comparison of constant %0 with expression of type BOOL" + " is always %1, as the only well defined values for BOOL are YES and NO">, + InGroup<TautologicalObjCBoolCompare>; def warn_mixed_sign_comparison : Warning< "comparison of integers of different signs: %0 and %1">, @@ -6239,6 +6350,10 @@ def err_bad_cxx_cast_bitfield : Error< def err_bad_cxx_cast_qualifiers_away : Error< "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" "functional-style cast}0 from %1 to %2 casts away qualifiers">; +def err_bad_cxx_cast_addr_space_mismatch : Error< + "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" + "functional-style cast}0 from %1 to %2 converts between mismatching address" + " spaces">; def ext_bad_cxx_cast_qualifiers_away_incoherent : ExtWarn< "ISO C++ does not allow " "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" @@ -6319,13 +6434,15 @@ def err_variably_modified_typeid : Error<"'typeid' of variably modified type %0" def err_static_illegal_in_new : Error< "the 'static' modifier for the array size is not legal in new expressions">; def err_array_new_needs_size : Error< - "array size must be specified in new expressions">; + "array size must be specified in new expression with no initializer">; def err_bad_new_type : Error< "cannot allocate %select{function|reference}1 type %0 with new">; def err_new_incomplete_type : Error< "allocation of incomplete type %0">; def err_new_array_nonconst : Error< "only the first dimension of an allocated array may have dynamic size">; +def err_new_array_size_unknown_from_init : Error< + "cannot determine allocated array size from initializer">; def err_new_array_init_args : Error< "array 'new' cannot have initialization arguments">; def ext_new_paren_array_nonconst : ExtWarn< @@ -6511,6 +6628,12 @@ def err_throw_incomplete : Error< "cannot throw object of incomplete type %0">; def err_throw_incomplete_ptr : Error< "cannot throw pointer to object of incomplete type %0">; +def warn_throw_underaligned_obj : Warning< + "underaligned exception object thrown">, + InGroup<UnderalignedExceptionObject>; +def note_throw_underaligned_obj : Note< + "required alignment of type %0 (%1 bytes) is larger than the supported " + "alignment of C++ exception objects on this target (%2 bytes)">; def err_return_in_constructor_handler : Error< "return in the catch of a function try block of a constructor is illegal">; def warn_cdtor_function_try_handler_mem_expr : Warning< @@ -6589,6 +6712,11 @@ let CategoryName = "Lambda Issue" in { "cannot deduce type for lambda capture %0 from initializer of type %2">; def err_init_capture_deduction_failure_from_init_list : Error< "cannot deduce type for lambda capture %0 from initializer list">; + def warn_cxx17_compat_init_capture_pack : Warning< + "initialized lambda capture packs are incompatible with C++ standards " + "before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; + def ext_init_capture_pack : ExtWarn< + "initialized lambda pack captures are a C++2a extension">, InGroup<CXX2a>; // C++14 generic lambdas. def warn_cxx11_compat_generic_lambda : Warning< @@ -6807,7 +6935,7 @@ def ext_typecheck_convert_int_pointer : ExtWarn< "; take the address with &|" "; remove *|" "; remove &}3">, - InGroup<IntConversion>; + InGroup<IntConversion>, SFINAEFailure; def ext_typecheck_convert_pointer_void_func : Extension< "%select{%diff{assigning to $ from $|assigning to different types}0,1" "|%diff{passing $ to parameter of type $|" @@ -6952,6 +7080,19 @@ def err_typecheck_incompatible_address_space : Error< "sending to parameter of different type}0,1" "|%diff{casting $ to type $|casting between types}0,1}2" " changes address space of pointer">; +def err_typecheck_incompatible_nested_address_space : Error< + "%select{%diff{assigning $ to $|assigning to different types}1,0" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2" + " changes address space of nested pointer">; def err_typecheck_incompatible_ownership : Error< "%select{%diff{assigning $ to $|assigning to different types}1,0" "|%diff{passing $ to parameter of type $|" @@ -7121,7 +7262,7 @@ def err_kern_type_not_void_return : Error< def err_kern_is_nonstatic_method : Error< "kernel function %0 must be a free function or static member function">; def err_config_scalar_return : Error< - "CUDA special function 'cudaConfigureCall' must have scalar return type">; + "CUDA special function '%0' must have scalar return type">; def err_kern_call_not_global_function : Error< "kernel call to non-global function %0">; def err_global_call_not_config : Error< @@ -7396,6 +7537,10 @@ let CategoryName = "Inline Assembly Issue" in { "use constraint modifier \"%0\"">; def note_asm_input_duplicate_first : Note< "constraint '%0' is already present here">; + def error_duplicate_asm_operand_name : Error< + "duplicate use of asm operand name \"%0\"">; + def note_duplicate_asm_operand_name : Note< + "asm operand name \"%0\" first referenced here">; } def error_inoutput_conflict_with_clobber : Error< @@ -7730,12 +7875,12 @@ def err_defaulted_special_member_copy_const_param : Error< def err_defaulted_copy_assign_not_ref : Error< "the parameter for an explicitly-defaulted copy assignment operator must be an " "lvalue reference type">; -def err_incorrect_defaulted_exception_spec : Error< - "exception specification of explicitly defaulted " - "%sub{select_special_member_kind}0 does not match the calculated one">; def err_incorrect_defaulted_constexpr : Error< "defaulted definition of %sub{select_special_member_kind}0 " "is not constexpr">; +def err_incorrect_defaulted_consteval : Error< + "defaulted declaration of %sub{select_special_member_kind}0 " + "cannot be consteval because implicit definition is not constexpr">; def warn_defaulted_method_deleted : Warning< "explicitly defaulted %sub{select_special_member_kind}0 is implicitly " "deleted">, InGroup<DiagGroup<"defaulted-function-deleted">>; @@ -7819,7 +7964,8 @@ def warn_format_mix_positional_nonpositional_args : Warning< "cannot mix positional and non-positional arguments in format string">, InGroup<Format>; def warn_static_array_too_small : Warning< - "array argument is too small; contains %0 elements, callee requires at least %1">, + "array argument is too small; %select{contains %0 elements|is of size %0}2," + " callee requires at least %1">, InGroup<ArrayBounds>; def note_callee_static_array : Note< "callee declares array parameter as static here">; @@ -8531,6 +8677,10 @@ def err_invalid_astype_of_different_size : Error< "invalid reinterpretation: sizes of %0 and %1 must match">; def err_static_kernel : Error< "kernel functions cannot be declared static">; +def err_method_kernel : Error< + "kernel functions cannot be class members">; +def err_template_kernel : Error< + "kernel functions cannot be used in a template declaration, instantiation or specialization">; def err_opencl_ptrptr_kernel_param : Error< "kernel parameter cannot be declared as a pointer to a pointer">; def err_kernel_arg_address_space : Error< @@ -8673,6 +8823,14 @@ def err_opencl_builtin_expected_type : Error< def ext_opencl_ext_vector_type_rgba_selector: ExtWarn< "vector component name '%0' is an OpenCL version 2.2 feature">, InGroup<OpenCLUnsupportedRGBA>; + +def err_openclcxx_placement_new : Error< + "use of placement new requires explicit declaration">; + +// MIG routine annotations. +def warn_mig_server_routine_does_not_return_kern_return_t : Warning< + "'mig_server_routine' attribute only applies to routines that return a kern_return_t">, + InGroup<IgnoredAttributes>; } // end of sema category let CategoryName = "OpenMP Issue" in { @@ -8736,6 +8894,8 @@ def err_omp_threadprivate_incomplete_type : Error< "threadprivate variable with incomplete type %0">; def err_omp_no_dsa_for_variable : Error< "variable %0 must have explicitly specified data sharing attributes">; +def note_omp_default_dsa_none : Note< + "explicit data sharing attribute requested here">; def err_omp_wrong_dsa : Error< "%0 variable cannot be %1">; def err_omp_variably_modified_type_not_supported : Error< @@ -8954,6 +9114,14 @@ def err_omp_parent_cancel_region_ordered : Error< def err_omp_reduction_wrong_type : Error<"reduction type cannot be %select{qualified with 'const', 'volatile' or 'restrict'|a function|a reference|an array}0 type">; def err_omp_wrong_var_in_declare_reduction : Error<"only %select{'omp_priv' or 'omp_orig'|'omp_in' or 'omp_out'}0 variables are allowed in %select{initializer|combiner}0 expression">; def err_omp_declare_reduction_redefinition : Error<"redefinition of user-defined reduction for type %0">; +def err_omp_mapper_wrong_type : Error< + "mapper type must be of struct, union or class type">; +def err_omp_declare_mapper_wrong_var : Error< + "only variable %0 is allowed in map clauses of this 'omp declare mapper' directive">; +def err_omp_declare_mapper_redefinition : Error< + "redefinition of user-defined mapper for type %0 with name %1">; +def err_omp_invalid_mapper: Error< + "cannot find a valid user-defined mapper for type %0 with name %1">; def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">; def err_omp_typecheck_section_value : Error< "subscripted value is not an array or pointer">; @@ -9072,6 +9240,10 @@ def err_omp_requires_clause_redeclaration : Error < "Only one %0 clause can appear on a requires directive in a single translation unit">; def note_omp_requires_previous_clause : Note < "%0 clause previously used here">; +def err_omp_target_before_requires : Error < + "target region encountered before requires directive with '%0' clause">; +def note_omp_requires_encountered_target : Note < + "target previously encountered here">; def err_omp_invalid_scope : Error < "'#pragma omp %0' directive must appear only in file scope">; def note_omp_invalid_length_on_this_ptr_mapping : Note < @@ -9082,6 +9254,38 @@ def note_omp_invalid_subscript_on_this_ptr_map : Note < "expected 'this' subscript expression on map clause to be 'this[0]'">; def err_omp_invalid_map_this_expr : Error < "invalid 'this' expression on 'map' clause">; +def err_implied_omp_allocator_handle_t_not_found : Error< + "omp_allocator_handle_t type not found; include <omp.h>">; +def err_omp_expected_predefined_allocator : Error< + "expected one of the predefined allocators for the variables with the static " + "storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', " + "'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 'omp_low_lat_mem_alloc', " + "'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 'omp_thread_mem_alloc'">; +def warn_omp_used_different_allocator : Warning< + "allocate directive specifies %select{default|'%1'}0 allocator while " + "previously used %select{default|'%3'}2">, + InGroup<OpenMPClauses>; +def note_omp_previous_allocator : Note< + "previous allocator is specified here">; +def err_expected_allocator_clause : Error<"expected an 'allocator' clause " + "inside of the target region; provide an 'allocator' clause or use 'requires'" + " directive with the 'dynamic_allocators' clause">; +def err_expected_allocator_expression : Error<"expected an allocator expression " + "inside of the target region; provide an allocator expression or use 'requires'" + " directive with the 'dynamic_allocators' clause">; +def warn_omp_allocate_thread_on_task_target_directive : Warning< + "allocator with the 'thread' trait access has unspecified behavior on '%0' directive">, + InGroup<OpenMPClauses>; +def err_omp_expected_private_copy_for_allocate : Error< + "the referenced item is not found in any private clause on the same directive">; +def err_omp_stmt_depends_on_loop_counter : Error< + "the loop %select{initializer|condition}0 expression depends on the current loop control variable">; +def err_omp_invariant_or_linear_dependency : Error< + "expected loop invariant expression or '<invariant1> * %0 + <invariant2>' kind of expression">; +def err_omp_wrong_dependency_iterator_type : Error< + "expected an integer or a pointer type of the outer loop counter '%0' for non-rectangular nests">; +def err_omp_unsupported_type : Error < + "host requires %0 bit size %1 type support, but device '%2' does not support it">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { @@ -9115,7 +9319,7 @@ let CategoryName = "Modules Issue" in { def err_module_decl_in_module_map_module : Error< "'module' declaration found while building module from module map">; def err_module_decl_in_header_module : Error< - "'module' declaration found while building header module">; + "'module' declaration found while building header unit">; def err_module_interface_implementation_mismatch : Error< "missing 'export' specifier in module declaration while " "building module interface">; @@ -9133,6 +9337,9 @@ def err_module_redeclaration : Error< def note_prev_module_declaration : Note<"previous module declaration is here">; def err_module_declaration_missing : Error< "missing 'export module' declaration in module interface unit">; +def err_module_declaration_missing_after_global_module_introducer : Error< + "missing 'module' declaration at end of global module fragment " + "introduced here">; def err_module_private_specialization : Error< "%select{template|partial|member}0 specialization cannot be " "declared __module_private__">; @@ -9151,6 +9358,12 @@ def err_module_unimported_use_header : Error< "%select{declaration|definition|default argument|" "explicit specialization|partial specialization}0 of %1 must be imported " "from module '%2' before it is required">; +def err_module_unimported_use_global_module_fragment : Error< + "%select{missing '#include'|missing '#include %3'}2; " + "%select{||default argument of |explicit specialization of |" + "partial specialization of }0%1 must be " + "%select{declared|defined|defined|declared|declared}0 " + "before it is used">; def err_module_unimported_use_multiple : Error< "%select{declaration|definition|default argument|" "explicit specialization|partial specialization}0 of %1 must be imported " @@ -9170,12 +9383,48 @@ def err_module_self_import : Error< def err_module_import_in_implementation : Error< "@import of module '%0' in implementation of '%1'; use #import">; -// C++ Modules TS +// C++ Modules +def err_module_decl_not_at_start : Error< + "module declaration must occur at the start of the translation unit">; +def note_global_module_introducer_missing : Note< + "add 'module;' to the start of the file to introduce a " + "global module fragment">; +def err_export_within_anonymous_namespace : Error< + "export declaration appears within anonymous namespace">; +def note_anonymous_namespace : Note<"anonymous namespace begins here">; +def ext_export_no_name_block : ExtWarn< + "ISO C++20 does not permit %select{an empty|a static_assert}0 declaration " + "to appear in an export block">, InGroup<ExportUnnamed>; +def ext_export_no_names : ExtWarn< + "ISO C++20 does not permit a declaration that does not introduce any names " + "to be exported">, InGroup<ExportUnnamed>; +def note_export : Note<"export block begins here">; +def err_export_no_name : Error< + "%select{empty|static_assert|asm}0 declaration cannot be exported">; +def ext_export_using_directive : ExtWarn< + "ISO C++20 does not permit using directive to be exported">, + InGroup<DiagGroup<"export-using-directive">>; def err_export_within_export : Error< "export declaration appears within another export declaration">; +def err_export_internal : Error< + "declaration of %0 with internal linkage cannot be exported">; +def err_export_using_internal : Error< + "using declaration referring to %0 with internal linkage cannot be exported">; def err_export_not_in_module_interface : Error< - "export declaration can only be used within a module interface unit after " - "the module declaration">; + "export declaration can only be used within a module interface unit" + "%select{ after the module declaration|}0">; +def err_export_in_private_module_fragment : Error< + "export declaration cannot be used in a private module fragment">; +def note_private_module_fragment : Note< + "private module fragment begins here">; +def err_private_module_fragment_not_module : Error< + "private module fragment declaration with no preceding module declaration">; +def err_private_module_fragment_redefined : Error< + "private module fragment redefined">; +def err_private_module_fragment_not_module_interface : Error< + "private module fragment in module implementation unit">; +def note_not_module_interface_add_export : Note< + "add 'export' here if this is intended to be a module interface unit">; def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn< "ambiguous use of internal linkage declaration %0 defined in multiple modules">, @@ -9198,13 +9447,15 @@ def err_coroutine_objc_method : Error< "Objective-C methods as coroutines are not yet supported">; def err_coroutine_unevaluated_context : Error< "'%0' cannot be used in an unevaluated context">; +def err_coroutine_within_handler : Error< + "'%0' cannot be used in the handler of a try block">; def err_coroutine_outside_function : Error< "'%0' cannot be used outside a function">; def err_coroutine_invalid_func_context : Error< "'%1' cannot be used in %select{a constructor|a destructor" - "|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">; + "|the 'main' function|a constexpr function" + "|a function with a deduced return type|a varargs function" + "|a consteval function}0">; def err_implied_coroutine_type_not_found : Error< "%0 type was not found; include <experimental/coroutine> before defining " "a coroutine">; @@ -9442,7 +9693,7 @@ def err_multiversion_doesnt_support : Error< "attribute '%select{target|cpu_specific|cpu_dispatch}0' multiversioned functions do not " "yet support %select{function templates|virtual functions|" "deduced return types|constructors|destructors|deleted functions|" - "defaulted functions|constexpr functions}1">; + "defaulted functions|constexpr functions|consteval function}1">; def err_multiversion_not_allowed_on_main : Error< "'main' cannot be a multiversioned function">; def err_multiversion_not_supported : Error< @@ -9475,6 +9726,18 @@ def err_std_compare_type_not_supported : Error< "the type is not trivially copyable|" "the type does not have the expected form}1">; +// Memory Tagging Extensions (MTE) diagnostics +def err_memtag_arg_null_or_pointer : Error< + "%0 argument of MTE builtin function must be a null or a pointer (%1 invalid)">; +def err_memtag_any2arg_pointer : Error< + "at least one argument of MTE builtin function must be a pointer (%0, %1 invalid)">; +def err_memtag_arg_must_be_pointer : Error< + "%0 argument of MTE builtin function must be a pointer (%1 invalid)">; +def err_memtag_arg_must_be_integer : Error< + "%0 argument of MTE builtin function must be an integer type (%1 invalid)">; +def err_memtag_arg_must_be_unsigned : Error< + "%0 argument of MTE builtin function must be an unsigned integer type (%1 invalid)">; + def warn_dereference_of_noderef_type : Warning< "dereferencing %0; was declared with a 'noderef' type">, InGroup<NoDeref>; def warn_dereference_of_noderef_type_no_decl : Warning< @@ -9488,4 +9751,8 @@ def err_builtin_launder_invalid_arg : Error< "%select{non-pointer|function pointer|void pointer}0 argument to " "'__builtin_launder' is not allowed">; +def err_bit_cast_non_trivially_copyable : Error< + "__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">; +def err_bit_cast_type_size_mismatch : Error< + "__builtin_bit_cast source size does not equal destination size (%0 vs %1)">; } // end of sema component. diff --git a/include/clang/Basic/DiagnosticSerialization.h b/include/clang/Basic/DiagnosticSerialization.h index d19e638dcf13..7e46a36a7fd3 100644 --- a/include/clang/Basic/DiagnosticSerialization.h +++ b/include/clang/Basic/DiagnosticSerialization.h @@ -1,9 +1,8 @@ //===--- DiagnosticSerialization.h - Serialization Diagnostics -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td index 54237d16f5c1..43ba19b5853e 100644 --- a/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/include/clang/Basic/DiagnosticSerializationKinds.td @@ -1,9 +1,8 @@ //==--- DiagnosticSerializationKinds.td - serialization diagnostics -------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -73,6 +72,10 @@ def note_module_file_imported_by : Note< def err_module_file_not_module : Error< "AST file '%0' was not built as a module">, DefaultFatal; +def remark_module_import : Remark< + "importing module '%0'%select{| into '%3'}2 from '%1'">, + InGroup<ModuleImport>; + def err_imported_module_not_found : Error< "module '%0' in AST file '%1' (imported by AST file '%2') " "is not defined in any loaded module map file; " diff --git a/include/clang/Basic/ExceptionSpecificationType.h b/include/clang/Basic/ExceptionSpecificationType.h index 0c2c8e6d860a..5616860555c8 100644 --- a/include/clang/Basic/ExceptionSpecificationType.h +++ b/include/clang/Basic/ExceptionSpecificationType.h @@ -1,9 +1,8 @@ //===--- ExceptionSpecificationType.h ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -23,6 +22,7 @@ enum ExceptionSpecificationType { EST_DynamicNone, ///< throw() EST_Dynamic, ///< throw(T1, T2) EST_MSAny, ///< Microsoft throw(...) extension + EST_NoThrow, ///< Microsoft __declspec(nothrow) extension EST_BasicNoexcept, ///< noexcept EST_DependentNoexcept,///< noexcept(expression), value-dependent EST_NoexceptFalse, ///< noexcept(expression), evals to 'false' @@ -42,7 +42,8 @@ inline bool isComputedNoexcept(ExceptionSpecificationType ESpecType) { } inline bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType) { - return ESpecType == EST_BasicNoexcept || isComputedNoexcept(ESpecType); + return ESpecType == EST_BasicNoexcept || ESpecType == EST_NoThrow || + isComputedNoexcept(ESpecType); } inline bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType) { diff --git a/include/clang/Basic/ExpressionTraits.h b/include/clang/Basic/ExpressionTraits.h index 2983adde1ed6..85005330a0af 100644 --- a/include/clang/Basic/ExpressionTraits.h +++ b/include/clang/Basic/ExpressionTraits.h @@ -1,9 +1,8 @@ //===- ExpressionTraits.h - C++ Expression Traits Support Enums -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/Features.def b/include/clang/Basic/Features.def index 05464ed85f13..7081c02e83ea 100644 --- a/include/clang/Basic/Features.def +++ b/include/clang/Basic/Features.def @@ -1,9 +1,8 @@ //===--- Features.def - Features and Extensions database --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -43,6 +42,7 @@ FEATURE(address_sanitizer, FEATURE(hwaddress_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress)) +FEATURE(memtag_sanitizer, LangOpts.Sanitize.has(SanitizerKind::MemTag)) FEATURE(xray_instrument, LangOpts.XRayInstrument) FEATURE(undefined_behavior_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Undefined)) @@ -87,8 +87,6 @@ FEATURE(memory_sanitizer, SanitizerKind::KernelMemory)) FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) -FEATURE(efficiency_sanitizer, - LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) // Objective-C features FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE? @@ -96,7 +94,7 @@ FEATURE(objc_arc, LangOpts.ObjCAutoRefCount) FEATURE(objc_arc_fields, true) FEATURE(objc_arc_weak, LangOpts.ObjCWeak) FEATURE(objc_default_synthesize_properties, LangOpts.ObjC) -FEATURE(objc_fixed_enum, true) +FEATURE(objc_fixed_enum, LangOpts.ObjC) FEATURE(objc_instancetype, LangOpts.ObjC) FEATURE(objc_kindof, LangOpts.ObjC) FEATURE(objc_modules, LangOpts.ObjC && LangOpts.Modules) @@ -119,6 +117,9 @@ FEATURE(objc_bridge_id_on_typedefs, true) FEATURE(objc_generics, LangOpts.ObjC) FEATURE(objc_generics_variance, LangOpts.ObjC) FEATURE(objc_class_property, LangOpts.ObjC) +FEATURE(objc_c_static_assert, LangOpts.C11) +FEATURE(objc_cxx_static_assert, LangOpts.CPlusPlus11) +EXTENSION(objc_c_static_assert, true) // C11 features FEATURE(c_alignas, LangOpts.C11) FEATURE(c_alignof, LangOpts.C11) @@ -247,6 +248,8 @@ EXTENSION(cxx_variable_templates, LangOpts.CPlusPlus) // Miscellaneous language extensions EXTENSION(overloadable_unmarked, true) EXTENSION(pragma_clang_attribute_namespaces, true) +EXTENSION(pragma_clang_attribute_external_declaration, true) +EXTENSION(gnu_asm, LangOpts.GNUAsm) #undef EXTENSION #undef FEATURE diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h index e7891baf5304..96983475f454 100644 --- a/include/clang/Basic/FileManager.h +++ b/include/clang/Basic/FileManager.h @@ -1,9 +1,8 @@ //===--- FileManager.h - File System Probing and Caching --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -68,17 +67,15 @@ class FileEntry { unsigned UID; // A unique (small) ID for the file. llvm::sys::fs::UniqueID UniqueID; bool IsNamedPipe; - bool InPCH; bool IsValid; // Is this \c FileEntry initialized and valid? - bool DeferredOpen; // Created by getFile(OpenFile=0); may open later. /// The open file, if it is owned by the \p FileEntry. mutable std::unique_ptr<llvm::vfs::File> File; public: FileEntry() - : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false), - DeferredOpen(false) {} + : UniqueID(0, 0), IsNamedPipe(false), IsValid(false) + {} FileEntry(const FileEntry &) = delete; FileEntry &operator=(const FileEntry &) = delete; @@ -89,7 +86,6 @@ public: off_t getSize() const { return Size; } unsigned getUID() const { return UID; } const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; } - bool isInPCH() const { return InPCH; } time_t getModificationTime() const { return ModTime; } /// Return the directory the file lives in. @@ -110,8 +106,6 @@ public: bool isOpenForTests() const { return File != nullptr; } }; -struct FileData; - /// Implements support for file system lookup, file system caching, /// and directory search management. /// @@ -170,7 +164,7 @@ class FileManager : public RefCountedBase<FileManager> { // Caching. std::unique_ptr<FileSystemStatCache> StatCache; - bool getStatValue(StringRef Path, FileData &Data, bool isFile, + bool getStatValue(StringRef Path, llvm::vfs::Status &Status, bool isFile, std::unique_ptr<llvm::vfs::File> *F); /// Add all ancestors of the given path (pointing to either a file @@ -181,6 +175,10 @@ class FileManager : public RefCountedBase<FileManager> { void fillRealPathName(FileEntry *UFE, llvm::StringRef FileName); public: + /// Construct a file manager, optionally with a custom VFS. + /// + /// \param FS if non-null, the VFS to use. Otherwise uses + /// llvm::vfs::getRealFileSystem(). FileManager(const FileSystemOptions &FileSystemOpts, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr); ~FileManager(); @@ -223,9 +221,7 @@ public: FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; } const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } - IntrusiveRefCntPtr<llvm::vfs::FileSystem> getVirtualFileSystem() const { - return FS; - } + llvm::vfs::FileSystem &getVirtualFileSystem() const { return *FS; } /// Retrieve a file entry for a "virtual" file that acts as /// if there were a file with the given name on disk. diff --git a/include/clang/Basic/FileSystemOptions.h b/include/clang/Basic/FileSystemOptions.h index 8b8b13bb5686..458af0c7b659 100644 --- a/include/clang/Basic/FileSystemOptions.h +++ b/include/clang/Basic/FileSystemOptions.h @@ -1,9 +1,8 @@ //===--- FileSystemOptions.h - File System Options --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h index f93170c754d5..d37f2d507f83 100644 --- a/include/clang/Basic/FileSystemStatCache.h +++ b/include/clang/Basic/FileSystemStatCache.h @@ -1,9 +1,8 @@ //===- FileSystemStatCache.h - Caching for 'stat' calls ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -20,40 +19,15 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/VirtualFileSystem.h" #include <cstdint> #include <ctime> #include <memory> #include <string> #include <utility> -namespace llvm { - -namespace vfs { - -class File; -class FileSystem; - -} // namespace vfs -} // namespace llvm - namespace clang { -// FIXME: should probably replace this with vfs::Status -struct FileData { - std::string Name; - uint64_t Size = 0; - time_t ModTime = 0; - llvm::sys::fs::UniqueID UniqueID; - bool IsDirectory = false; - bool IsNamedPipe = false; - bool InPCH = false; - - // FIXME: remove this when files support multiple names - bool IsVFSMapped = false; - - FileData() = default; -}; - /// Abstract interface for introducing a FileManager cache for 'stat' /// system calls, which is used by precompiled and pretokenized headers to /// improve performance. @@ -63,14 +37,6 @@ class FileSystemStatCache { public: virtual ~FileSystemStatCache() = default; - enum LookupResult { - /// We know the file exists and its cached stat data. - CacheExists, - - /// We know that the file doesn't exist. - CacheMissing - }; - /// Get the 'stat' information for the specified path, using the cache /// to accelerate it if possible. /// @@ -81,17 +47,19 @@ public: /// success for directories (not files). On a successful file lookup, the /// implementation can optionally fill in \p F with a valid \p File object and /// the client guarantees that it will close it. - static bool get(StringRef Path, FileData &Data, bool isFile, - std::unique_ptr<llvm::vfs::File> *F, - FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS); + static std::error_code + get(StringRef Path, llvm::vfs::Status &Status, bool isFile, + std::unique_ptr<llvm::vfs::File> *F, + FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS); protected: // FIXME: The pointer here is a non-owning/optional reference to the // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but // Optional needs some work to support references so this isn't possible yet. - virtual LookupResult getStat(StringRef Path, FileData &Data, bool isFile, - std::unique_ptr<llvm::vfs::File> *F, - llvm::vfs::FileSystem &FS) = 0; + virtual std::error_code getStat(StringRef Path, llvm::vfs::Status &Status, + bool isFile, + std::unique_ptr<llvm::vfs::File> *F, + llvm::vfs::FileSystem &FS) = 0; }; /// A stat "cache" that can be used by FileManager to keep @@ -100,17 +68,19 @@ protected: class MemorizeStatCalls : public FileSystemStatCache { public: /// The set of stat() calls that have been seen. - llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls; + llvm::StringMap<llvm::vfs::Status, llvm::BumpPtrAllocator> StatCalls; using iterator = - llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator; + llvm::StringMap<llvm::vfs::Status, + llvm::BumpPtrAllocator>::const_iterator; iterator begin() const { return StatCalls.begin(); } iterator end() const { return StatCalls.end(); } - LookupResult getStat(StringRef Path, FileData &Data, bool isFile, - std::unique_ptr<llvm::vfs::File> *F, - llvm::vfs::FileSystem &FS) override; + std::error_code getStat(StringRef Path, llvm::vfs::Status &Status, + bool isFile, + std::unique_ptr<llvm::vfs::File> *F, + llvm::vfs::FileSystem &FS) override; }; } // namespace clang diff --git a/include/clang/Basic/FixedPoint.h b/include/clang/Basic/FixedPoint.h index 9a9b7cc9c1fb..a931e21e18f1 100644 --- a/include/clang/Basic/FixedPoint.h +++ b/include/clang/Basic/FixedPoint.h @@ -1,9 +1,8 @@ //===- FixedPoint.h - Fixed point constant handling -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -18,6 +17,8 @@ #define LLVM_CLANG_BASIC_FIXEDPOINT_H #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/raw_ostream.h" namespace clang { @@ -36,6 +37,8 @@ public: : Width(Width), Scale(Scale), IsSigned(IsSigned), IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) { assert(Width >= Scale && "Not enough room for the scale"); + assert(!(IsSigned && HasUnsignedPadding) && + "Cannot have unsigned padding on a signed type."); } unsigned getWidth() const { return Width; } @@ -46,6 +49,9 @@ public: void setSaturated(bool Saturated) { IsSaturated = Saturated; } + /// Return the number of integral bits represented by these semantics. These + /// are separate from the fractional bits and do not include the sign or + /// padding bit. unsigned getIntegralBits() const { if (IsSigned || (!IsSigned && HasUnsignedPadding)) return Width - Scale - 1; @@ -53,6 +59,21 @@ public: return Width - Scale; } + /// Return the FixedPointSemantics that allows for calculating the full + /// precision semantic that can precisely represent the precision and ranges + /// of both input values. This does not compute the resulting semantics for a + /// given binary operation. + FixedPointSemantics + getCommonSemantics(const FixedPointSemantics &Other) const; + + /// Return the FixedPointSemantics for an integer type. + static FixedPointSemantics GetIntegerSemantics(unsigned Width, + bool IsSigned) { + return FixedPointSemantics(Width, /*Scale=*/0, IsSigned, + /*IsSaturated=*/false, + /*HasUnsignedPadding=*/false); + } + private: unsigned Width; unsigned Scale; @@ -83,24 +104,45 @@ class APFixedPoint { : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()), Sema) {} + // Zero initialization. + APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {} + llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); } inline unsigned getWidth() const { return Sema.getWidth(); } inline unsigned getScale() const { return Sema.getScale(); } inline bool isSaturated() const { return Sema.isSaturated(); } inline bool isSigned() const { return Sema.isSigned(); } inline bool hasPadding() const { return Sema.hasUnsignedPadding(); } + FixedPointSemantics getSemantics() const { return Sema; } + + bool getBoolValue() const { return Val.getBoolValue(); } + + // Convert this number to match the semantics provided. If the overflow + // parameter is provided, set this value to true or false to indicate if this + // operation results in an overflow. + APFixedPoint convert(const FixedPointSemantics &DstSema, + bool *Overflow = nullptr) const; + + // Perform binary operations on a fixed point type. The resulting fixed point + // value will be in the common, full precision semantics that can represent + // the precision and ranges os both input values. See convert() for an + // explanation of the Overflow parameter. + APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const; - // Convert this number to match the semantics provided. - APFixedPoint convert(const FixedPointSemantics &DstSema) const; + /// Perform a unary negation (-X) on this fixed point type, taking into + /// account saturation if applicable. + APFixedPoint negate(bool *Overflow = nullptr) const; APFixedPoint shr(unsigned Amt) const { return APFixedPoint(Val >> Amt, Sema); - } + } APFixedPoint shl(unsigned Amt) const { return APFixedPoint(Val << Amt, Sema); } + /// Return the integral part of this fixed point number, rounded towards + /// zero. (-2.5k -> -2) llvm::APSInt getIntPart() const { if (Val < 0 && Val != -Val) // Cover the case when we have the min val return -(-Val >> getScale()); @@ -108,6 +150,24 @@ class APFixedPoint { return Val >> getScale(); } + /// Return the integral part of this fixed point number, rounded towards + /// zero. The value is stored into an APSInt with the provided width and sign. + /// If the overflow parameter is provided, and the integral value is not able + /// to be fully stored in the provided width and sign, the overflow parameter + /// is set to true. + /// + /// If the overflow parameter is provided, set this value to true or false to + /// indicate if this operation results in an overflow. + llvm::APSInt convertToInt(unsigned DstWidth, bool DstSign, + bool *Overflow = nullptr) const; + + void toString(llvm::SmallVectorImpl<char> &Str) const; + std::string toString() const { + llvm::SmallString<40> S; + toString(S); + return S.str(); + } + // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1. int compare(const APFixedPoint &Other) const; bool operator==(const APFixedPoint &Other) const { @@ -128,11 +188,25 @@ class APFixedPoint { static APFixedPoint getMax(const FixedPointSemantics &Sema); static APFixedPoint getMin(const FixedPointSemantics &Sema); + /// Create an APFixedPoint with a value equal to that of the provided integer, + /// and in the same semantics as the provided target semantics. If the value + /// is not able to fit in the specified fixed point semantics, and the + /// overflow parameter is provided, it is set to true. + static APFixedPoint getFromIntValue(const llvm::APSInt &Value, + const FixedPointSemantics &DstFXSema, + bool *Overflow = nullptr); + private: llvm::APSInt Val; FixedPointSemantics Sema; }; +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const APFixedPoint &FX) { + OS << FX.toString(); + return OS; +} + } // namespace clang #endif diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 82e8c8c34951..465486ede715 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -1,9 +1,8 @@ //===- IdentifierTable.h - Hash table for identifier lookup -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -939,9 +938,6 @@ struct DenseMapInfo<clang::Selector> { } }; -template <> -struct isPodLike<clang::Selector> { static const bool value = true; }; - template<> struct PointerLikeTypeTraits<clang::Selector> { static const void *getAsVoidPointer(clang::Selector P) { diff --git a/include/clang/Basic/JsonSupport.h b/include/clang/Basic/JsonSupport.h new file mode 100644 index 000000000000..bbcc747e6847 --- /dev/null +++ b/include/clang/Basic/JsonSupport.h @@ -0,0 +1,119 @@ +//===- JsonSupport.h - JSON Output Utilities --------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_JSONSUPPORT_H +#define LLVM_CLANG_BASIC_JSONSUPPORT_H + +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceManager.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" + + +namespace clang { + +inline raw_ostream &Indent(raw_ostream &Out, const unsigned int Space, + bool IsDot) { + for (unsigned int I = 0; I < Space * 2; ++I) + Out << (IsDot ? " " : " "); + return Out; +} + +inline std::string JsonFormat(StringRef RawSR, bool AddQuotes) { + if (RawSR.empty()) + return "null"; + + // Trim special characters. + std::string Str = RawSR.trim().str(); + size_t Pos = 0; + + // Escape backslashes. + while (true) { + Pos = Str.find('\\', Pos); + if (Pos == std::string::npos) + break; + + // Prevent bad conversions. + size_t TempPos = (Pos != 0) ? Pos - 1 : 0; + + // See whether the current backslash is not escaped. + if (TempPos != Str.find("\\\\", Pos)) { + Str.insert(Pos, "\\"); + ++Pos; // As we insert the backslash move plus one. + } + + ++Pos; + } + + // Escape double quotes. + Pos = 0; + while (true) { + Pos = Str.find('\"', Pos); + if (Pos == std::string::npos) + break; + + // Prevent bad conversions. + size_t TempPos = (Pos != 0) ? Pos - 1 : 0; + + // See whether the current double quote is not escaped. + if (TempPos != Str.find("\\\"", Pos)) { + Str.insert(Pos, "\\"); + ++Pos; // As we insert the escape-character move plus one. + } + + ++Pos; + } + + // Remove new-lines. + Str.erase(std::remove(Str.begin(), Str.end(), '\n'), Str.end()); + + if (!AddQuotes) + return Str; + + return '\"' + Str + '\"'; +} + +inline void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, + const SourceManager &SM, + bool AddBraces = true) { + // Mostly copy-pasted from SourceLocation::print. + if (!Loc.isValid()) { + Out << "null"; + return; + } + + if (Loc.isFileID()) { + PresumedLoc PLoc = SM.getPresumedLoc(Loc); + + if (PLoc.isInvalid()) { + Out << "null"; + return; + } + // The macro expansion and spelling pos is identical for file locs. + if (AddBraces) + Out << "{ "; + Out << "\"line\": " << PLoc.getLine() + << ", \"column\": " << PLoc.getColumn() + << ", \"file\": \"" << PLoc.getFilename() << "\""; + if (AddBraces) + Out << " }"; + return; + } + + // We want 'location: { ..., spelling: { ... }}' but not + // 'location: { ... }, spelling: { ... }', hence the dance + // with braces. + Out << "{ "; + printSourceLocationAsJson(Out, SM.getExpansionLoc(Loc), SM, false); + Out << ", \"spelling\": "; + printSourceLocationAsJson(Out, SM.getSpellingLoc(Loc), SM, true); + Out << " }"; +} +} // namespace clang + +#endif // LLVM_CLANG_BASIC_JSONSUPPORT_H diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h index 3f833c62c0a8..e9bb96af972e 100644 --- a/include/clang/Basic/LLVM.h +++ b/include/clang/Basic/LLVM.h @@ -1,9 +1,8 @@ //===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/Lambda.h b/include/clang/Basic/Lambda.h index 675854e67e7a..853821a33c2a 100644 --- a/include/clang/Basic/Lambda.h +++ b/include/clang/Basic/Lambda.h @@ -1,9 +1,8 @@ //===--- Lambda.h - Types for C++ Lambdas -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index 49961856c965..31aca2b0d695 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -1,9 +1,8 @@ //===--- LangOptions.def - Language option database -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -83,6 +82,7 @@ LANGOPT(C99 , 1, 0, "C99") LANGOPT(C11 , 1, 0, "C11") LANGOPT(C17 , 1, 0, "C17") +LANGOPT(C2x , 1, 0, "C2x") LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode") LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions") LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks") @@ -137,7 +137,7 @@ LANGOPT(Freestanding, 1, 0, "freestanding implementation") LANGOPT(NoBuiltin , 1, 0, "disable builtin functions") LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions") LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly") -LANGOPT(CoroutinesTS , 1, 0, "C++ coroutines TS") +LANGOPT(Coroutines , 1, 0, "C++20 coroutines") LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods") LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments") @@ -149,12 +149,14 @@ LANGOPT(Blocks , 1, 0, "blocks extension to C") BENIGN_LANGOPT(EmitAllDecls , 1, 0, "emitting all declarations") LANGOPT(MathErrno , 1, 1, "errno in math functions") BENIGN_LANGOPT(HeinousExtensions , 1, 0, "extensions that we really don't like and may be ripped out at any time") -LANGOPT(Modules , 1, 0, "modules extension to C") -COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS") +LANGOPT(Modules , 1, 0, "modules semantics") +COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS syntax") +COMPATIBLE_LANGOPT(CPlusPlusModules, 1, 0, "C++ modules syntax") BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None, "compiling a module interface") BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch") BENIGN_LANGOPT(BuildingPCHWithObjectFile, 1, 0, "building a pch which has a corresponding object file") +BENIGN_LANGOPT(CacheGeneratedPCH, 1, 0, "cache generated PCH files in memory") COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses") BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references") COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules") @@ -169,8 +171,12 @@ VALUE_LANGOPT(PackStruct , 32, 0, VALUE_LANGOPT(MaxTypeAlign , 32, 0, "default maximum alignment for types") VALUE_LANGOPT(AlignDouble , 1, 0, "Controls if doubles should be aligned to 8 bytes (x86 only)") +VALUE_LANGOPT(LongDoubleSize , 32, 0, "width of long double") +LANGOPT(PPCIEEELongDouble , 1, 0, "use IEEE 754 quadruple-precision for long double") COMPATIBLE_VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level") COMPATIBLE_VALUE_LANGOPT(PIE , 1, 0, "is pie") +LANGOPT(ROPI , 1, 0, "Read-only position independence") +LANGOPT(RWPI , 1, 0, "Read-write position independence") COMPATIBLE_LANGOPT(GNUInline , 1, 0, "GNU inline semantics") COMPATIBLE_LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro") COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro") @@ -191,8 +197,8 @@ LANGOPT(ShortEnums , 1, 0, "short enum types") LANGOPT(OpenCL , 1, 0, "OpenCL") LANGOPT(OpenCLVersion , 32, 0, "OpenCL C version") -LANGOPT(OpenCLCPlusPlus , 1, 0, "OpenCL C++") -LANGOPT(OpenCLCPlusPlusVersion , 32, 0, "OpenCL C++ version") +LANGOPT(OpenCLCPlusPlus , 1, 0, "C++ for OpenCL") +LANGOPT(OpenCLCPlusPlusVersion , 32, 0, "C++ for OpenCL version") LANGOPT(NativeHalfType , 1, 0, "Native half type support") LANGOPT(NativeHalfArgsAndReturns, 1, 0, "Native half args and returns") LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns") @@ -204,9 +210,9 @@ LANGOPT(OpenMPUseTLS , 1, 0, "Use TLS for threadprivates or runtime calls") LANGOPT(OpenMPIsDevice , 1, 0, "Generate code only for OpenMP target device") LANGOPT(OpenMPCUDAMode , 1, 0, "Generate code for OpenMP pragmas in SIMT/SPMD mode") LANGOPT(OpenMPCUDAForceFullRuntime , 1, 0, "Force to use full runtime in all constructs when offloading to CUDA devices") -LANGOPT(OpenMPHostCXXExceptions , 1, 0, "C++ exceptions handling in the host code.") LANGOPT(OpenMPCUDANumSMs , 32, 0, "Number of SMs for CUDA devices.") LANGOPT(OpenMPCUDABlocksPerSM , 32, 0, "Number of blocks per SM for CUDA devices.") +LANGOPT(OpenMPCUDAReductionBufNum , 32, 1024, "Number of the reduction records in the intermediate reduction buffer used for the teams reductions.") LANGOPT(OpenMPOptimisticCollapse , 1, 0, "Use at most 32 bits to represent the collapsed loop nest counter.") LANGOPT(RenderScript , 1, 0, "RenderScript") @@ -216,6 +222,8 @@ LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr function LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions") LANGOPT(GPURelocatableDeviceCode, 1, 0, "generate relocatable device code") +LANGOPT(SYCLIsDevice , 1, 0, "Generate code for SYCL device") + LANGOPT(SizedDeallocation , 1, 0, "sized deallocation") LANGOPT(AlignedAllocation , 1, 0, "aligned allocation") LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable") @@ -250,6 +258,7 @@ LANGOPT(CFProtectionBranch , 1, 0, "Control-Flow Branch Protection enabled") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode") LANGOPT(IncludeDefaultHeader, 1, 0, "Include default header file for OpenCL") +LANGOPT(DeclareOpenCLBuiltins, 1, 0, "Declare OpenCL builtin functions") BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing") LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime") LANGOPT( @@ -259,9 +268,11 @@ LANGOPT( ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode") ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility, - "value symbol visibility") + "default visibility for functions and variables [-fvisibility]") ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility, - "type symbol visibility") + "default visibility for types [-ftype-visibility]") +LANGOPT(SetVisibilityForExternDecls, 1, 0, + "apply global symbol visibility to external declarations without an explicit visibility") ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, "stack protector mode") ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, @@ -292,6 +303,8 @@ LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan " "field padding (0: none, 1:least " "aggressive, 2: more aggressive)") +LANGOPT(Cmse, 1, 0, "ARM Security extensions support") + LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation") LANGOPT(XRayAlwaysEmitCustomEvents, 1, 0, "controls whether to always emit intrinsic calls to " diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 9cff7c516043..8099eed28c5e 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -1,9 +1,8 @@ //===- LangOptions.h - C Language Family Language Options -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -110,7 +109,8 @@ public: MSVC2013 = 1800, MSVC2015 = 1900, MSVC2017 = 1910, - MSVC2017_5 = 1912 + MSVC2017_5 = 1912, + MSVC2017_7 = 1914, }; /// Clang versions with different platform ABI conformance. @@ -216,7 +216,7 @@ public: /// If none is specified, abort (GCC-compatible behaviour). std::string OverflowHandler; - /// The module currently being compiled as speficied by -fmodule-name. + /// The module currently being compiled as specified by -fmodule-name. std::string ModuleName; /// The name of the current module, of which the main source file @@ -266,7 +266,7 @@ public: /// Do we need to track the owning module for a local declaration? bool trackLocalOwningModule() const { - return isCompilingModule() || ModulesLocalVisibility || ModulesTS; + return isCompilingModule() || ModulesLocalVisibility; } bool isSignedOverflowDefined() const { diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h index 529cfa9f3f8d..696f85b18535 100644 --- a/include/clang/Basic/Linkage.h +++ b/include/clang/Basic/Linkage.h @@ -1,9 +1,8 @@ //===- Linkage.h - Linkage enumeration and utilities ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/MSP430Target.def b/include/clang/Basic/MSP430Target.def index 758113c5f575..a1e192c19261 100644 --- a/include/clang/Basic/MSP430Target.def +++ b/include/clang/Basic/MSP430Target.def @@ -1,9 +1,8 @@ //===--- MSP430Target.def - MSP430 Feature/Processor Database----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/MacroBuilder.h b/include/clang/Basic/MacroBuilder.h index b2edc972fee2..96e67cbbfa3f 100644 --- a/include/clang/Basic/MacroBuilder.h +++ b/include/clang/Basic/MacroBuilder.h @@ -1,9 +1,8 @@ //===--- MacroBuilder.h - CPP Macro building utility ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/MemoryBufferCache.h b/include/clang/Basic/MemoryBufferCache.h deleted file mode 100644 index c79c3c40e4eb..000000000000 --- a/include/clang/Basic/MemoryBufferCache.h +++ /dev/null @@ -1,80 +0,0 @@ -//===- 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 diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h index 02a4ef610b64..0f2549f09943 100644 --- a/include/clang/Basic/Module.h +++ b/include/clang/Basic/Module.h @@ -1,9 +1,8 @@ //===- Module.h - Describe a module -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -78,9 +77,11 @@ public: /// This is a C++ Modules TS module interface unit. ModuleInterfaceUnit, - /// This is a fragment of the global module within some C++ Modules - /// TS module. + /// This is a fragment of the global module within some C++ module. GlobalModuleFragment, + + /// This is the private module fragment within some C++ module. + PrivateModuleFragment, }; /// The kind of this module. @@ -112,6 +113,11 @@ public: /// eventually be exposed, for use in "private" modules. std::string ExportAsModule; + /// Does this Module scope describe part of the purview of a named C++ module? + bool isModulePurview() const { + return Kind == ModuleInterfaceUnit || Kind == PrivateModuleFragment; + } + private: /// The submodules of this module, indexed by name. std::vector<Module *> SubModules; @@ -535,6 +541,7 @@ public: /// /// \returns The submodule if found, or NULL otherwise. Module *findSubmodule(StringRef Name) const; + Module *findOrInferSubmodule(StringRef Name); /// Determine whether the specified module would be visible to /// a lookup at the end of this module. diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h index fcfbe56b496f..5329b38c2072 100644 --- a/include/clang/Basic/ObjCRuntime.h +++ b/include/clang/Basic/ObjCRuntime.h @@ -1,9 +1,8 @@ //===- ObjCRuntime.h - Objective-C Runtime Configuration --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -247,6 +246,22 @@ public: llvm_unreachable("bad kind"); } + /// Does this runtime provide the objc_alloc_init entrypoint? This can apply + /// the same optimization as objc_alloc, but also sends an -init message, + /// reducing code size on the caller. + bool shouldUseRuntimeFunctionForCombinedAllocInit() const { + switch (getKind()) { + case MacOSX: + return getVersion() >= VersionTuple(10, 14, 4); + case iOS: + return getVersion() >= VersionTuple(12, 2); + case WatchOS: + return getVersion() >= VersionTuple(5, 2); + default: + return false; + } + } + /// Does this runtime supports optimized setter entrypoints? bool hasOptimizedSetter() const { switch (getKind()) { @@ -414,6 +429,23 @@ public: } } + /// Returns true if this Objective-C runtime supports Objective-C class + /// stubs. + bool allowsClassStubs() const { + switch (getKind()) { + case FragileMacOSX: + case GCC: + case GNUstep: + case ObjFW: + return false; + case MacOSX: + case iOS: + case WatchOS: + return true; + } + llvm_unreachable("bad kind"); + } + /// Try to parse an Objective-C runtime specification from the given /// string. /// diff --git a/include/clang/Basic/OpenCLExtensionTypes.def b/include/clang/Basic/OpenCLExtensionTypes.def index b72f7efd6f28..84ffbe936b77 100644 --- a/include/clang/Basic/OpenCLExtensionTypes.def +++ b/include/clang/Basic/OpenCLExtensionTypes.def @@ -1,9 +1,8 @@ //===-- OpenCLExtensionTypes.def - Metadata about BuiltinTypes ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // This file extends builtin types database with OpenCL extension types. diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def index 5e7d2cb473c7..5536a6e8e4df 100644 --- a/include/clang/Basic/OpenCLExtensions.def +++ b/include/clang/Basic/OpenCLExtensions.def @@ -1,9 +1,8 @@ //===--- OpenCLExtensions.def - OpenCL extension list -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -82,6 +81,12 @@ OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U) OPENCLEXT_INTERNAL(cl_amd_media_ops, 100, ~0U) OPENCLEXT_INTERNAL(cl_amd_media_ops2, 100, ~0U) +// ARM OpenCL extensions +OPENCLEXT_INTERNAL(cl_arm_integer_dot_product_int8, 120, ~0U) +OPENCLEXT_INTERNAL(cl_arm_integer_dot_product_accumulate_int8, 120, ~0U) +OPENCLEXT_INTERNAL(cl_arm_integer_dot_product_accumulate_int16, 120, ~0U) +OPENCLEXT_INTERNAL(cl_arm_integer_dot_product_accumulate_saturate_int8, 120, ~0U) + // Intel OpenCL extensions OPENCLEXT_INTERNAL(cl_intel_subgroups, 120, ~0U) OPENCLEXT_INTERNAL(cl_intel_subgroups_short, 120, ~0U) diff --git a/include/clang/Basic/OpenCLImageTypes.def b/include/clang/Basic/OpenCLImageTypes.def index 0efed996ab96..cfb018a661ae 100644 --- a/include/clang/Basic/OpenCLImageTypes.def +++ b/include/clang/Basic/OpenCLImageTypes.def @@ -1,9 +1,8 @@ //===-- OpenCLImageTypes.def - Metadata about BuiltinTypes ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // This file extends builtin types database with OpenCL image singleton types. diff --git a/include/clang/Basic/OpenCLOptions.h b/include/clang/Basic/OpenCLOptions.h index cc4e9922dca0..47310da1d6d9 100644 --- a/include/clang/Basic/OpenCLOptions.h +++ b/include/clang/Basic/OpenCLOptions.h @@ -1,9 +1,8 @@ //===--- OpenCLOptions.h ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -15,6 +14,7 @@ #ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H #define LLVM_CLANG_BASIC_OPENCLOPTIONS_H +#include "clang/Basic/LangOptions.h" #include "llvm/ADT/StringMap.h" namespace clang { @@ -42,25 +42,29 @@ public: // Is supported as either an extension or an (optional) core feature for // OpenCL version \p CLVer. - bool isSupported(llvm::StringRef Ext, unsigned CLVer) const { + bool isSupported(llvm::StringRef Ext, LangOptions LO) const { + // In C++ mode all extensions should work at least as in v2.0. + auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; auto I = OptMap.find(Ext)->getValue(); return I.Supported && I.Avail <= CLVer; } // Is supported (optional) OpenCL core features for OpenCL version \p CLVer. // For supported extension, return false. - bool isSupportedCore(llvm::StringRef Ext, unsigned CLVer) const { + bool isSupportedCore(llvm::StringRef Ext, LangOptions LO) const { + // In C++ mode all extensions should work at least as in v2.0. + auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.Avail <= CLVer && - I.Core != ~0U && CLVer >= I.Core; + return I.Supported && I.Avail <= CLVer && I.Core != ~0U && CLVer >= I.Core; } // Is supported OpenCL extension for OpenCL version \p CLVer. // For supported (optional) core feature, return false. - bool isSupportedExtension(llvm::StringRef Ext, unsigned CLVer) const { + bool isSupportedExtension(llvm::StringRef Ext, LangOptions LO) const { + // In C++ mode all extensions should work at least as in v2.0. + auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.Avail <= CLVer && - (I.Core == ~0U || CLVer < I.Core); + return I.Supported && I.Avail <= CLVer && (I.Core == ~0U || CLVer < I.Core); } void enable(llvm::StringRef Ext, bool V = true) { @@ -122,10 +126,10 @@ public: I->second.Enabled = false; } - void enableSupportedCore(unsigned CLVer) { - for (llvm::StringMap<Info>::iterator I = OptMap.begin(), - E = OptMap.end(); I != E; ++I) - if (isSupportedCore(I->getKey(), CLVer)) + void enableSupportedCore(LangOptions LO) { + for (llvm::StringMap<Info>::iterator I = OptMap.begin(), E = OptMap.end(); + I != E; ++I) + if (isSupportedCore(I->getKey(), LO)) I->second.Enabled = true; } @@ -133,6 +137,6 @@ public: friend class ASTReader; }; -} // end namespace clang +} // end namespace clang #endif diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def index f86721b1b07e..9685af4cade8 100644 --- a/include/clang/Basic/OpenMPKinds.def +++ b/include/clang/Basic/OpenMPKinds.def @@ -1,9 +1,8 @@ //===--- OpenMPKinds.def - OpenMP directives and clauses list ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file @@ -123,6 +122,12 @@ #ifndef OPENMP_MAP_MODIFIER_KIND #define OPENMP_MAP_MODIFIER_KIND(Name) #endif +#ifndef OPENMP_TO_MODIFIER_KIND +#define OPENMP_TO_MODIFIER_KIND(Name) +#endif +#ifndef OPENMP_FROM_MODIFIER_KIND +#define OPENMP_FROM_MODIFIER_KIND(Name) +#endif #ifndef OPENMP_DIST_SCHEDULE_KIND #define OPENMP_DIST_SCHEDULE_KIND(Name) #endif @@ -180,6 +185,12 @@ #ifndef OPENMP_TASKGROUP_CLAUSE #define OPENMP_TASKGROUP_CLAUSE(Name) #endif +#ifndef OPENMP_DECLARE_MAPPER_CLAUSE +#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) +#endif +#ifndef OPENMP_ALLOCATE_CLAUSE +# define OPENMP_ALLOCATE_CLAUSE(Name) +#endif // OpenMP directives. OPENMP_DIRECTIVE(threadprivate) @@ -215,6 +226,7 @@ OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections") OPENMP_DIRECTIVE_EXT(for_simd, "for simd") OPENMP_DIRECTIVE_EXT(cancellation_point, "cancellation point") OPENMP_DIRECTIVE_EXT(declare_reduction, "declare reduction") +OPENMP_DIRECTIVE_EXT(declare_mapper, "declare mapper") OPENMP_DIRECTIVE_EXT(declare_simd, "declare simd") OPENMP_DIRECTIVE(taskloop) OPENMP_DIRECTIVE_EXT(taskloop_simd, "taskloop simd") @@ -235,8 +247,10 @@ OPENMP_DIRECTIVE_EXT(target_teams_distribute, "target teams distribute") OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for, "target teams distribute parallel for") OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for_simd, "target teams distribute parallel for simd") OPENMP_DIRECTIVE_EXT(target_teams_distribute_simd, "target teams distribute simd") +OPENMP_DIRECTIVE(allocate) // OpenMP clauses. +OPENMP_CLAUSE(allocator, OMPAllocatorClause) OPENMP_CLAUSE(if, OMPIfClause) OPENMP_CLAUSE(final, OMPFinalClause) OPENMP_CLAUSE(num_threads, OMPNumThreadsClause) @@ -290,6 +304,7 @@ OPENMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) +OPENMP_CLAUSE(allocate, OMPAllocateClause) // Clauses allowed for OpenMP directive 'parallel'. OPENMP_PARALLEL_CLAUSE(if) @@ -301,6 +316,7 @@ OPENMP_PARALLEL_CLAUSE(firstprivate) OPENMP_PARALLEL_CLAUSE(shared) OPENMP_PARALLEL_CLAUSE(reduction) OPENMP_PARALLEL_CLAUSE(copyin) +OPENMP_PARALLEL_CLAUSE(allocate) // Clauses allowed for directive 'omp simd'. OPENMP_SIMD_CLAUSE(private) @@ -311,6 +327,7 @@ OPENMP_SIMD_CLAUSE(safelen) OPENMP_SIMD_CLAUSE(simdlen) OPENMP_SIMD_CLAUSE(collapse) OPENMP_SIMD_CLAUSE(reduction) +OPENMP_SIMD_CLAUSE(allocate) // Clauses allowed for directive 'omp for'. OPENMP_FOR_CLAUSE(private) @@ -322,6 +339,7 @@ OPENMP_FOR_CLAUSE(schedule) OPENMP_FOR_CLAUSE(ordered) OPENMP_FOR_CLAUSE(nowait) OPENMP_FOR_CLAUSE(linear) +OPENMP_FOR_CLAUSE(allocate) // Clauses allowed for directive 'omp for simd'. OPENMP_FOR_SIMD_CLAUSE(private) @@ -336,6 +354,7 @@ OPENMP_FOR_SIMD_CLAUSE(simdlen) OPENMP_FOR_SIMD_CLAUSE(linear) OPENMP_FOR_SIMD_CLAUSE(aligned) OPENMP_FOR_SIMD_CLAUSE(ordered) +OPENMP_FOR_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'omp sections'. OPENMP_SECTIONS_CLAUSE(private) @@ -343,12 +362,14 @@ OPENMP_SECTIONS_CLAUSE(lastprivate) OPENMP_SECTIONS_CLAUSE(firstprivate) OPENMP_SECTIONS_CLAUSE(reduction) OPENMP_SECTIONS_CLAUSE(nowait) +OPENMP_SECTIONS_CLAUSE(allocate) // Clauses allowed for directive 'omp single'. OPENMP_SINGLE_CLAUSE(private) OPENMP_SINGLE_CLAUSE(firstprivate) OPENMP_SINGLE_CLAUSE(copyprivate) OPENMP_SINGLE_CLAUSE(nowait) +OPENMP_SINGLE_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'cancel'. OPENMP_CANCEL_CLAUSE(if) @@ -384,6 +405,7 @@ OPENMP_DEFAULTMAP_MODIFIER(tofrom) OPENMP_DEPEND_KIND(in) OPENMP_DEPEND_KIND(out) OPENMP_DEPEND_KIND(inout) +OPENMP_DEPEND_KIND(mutexinoutset) OPENMP_DEPEND_KIND(source) OPENMP_DEPEND_KIND(sink) @@ -407,6 +429,7 @@ OPENMP_PARALLEL_FOR_CLAUSE(collapse) OPENMP_PARALLEL_FOR_CLAUSE(schedule) OPENMP_PARALLEL_FOR_CLAUSE(ordered) OPENMP_PARALLEL_FOR_CLAUSE(linear) +OPENMP_PARALLEL_FOR_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'parallel for simd'. OPENMP_PARALLEL_FOR_SIMD_CLAUSE(if) @@ -426,6 +449,7 @@ OPENMP_PARALLEL_FOR_SIMD_CLAUSE(simdlen) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(linear) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(aligned) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(ordered) +OPENMP_PARALLEL_FOR_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'parallel sections'. OPENMP_PARALLEL_SECTIONS_CLAUSE(if) @@ -438,6 +462,7 @@ OPENMP_PARALLEL_SECTIONS_CLAUSE(shared) OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction) OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin) OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate) +OPENMP_PARALLEL_SECTIONS_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'task'. OPENMP_TASK_CLAUSE(if) @@ -451,6 +476,7 @@ OPENMP_TASK_CLAUSE(mergeable) OPENMP_TASK_CLAUSE(depend) OPENMP_TASK_CLAUSE(priority) OPENMP_TASK_CLAUSE(in_reduction) +OPENMP_TASK_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'atomic'. OPENMP_ATOMIC_CLAUSE(read) @@ -470,6 +496,7 @@ OPENMP_TARGET_CLAUSE(defaultmap) OPENMP_TARGET_CLAUSE(firstprivate) OPENMP_TARGET_CLAUSE(is_device_ptr) OPENMP_TARGET_CLAUSE(reduction) +OPENMP_TARGET_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'requires'. OPENMP_REQUIRES_CLAUSE(unified_address) @@ -478,6 +505,9 @@ OPENMP_REQUIRES_CLAUSE(reverse_offload) OPENMP_REQUIRES_CLAUSE(dynamic_allocators) OPENMP_REQUIRES_CLAUSE(atomic_default_mem_order) +// Clauses allowed for OpenMP directive 'allocate'. +OPENMP_ALLOCATE_CLAUSE(allocator) + // Modifiers for 'atomic_default_mem_order' clause. OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst) OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel) @@ -518,6 +548,7 @@ OPENMP_TARGET_PARALLEL_CLAUSE(proc_bind) OPENMP_TARGET_PARALLEL_CLAUSE(shared) OPENMP_TARGET_PARALLEL_CLAUSE(reduction) OPENMP_TARGET_PARALLEL_CLAUSE(is_device_ptr) +OPENMP_TARGET_PARALLEL_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'target parallel for'. OPENMP_TARGET_PARALLEL_FOR_CLAUSE(if) @@ -539,6 +570,7 @@ OPENMP_TARGET_PARALLEL_FOR_CLAUSE(schedule) OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered) OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear) OPENMP_TARGET_PARALLEL_FOR_CLAUSE(is_device_ptr) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'target update'. OPENMP_TARGET_UPDATE_CLAUSE(if) @@ -556,6 +588,7 @@ OPENMP_TEAMS_CLAUSE(shared) OPENMP_TEAMS_CLAUSE(reduction) OPENMP_TEAMS_CLAUSE(num_teams) OPENMP_TEAMS_CLAUSE(thread_limit) +OPENMP_TEAMS_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'ordered'. OPENMP_ORDERED_CLAUSE(threads) @@ -573,6 +606,13 @@ OPENMP_MAP_KIND(release) // Map-type-modifiers for 'map' clause. OPENMP_MAP_MODIFIER_KIND(always) OPENMP_MAP_MODIFIER_KIND(close) +OPENMP_MAP_MODIFIER_KIND(mapper) + +// Modifiers for 'to' clause. +OPENMP_TO_MODIFIER_KIND(mapper) + +// Modifiers for 'from' clause. +OPENMP_FROM_MODIFIER_KIND(mapper) // Clauses allowed for OpenMP directive 'taskloop'. OPENMP_TASKLOOP_CLAUSE(if) @@ -591,6 +631,7 @@ OPENMP_TASKLOOP_CLAUSE(nogroup) OPENMP_TASKLOOP_CLAUSE(num_tasks) OPENMP_TASKLOOP_CLAUSE(reduction) OPENMP_TASKLOOP_CLAUSE(in_reduction) +OPENMP_TASKLOOP_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'taskloop simd'. OPENMP_TASKLOOP_SIMD_CLAUSE(if) @@ -613,6 +654,7 @@ OPENMP_TASKLOOP_SIMD_CLAUSE(nogroup) OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks) OPENMP_TASKLOOP_SIMD_CLAUSE(reduction) OPENMP_TASKLOOP_SIMD_CLAUSE(in_reduction) +OPENMP_TASKLOOP_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'critical'. OPENMP_CRITICAL_CLAUSE(hint) @@ -623,6 +665,7 @@ OPENMP_DISTRIBUTE_CLAUSE(firstprivate) OPENMP_DISTRIBUTE_CLAUSE(lastprivate) OPENMP_DISTRIBUTE_CLAUSE(collapse) OPENMP_DISTRIBUTE_CLAUSE(dist_schedule) +OPENMP_DISTRIBUTE_CLAUSE(allocate) // Static attributes for 'dist_schedule' clause. OPENMP_DIST_SCHEDULE_KIND(static) @@ -641,6 +684,7 @@ OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'distribute parallel for simd' OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) @@ -660,6 +704,7 @@ OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'distribute simd' OPENMP_DISTRIBUTE_SIMD_CLAUSE(private) @@ -672,6 +717,7 @@ OPENMP_DISTRIBUTE_SIMD_CLAUSE(aligned) OPENMP_DISTRIBUTE_SIMD_CLAUSE(safelen) OPENMP_DISTRIBUTE_SIMD_CLAUSE(simdlen) OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'target parallel for simd'. OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if) @@ -696,6 +742,7 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen) OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen) OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned) OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'target simd'. OPENMP_TARGET_SIMD_CLAUSE(if) @@ -714,6 +761,7 @@ OPENMP_TARGET_SIMD_CLAUSE(safelen) OPENMP_TARGET_SIMD_CLAUSE(simdlen) OPENMP_TARGET_SIMD_CLAUSE(collapse) OPENMP_TARGET_SIMD_CLAUSE(reduction) +OPENMP_TARGET_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'teams distribute'. OPENMP_TEAMS_DISTRIBUTE_CLAUSE(default) @@ -726,6 +774,7 @@ OPENMP_TEAMS_DISTRIBUTE_CLAUSE(thread_limit) OPENMP_TEAMS_DISTRIBUTE_CLAUSE(lastprivate) OPENMP_TEAMS_DISTRIBUTE_CLAUSE(collapse) OPENMP_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule) +OPENMP_TEAMS_DISTRIBUTE_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'teams distribute simd' OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(default) @@ -742,6 +791,7 @@ OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear) OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned) OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen) OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen) +OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'teams distribute parallel for simd' OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) @@ -762,6 +812,7 @@ OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams) OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit) +OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'teams distribute parallel for' OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) @@ -779,6 +830,7 @@ OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams) OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit) OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) +OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'target teams'. OPENMP_TARGET_TEAMS_CLAUSE(if) @@ -795,6 +847,7 @@ OPENMP_TARGET_TEAMS_CLAUSE(shared) OPENMP_TARGET_TEAMS_CLAUSE(reduction) OPENMP_TARGET_TEAMS_CLAUSE(num_teams) OPENMP_TARGET_TEAMS_CLAUSE(thread_limit) +OPENMP_TARGET_TEAMS_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'target teams distribute'. OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(if) @@ -814,6 +867,7 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(thread_limit) OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(lastprivate) OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(collapse) OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule) +OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'target teams distribute parallel for'. OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) @@ -836,6 +890,7 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) +OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) // Clauses allowed for OpenMP directive // 'target teams distribute parallel for simd'. @@ -863,6 +918,7 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) +OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'target teams distribute simd'. OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if) @@ -885,10 +941,17 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear) OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned) OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen) OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen) +OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate) // Clauses allowed for OpenMP directive 'taskgroup'. OPENMP_TASKGROUP_CLAUSE(task_reduction) +OPENMP_TASKGROUP_CLAUSE(allocate) + +// Clauses allowed for OpenMP directive 'declare mapper'. +OPENMP_DECLARE_MAPPER_CLAUSE(map) +#undef OPENMP_ALLOCATE_CLAUSE +#undef OPENMP_DECLARE_MAPPER_CLAUSE #undef OPENMP_TASKGROUP_CLAUSE #undef OPENMP_TASKLOOP_SIMD_CLAUSE #undef OPENMP_TASKLOOP_CLAUSE @@ -926,6 +989,8 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction) #undef OPENMP_FOR_SIMD_CLAUSE #undef OPENMP_MAP_KIND #undef OPENMP_MAP_MODIFIER_KIND +#undef OPENMP_TO_MODIFIER_KIND +#undef OPENMP_FROM_MODIFIER_KIND #undef OPENMP_DISTRIBUTE_CLAUSE #undef OPENMP_DIST_SCHEDULE_KIND #undef OPENMP_DEFAULTMAP_KIND diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h index 3e03a48cf68e..d8dee2310ec2 100644 --- a/include/clang/Basic/OpenMPKinds.h +++ b/include/clang/Basic/OpenMPKinds.h @@ -1,9 +1,8 @@ //===--- OpenMPKinds.h - OpenMP enums ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -105,6 +104,22 @@ enum OpenMPMapModifierKind { OMPC_MAP_MODIFIER_last }; +/// OpenMP modifier kind for 'to' clause. +enum OpenMPToModifierKind { +#define OPENMP_TO_MODIFIER_KIND(Name) \ + OMPC_TO_MODIFIER_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_TO_MODIFIER_unknown +}; + +/// OpenMP modifier kind for 'from' clause. +enum OpenMPFromModifierKind { +#define OPENMP_FROM_MODIFIER_KIND(Name) \ + OMPC_FROM_MODIFIER_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_FROM_MODIFIER_unknown +}; + /// OpenMP attributes for 'dist_schedule' clause. enum OpenMPDistScheduleClauseKind { #define OPENMP_DIST_SCHEDULE_KIND(Name) OMPC_DIST_SCHEDULE_##Name, diff --git a/include/clang/Basic/OperatorKinds.def b/include/clang/Basic/OperatorKinds.def index d86294bac902..d464db29274e 100644 --- a/include/clang/Basic/OperatorKinds.def +++ b/include/clang/Basic/OperatorKinds.def @@ -1,9 +1,8 @@ //===--- OperatorKinds.def - C++ Overloaded Operator Database ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/OperatorKinds.h b/include/clang/Basic/OperatorKinds.h index 3096f835e66b..9757acaa5300 100644 --- a/include/clang/Basic/OperatorKinds.h +++ b/include/clang/Basic/OperatorKinds.h @@ -1,9 +1,8 @@ //===--- OperatorKinds.h - C++ Overloaded Operators -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/OperatorPrecedence.h b/include/clang/Basic/OperatorPrecedence.h index 4389e3bbd257..61ac7ad62f6b 100644 --- a/include/clang/Basic/OperatorPrecedence.h +++ b/include/clang/Basic/OperatorPrecedence.h @@ -1,9 +1,8 @@ //===--- OperatorPrecedence.h - Operator precedence levels ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h index 9727af86f649..ae8de67e8776 100644 --- a/include/clang/Basic/PartialDiagnostic.h +++ b/include/clang/Basic/PartialDiagnostic.h @@ -1,9 +1,8 @@ //===- PartialDiagnostic.h - Diagnostic "closures" --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -17,6 +16,7 @@ #define LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/SmallVector.h" diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h index e41c24737798..557462a5b90d 100644 --- a/include/clang/Basic/PlistSupport.h +++ b/include/clang/Basic/PlistSupport.h @@ -1,9 +1,8 @@ //===- PlistSupport.h - Plist Output Utilities ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -128,7 +127,11 @@ inline void EmitRange(raw_ostream &o, const SourceManager &SM, assert(R.isCharRange() && "cannot handle a token range"); Indent(o, indent) << "<array>\n"; EmitLocation(o, SM, R.getBegin(), FM, indent + 1); - EmitLocation(o, SM, R.getEnd(), FM, indent + 1); + + // The ".getLocWithOffset(-1)" emulates the behavior of an off-by-one bug + // in Lexer that is already fixed. It is here for backwards compatibility + // even though it is incorrect. + EmitLocation(o, SM, R.getEnd().getLocWithOffset(-1), FM, indent + 1); Indent(o, indent) << "</array>\n"; } diff --git a/include/clang/Basic/PragmaKinds.h b/include/clang/Basic/PragmaKinds.h index b373a9e4e29e..103b97db718b 100644 --- a/include/clang/Basic/PragmaKinds.h +++ b/include/clang/Basic/PragmaKinds.h @@ -1,9 +1,8 @@ //===--- PragmaKinds.h - #pragma comment() kinds ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h index e652f52055d6..545a63b7e734 100644 --- a/include/clang/Basic/PrettyStackTrace.h +++ b/include/clang/Basic/PrettyStackTrace.h @@ -1,9 +1,8 @@ //===- clang/Basic/PrettyStackTrace.h - Pretty Crash Handling --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/SanitizerBlacklist.h b/include/clang/Basic/SanitizerBlacklist.h index 1ae5c36eea99..29af28b84365 100644 --- a/include/clang/Basic/SanitizerBlacklist.h +++ b/include/clang/Basic/SanitizerBlacklist.h @@ -1,9 +1,8 @@ //===--- SanitizerBlacklist.h - Blacklist for sanitizers --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/SanitizerSpecialCaseList.h b/include/clang/Basic/SanitizerSpecialCaseList.h index e3252022a44f..fb0db32c442f 100644 --- a/include/clang/Basic/SanitizerSpecialCaseList.h +++ b/include/clang/Basic/SanitizerSpecialCaseList.h @@ -1,9 +1,8 @@ //===--- SanitizerSpecialCaseList.h - SCL for sanitizers --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def index 0287468d71f5..0037cc2146f2 100644 --- a/include/clang/Basic/Sanitizers.def +++ b/include/clang/Basic/Sanitizers.def @@ -1,9 +1,8 @@ //===--- Sanitizers.def - Runtime sanitizer options -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -41,6 +40,12 @@ // AddressSanitizer SANITIZER("address", Address) +// Requires AddressSanitizer +SANITIZER("pointer-compare", PointerCompare) + +// Requires AddressSanitizer +SANITIZER("pointer-subtract", PointerSubtract) + // Kernel AddressSanitizer (KASan) SANITIZER("kernel-address", KernelAddress) @@ -50,6 +55,9 @@ SANITIZER("hwaddress", HWAddress) // Kernel Hardware-assisted AddressSanitizer (KHWASan) SANITIZER("kernel-hwaddress", KernelHWAddress) +// A variant of AddressSanitizer using AArch64 MTE extension. +SANITIZER("memtag", MemTag) + // MemorySanitizer SANITIZER("memory", Memory) @@ -125,7 +133,7 @@ SANITIZER("shadow-call-stack", ShadowCallStack) // ABI or address space layout implications, and only catch undefined behavior. SANITIZER_GROUP("undefined", Undefined, Alignment | Bool | Builtin | ArrayBounds | Enum | - FloatCastOverflow | FloatDivideByZero | + FloatCastOverflow | IntegerDivideByZero | NonnullAttribute | Null | ObjectSize | PointerOverflow | Return | ReturnsNonnullAttribute | Shift | SignedIntegerOverflow | Unreachable | VLABound | Function | @@ -166,19 +174,12 @@ SANITIZER_GROUP("integer", Integer, SANITIZER("local-bounds", LocalBounds) SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds) -// EfficiencySanitizer -SANITIZER("efficiency-cache-frag", EfficiencyCacheFrag) -SANITIZER("efficiency-working-set", EfficiencyWorkingSet) -// Meta-group only used internally. -SANITIZER_GROUP("efficiency-all", Efficiency, - EfficiencyCacheFrag | EfficiencyWorkingSet) - // Scudo hardened allocator SANITIZER("scudo", Scudo) // Magic group, containing all sanitizers. For example, "-fno-sanitize=all" // can be used to disable all the sanitizers. -SANITIZER_GROUP("all", All, ~0ULL) +SANITIZER_GROUP("all", All, ~SanitizerMask()) #undef SANITIZER #undef SANITIZER_GROUP diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h index fe9e76a1e325..5961abf2aa19 100644 --- a/include/clang/Basic/Sanitizers.h +++ b/include/clang/Basic/Sanitizers.h @@ -1,9 +1,8 @@ //===- Sanitizers.h - C Language Family Language Options --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -21,45 +20,146 @@ #include <cassert> #include <cstdint> +namespace llvm { +class hash_code; +} + namespace clang { -using SanitizerMask = uint64_t; +class SanitizerMask { + // NOTE: this class assumes kNumElem == 2 in most of the constexpr functions, + // in order to work within the C++11 constexpr function constraints. If you + // change kNumElem, you'll need to update those member functions as well. -namespace SanitizerKind { + /// Number of array elements. + static constexpr unsigned kNumElem = 2; + /// Mask value initialized to 0. + uint64_t maskLoToHigh[kNumElem]{}; + /// Number of bits in a mask. + static constexpr unsigned kNumBits = sizeof(decltype(maskLoToHigh)) * 8; + /// Number of bits in a mask element. + static constexpr unsigned kNumBitElem = sizeof(decltype(maskLoToHigh[0])) * 8; -// Assign ordinals to possible values of -fsanitize= flag, which we will use as -// bit positions. -enum SanitizerOrdinal : uint64_t { -#define SANITIZER(NAME, ID) SO_##ID, -#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group, -#include "clang/Basic/Sanitizers.def" - SO_Count + constexpr SanitizerMask(uint64_t mask1, uint64_t mask2) + : maskLoToHigh{mask1, mask2} {} + +public: + SanitizerMask() = default; + + static constexpr bool checkBitPos(const unsigned Pos) { + return Pos < kNumBits; + } + + /// Create a mask with a bit enabled at position Pos. + static constexpr SanitizerMask bitPosToMask(const unsigned Pos) { + return SanitizerMask((Pos < kNumBitElem) ? 1ULL << Pos % kNumBitElem : 0, + (Pos >= kNumBitElem && Pos < kNumBitElem * 2) + ? 1ULL << Pos % kNumBitElem + : 0); + } + + unsigned countPopulation() const { + unsigned total = 0; + for (const auto &Val : maskLoToHigh) + total += llvm::countPopulation(Val); + return total; + } + + void flipAllBits() { + for (auto &Val : maskLoToHigh) + Val = ~Val; + } + + bool isPowerOf2() const { + return countPopulation() == 1; + } + + llvm::hash_code hash_value() const; + + constexpr explicit operator bool() const { + return maskLoToHigh[0] || maskLoToHigh[1]; + } + + constexpr bool operator==(const SanitizerMask &V) const { + return maskLoToHigh[0] == V.maskLoToHigh[0] && + maskLoToHigh[1] == V.maskLoToHigh[1]; + } + + SanitizerMask &operator&=(const SanitizerMask &RHS) { + for (unsigned k = 0; k < kNumElem; k++) + maskLoToHigh[k] &= RHS.maskLoToHigh[k]; + return *this; + } + + SanitizerMask &operator|=(const SanitizerMask &RHS) { + for (unsigned k = 0; k < kNumElem; k++) + maskLoToHigh[k] |= RHS.maskLoToHigh[k]; + return *this; + } + + constexpr bool operator!() const { return !bool(*this); } + + constexpr bool operator!=(const SanitizerMask &RHS) const { + return !((*this) == RHS); + } + + friend constexpr inline SanitizerMask operator~(SanitizerMask v) { + return SanitizerMask(~v.maskLoToHigh[0], ~v.maskLoToHigh[1]); + } + + friend constexpr inline SanitizerMask operator&(SanitizerMask a, + const SanitizerMask &b) { + return SanitizerMask(a.maskLoToHigh[0] & b.maskLoToHigh[0], + a.maskLoToHigh[1] & b.maskLoToHigh[1]); + } + + friend constexpr inline SanitizerMask operator|(SanitizerMask a, + const SanitizerMask &b) { + return SanitizerMask(a.maskLoToHigh[0] | b.maskLoToHigh[0], + a.maskLoToHigh[1] | b.maskLoToHigh[1]); + } }; +// Declaring in clang namespace so that it can be found by ADL. +llvm::hash_code hash_value(const clang::SanitizerMask &Arg); + // Define the set of sanitizer kinds, as well as the set of sanitizers each // sanitizer group expands into. -#define SANITIZER(NAME, ID) \ - const SanitizerMask ID = 1ULL << SO_##ID; -#define SANITIZER_GROUP(NAME, ID, ALIAS) \ - const SanitizerMask ID = ALIAS; \ - const SanitizerMask ID##Group = 1ULL << SO_##ID##Group; +struct SanitizerKind { + // Assign ordinals to possible values of -fsanitize= flag, which we will use + // as bit positions. + enum SanitizerOrdinal : uint64_t { +#define SANITIZER(NAME, ID) SO_##ID, +#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group, #include "clang/Basic/Sanitizers.def" - -} // namespace SanitizerKind + SO_Count + }; + +#define SANITIZER(NAME, ID) \ + static constexpr SanitizerMask ID = SanitizerMask::bitPosToMask(SO_##ID); \ + static_assert(SanitizerMask::checkBitPos(SO_##ID), "Bit position too big."); +#define SANITIZER_GROUP(NAME, ID, ALIAS) \ + static constexpr SanitizerMask ID = SanitizerMask(ALIAS); \ + static constexpr SanitizerMask ID##Group = \ + SanitizerMask::bitPosToMask(SO_##ID##Group); \ + static_assert(SanitizerMask::checkBitPos(SO_##ID##Group), \ + "Bit position too big."); +#include "clang/Basic/Sanitizers.def" +}; // SanitizerKind struct SanitizerSet { /// Check if a certain (single) sanitizer is enabled. bool has(SanitizerMask K) const { - assert(llvm::isPowerOf2_64(K)); - return Mask & K; + assert(K.isPowerOf2() && "Has to be a single sanitizer."); + return static_cast<bool>(Mask & K); } /// Check if one or more sanitizers are enabled. - bool hasOneOf(SanitizerMask K) const { return Mask & K; } + bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); } /// Enable or disable a certain (single) sanitizer. void set(SanitizerMask K, bool Value) { - assert(llvm::isPowerOf2_64(K)); + assert(K.isPowerOf2() && "Has to be a single sanitizer."); Mask = Value ? (Mask | K) : (Mask & ~K); } @@ -67,10 +167,10 @@ struct SanitizerSet { void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; } /// Returns true if no sanitizers are enabled. - bool empty() const { return Mask == 0; } + bool empty() const { return !Mask; } /// Bitmask of enabled sanitizers. - SanitizerMask Mask = 0; + SanitizerMask Mask; }; /// Parse a single value from a -fsanitize= or -fno-sanitize= value list. @@ -85,7 +185,7 @@ SanitizerMask expandSanitizerGroups(SanitizerMask Kinds); inline SanitizerMask getPPTransparentSanitizers() { return SanitizerKind::CFI | SanitizerKind::Integer | SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | - SanitizerKind::Undefined; + SanitizerKind::Undefined | SanitizerKind::FloatDivideByZero; } } // namespace clang diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h index 014bdc3f3f0b..d6e2f6e6de94 100644 --- a/include/clang/Basic/SourceLocation.h +++ b/include/clang/Basic/SourceLocation.h @@ -1,9 +1,8 @@ //===- SourceLocation.h - Compact identifier for Source Files ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -26,7 +25,6 @@ namespace llvm { template <typename T> struct DenseMapInfo; -template <typename T> struct isPodLike; } // namespace llvm @@ -284,13 +282,15 @@ public: /// You can get a PresumedLoc from a SourceLocation with SourceManager. class PresumedLoc { const char *Filename = nullptr; + FileID ID; unsigned Line, Col; SourceLocation IncludeLoc; public: PresumedLoc() = default; - PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL) - : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {} + PresumedLoc(const char *FN, FileID FID, unsigned Ln, unsigned Co, + SourceLocation IL) + : Filename(FN), ID(FID), Line(Ln), Col(Co), IncludeLoc(IL) {} /// Return true if this object is invalid or uninitialized. /// @@ -307,6 +307,11 @@ public: return Filename; } + FileID getFileID() const { + assert(isValid()); + return ID; + } + /// Return the presumed line number of this location. /// /// This can be affected by \#line etc. @@ -458,11 +463,6 @@ namespace llvm { } }; - template <> - struct isPodLike<clang::SourceLocation> { static const bool value = true; }; - template <> - struct isPodLike<clang::FileID> { static const bool value = true; }; - // Teach SmallPtrSet how to handle SourceLocation. template<> struct PointerLikeTypeTraits<clang::SourceLocation> { diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index dcc4a37e239c..e32f749ae6ab 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -1,9 +1,8 @@ //===- SourceManager.h - Track and cache source files -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -106,7 +105,7 @@ namespace SrcMgr { /// /// This is owned by the ContentCache object. The bits indicate /// whether the buffer is invalid. - mutable llvm::PointerIntPair<llvm::MemoryBuffer *, 2> Buffer; + mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer; public: /// Reference to the file entry representing this ContentCache. @@ -185,10 +184,10 @@ namespace SrcMgr { /// will be emitted at. /// /// \param Invalid If non-NULL, will be set \c true if an error occurred. - llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag, - const SourceManager &SM, - SourceLocation Loc = SourceLocation(), - bool *Invalid = nullptr) const; + const llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag, + const SourceManager &SM, + SourceLocation Loc = SourceLocation(), + bool *Invalid = nullptr) const; /// Returns the size of the content encapsulated by this /// ContentCache. @@ -210,11 +209,13 @@ namespace SrcMgr { /// Get the underlying buffer, returning NULL if the buffer is not /// yet available. - llvm::MemoryBuffer *getRawBuffer() const { return Buffer.getPointer(); } + const llvm::MemoryBuffer *getRawBuffer() const { + return Buffer.getPointer(); + } /// Replace the existing buffer (which will be deleted) /// with the given buffer. - void replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree = false); + void replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree = false); /// Determine whether the buffer itself is invalid. bool isBufferInvalid() const { @@ -678,7 +679,7 @@ class SourceManager : public RefCountedBase<SourceManager> { /// Holds information for \#line directives. /// /// This is referenced by indices from SLocEntryTable. - LineTableInfo *LineTable = nullptr; + std::unique_ptr<LineTableInfo> LineTable; /// These ivars serve as a cache used in the getLineNumber /// method which is used to speedup getLineNumber calls to nearby locations. @@ -840,9 +841,9 @@ public: /// Create a new FileID that represents the specified memory buffer. /// - /// This does no caching of the buffer and takes ownership of the - /// MemoryBuffer, so only pass a MemoryBuffer to this once. - FileID createFileID(UnownedTag, llvm::MemoryBuffer *Buffer, + /// This does not take ownership of the MemoryBuffer. The memory buffer must + /// outlive the SourceManager. + FileID createFileID(UnownedTag, const llvm::MemoryBuffer *Buffer, SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User, int LoadedID = 0, unsigned LoadedOffset = 0, SourceLocation IncludeLoc = SourceLocation()) { @@ -888,8 +889,8 @@ public: /// /// \param Invalid If non-NULL, will be set \c true if an error /// occurs while retrieving the memory buffer. - llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File, - bool *Invalid = nullptr); + const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File, + bool *Invalid = nullptr); /// Override the contents of the given source file by providing an /// already-allocated buffer. @@ -952,8 +953,8 @@ public: /// /// If there is an error opening this buffer the first time, this /// manufactures a temporary buffer and returns a non-empty error string. - llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc, - bool *Invalid = nullptr) const { + const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc, + bool *Invalid = nullptr) const { bool MyInvalid = false; const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); if (MyInvalid || !Entry.isFile()) { @@ -967,7 +968,8 @@ public: Invalid); } - llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = nullptr) const { + const llvm::MemoryBuffer *getBuffer(FileID FID, + bool *Invalid = nullptr) const { bool MyInvalid = false; const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); if (MyInvalid || !Entry.isFile()) { @@ -1441,6 +1443,12 @@ public: return Filename.equals("<command line>"); } + /// Returns whether \p Loc is located in a <scratch space> file. + bool isWrittenInScratchSpace(SourceLocation Loc) const { + StringRef Filename(getPresumedLoc(Loc).getFilename()); + return Filename.equals("<scratch space>"); + } + /// Returns if a SourceLocation is in a system header. bool isInSystemHeader(SourceLocation Loc) const { return isSystem(getFileCharacteristic(Loc)); @@ -1453,7 +1461,20 @@ public: /// Returns whether \p Loc is expanded from a macro in a system header. bool isInSystemMacro(SourceLocation loc) const { - return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc)); + if (!loc.isMacroID()) + return false; + + // This happens when the macro is the result of a paste, in that case + // its spelling is the scratch memory, so we take the parent context. + // There can be several level of token pasting. + if (isWrittenInScratchSpace(getSpellingLoc(loc))) { + do { + loc = getImmediateMacroCallerLoc(loc); + } while (isWrittenInScratchSpace(getSpellingLoc(loc))); + return isInSystemMacro(loc); + } + + return isInSystemHeader(getSpellingLoc(loc)); } /// The size of the SLocEntry that \p FID represents. @@ -1775,7 +1796,7 @@ private: /// Create a new ContentCache for the specified memory buffer. const SrcMgr::ContentCache * - createMemBufferContentCache(llvm::MemoryBuffer *Buf, bool DoNotFree); + createMemBufferContentCache(const llvm::MemoryBuffer *Buf, bool DoNotFree); FileID getFileIDSlow(unsigned SLocOffset) const; FileID getFileIDLocal(unsigned SLocOffset) const; diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h index ddc58ffb6969..e67b93aea8a5 100644 --- a/include/clang/Basic/SourceManagerInternals.h +++ b/include/clang/Basic/SourceManagerInternals.h @@ -1,9 +1,8 @@ //===- SourceManagerInternals.h - SourceManager Internals -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h index 0af01e45437d..d1236e798e5d 100644 --- a/include/clang/Basic/Specifiers.h +++ b/include/clang/Basic/Specifiers.h @@ -1,9 +1,8 @@ //===--- Specifiers.h - Declaration and Type Specifiers ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -21,6 +20,21 @@ #include "llvm/Support/ErrorHandling.h" namespace clang { + + /// Define the meaning of possible values of the kind in ExplicitSpecifier. + enum class ExplicitSpecKind : unsigned { + ResolvedFalse, + ResolvedTrue, + Unresolved, + }; + + /// Define the kind of constexpr specifier. + enum ConstexprSpecKind { + CSK_unspecified, + CSK_constexpr, + CSK_consteval + }; + /// Specifies the width of a type, e.g., short, long, or long long. enum TypeSpecifierWidth { TSW_unspecified, @@ -141,6 +155,20 @@ namespace clang { OK_ObjCSubscript }; + /// The reason why a DeclRefExpr does not constitute an odr-use. + enum NonOdrUseReason { + /// This is an odr-use. + NOUR_None = 0, + /// This name appears in an unevaluated operand. + NOUR_Unevaluated, + /// This name appears as a potential result of an lvalue-to-rvalue + /// conversion that is a constant expression. + NOUR_Constant, + /// This name appears as a potential result of a discarded value + /// expression. + NOUR_Discarded, + }; + /// Describes the kind of template specialization that a /// particular template specialization declaration represents. enum TemplateSpecializationKind { diff --git a/include/clang/Basic/Stack.h b/include/clang/Basic/Stack.h index 15a37c6d5949..e0b04099de58 100644 --- a/include/clang/Basic/Stack.h +++ b/include/clang/Basic/Stack.h @@ -1,9 +1,8 @@ //===--- Stack.h - Utilities for dealing with stack space -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 9054fb11a6ff..be364de1a76c 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -11,8 +11,6 @@ class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> { // Statements def NullStmt : Stmt; def CompoundStmt : Stmt; -def LabelStmt : Stmt; -def AttributedStmt : Stmt; def IfStmt : Stmt; def SwitchStmt : Stmt; def WhileStmt : Stmt; @@ -29,6 +27,12 @@ def CaseStmt : DStmt<SwitchCase>; def DefaultStmt : DStmt<SwitchCase>; def CapturedStmt : Stmt; +// Statements that might produce a value (for example, as the last non-null +// statement in a GNU statement-expression). +def ValueStmt : Stmt<1>; +def LabelStmt : DStmt<ValueStmt>; +def AttributedStmt : DStmt<ValueStmt>; + // Asm statements def AsmStmt : Stmt<1>; def GCCAsmStmt : DStmt<AsmStmt>; @@ -53,7 +57,7 @@ def CoroutineBodyStmt : Stmt; def CoreturnStmt : Stmt; // Expressions -def Expr : Stmt<1>; +def Expr : DStmt<ValueStmt, 1>; def PredefinedExpr : DStmt<Expr>; def DeclRefExpr : DStmt<Expr>; def IntegerLiteral : DStmt<Expr>; @@ -92,6 +96,7 @@ def ParenListExpr : DStmt<Expr>; def VAArgExpr : DStmt<Expr>; def GenericSelectionExpr : DStmt<Expr>; def PseudoObjectExpr : DStmt<Expr>; +def SourceLocExpr : DStmt<Expr>; // Wrapper expressions def FullExpr : DStmt<Expr, 1>; @@ -187,6 +192,7 @@ def ConvertVectorExpr : DStmt<Expr>; def BlockExpr : DStmt<Expr>; def OpaqueValueExpr : DStmt<Expr>; def TypoExpr : DStmt<Expr>; +def BuiltinBitCastExpr : DStmt<ExplicitCastExpr>; // Microsoft Extensions. def MSPropertyRefExpr : DStmt<Expr>; diff --git a/include/clang/Basic/SyncScope.h b/include/clang/Basic/SyncScope.h index db4461eda013..15af02d83cde 100644 --- a/include/clang/Basic/SyncScope.h +++ b/include/clang/Basic/SyncScope.h @@ -1,9 +1,8 @@ //===--- SyncScope.h - Atomic synchronization scopes ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -96,7 +95,7 @@ class AtomicScopeOpenCLModel : public AtomicScopeModel { public: /// The enum values match the pre-defined macros /// __OPENCL_MEMORY_SCOPE_*, which are used to define memory_scope_* - /// enums in opencl-c.h. + /// enums in opencl-c-base.h. enum ID { WorkGroup = 1, Device = 2, diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h index ab4b1c43f7cf..50262fa310ce 100644 --- a/include/clang/Basic/TargetBuiltins.h +++ b/include/clang/Basic/TargetBuiltins.h @@ -1,9 +1,8 @@ //===--- TargetBuiltins.h - Target specific builtin IDs ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h index 455121a98f33..b1be40272513 100644 --- a/include/clang/Basic/TargetCXXABI.h +++ b/include/clang/Basic/TargetCXXABI.h @@ -1,9 +1,8 @@ //===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 786b1c251ca8..7a8384f5fbc0 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -1,9 +1,8 @@ //===--- TargetInfo.h - Expose information about the target -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -49,21 +48,10 @@ class SourceManager; namespace Builtin { struct Info; } -/// Exposes information about the current target. -/// -class TargetInfo : public RefCountedBase<TargetInfo> { - std::shared_ptr<TargetOptions> TargetOpts; - llvm::Triple Triple; -protected: - // Target values set by the ctor of the actual target implementation. Default - // values are specified by the TargetInfo constructor. - bool BigEndian; - bool TLSSupported; - bool VLASupported; - bool NoAsmVariants; // True if {|} are normal characters. - bool HasLegalHalfType; // True if the backend supports operations on the half - // LLVM IR type. - bool HasFloat128; +/// Fields controlling how types are laid out in memory; these may need to +/// be copied for targets like AMDGPU that base their ABIs on an auxiliary +/// CPU target. +struct TransferrableTargetInfo { unsigned char PointerWidth, PointerAlign; unsigned char BoolWidth, BoolAlign; unsigned char IntWidth, IntAlign; @@ -104,15 +92,92 @@ protected: unsigned char SuitableAlign; unsigned char DefaultAlignForAttributeAligned; unsigned char MinGlobalAlign; - unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; + + unsigned short NewAlign; unsigned short MaxVectorAlign; unsigned short MaxTLSAlign; + + const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat, + *LongDoubleFormat, *Float128Format; + + ///===---- Target Data Type Query Methods -------------------------------===// + enum IntType { + NoInt = 0, + SignedChar, + UnsignedChar, + SignedShort, + UnsignedShort, + SignedInt, + UnsignedInt, + SignedLong, + UnsignedLong, + SignedLongLong, + UnsignedLongLong + }; + + enum RealType { + NoFloat = 255, + Float = 0, + Double, + LongDouble, + Float128 + }; +protected: + IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType, + WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType, + ProcessIDType; + + /// Whether Objective-C's built-in boolean type should be signed char. + /// + /// Otherwise, when this flag is not set, the normal built-in boolean type is + /// used. + unsigned UseSignedCharForObjCBool : 1; + + /// Control whether the alignment of bit-field types is respected when laying + /// out structures. If true, then the alignment of the bit-field type will be + /// used to (a) impact the alignment of the containing structure, and (b) + /// ensure that the individual bit-field will not straddle an alignment + /// boundary. + unsigned UseBitFieldTypeAlignment : 1; + + /// Whether zero length bitfields (e.g., int : 0;) force alignment of + /// the next bitfield. + /// + /// If the alignment of the zero length bitfield is greater than the member + /// that follows it, `bar', `bar' will be aligned as the type of the + /// zero-length bitfield. + unsigned UseZeroLengthBitfieldAlignment : 1; + + /// Whether explicit bit field alignment attributes are honored. + unsigned UseExplicitBitFieldAlignment : 1; + + /// If non-zero, specifies a fixed alignment value for bitfields that follow + /// zero length bitfield, regardless of the zero length bitfield type. + unsigned ZeroLengthBitfieldBoundary; +}; + +/// Exposes information about the current target. +/// +class TargetInfo : public virtual TransferrableTargetInfo, + public RefCountedBase<TargetInfo> { + std::shared_ptr<TargetOptions> TargetOpts; + llvm::Triple Triple; +protected: + // Target values set by the ctor of the actual target implementation. Default + // values are specified by the TargetInfo constructor. + bool BigEndian; + bool TLSSupported; + bool VLASupported; + bool NoAsmVariants; // True if {|} are normal characters. + bool HasLegalHalfType; // True if the backend supports operations on the half + // LLVM IR type. + bool HasFloat128; + bool HasFloat16; + + unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; unsigned short SimdDefaultAlign; - unsigned short NewAlign; std::unique_ptr<llvm::DataLayout> DataLayout; const char *MCountName; - const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat, - *LongDoubleFormat, *Float128Format; unsigned char RegParmMax, SSERegParmMax; TargetCXXABI TheCXXABI; const LangASMap *AddrSpaceMap; @@ -153,29 +218,6 @@ public: return *TargetOpts; } - ///===---- Target Data Type Query Methods -------------------------------===// - enum IntType { - NoInt = 0, - SignedChar, - UnsignedChar, - SignedShort, - UnsignedShort, - SignedInt, - UnsignedInt, - SignedLong, - UnsignedLong, - SignedLongLong, - UnsignedLongLong - }; - - enum RealType { - NoFloat = 255, - Float = 0, - Double, - LongDouble, - Float128 - }; - /// The different kinds of __builtin_va_list types defined by /// the target implementation. enum BuiltinVaListKind { @@ -218,38 +260,6 @@ public: }; protected: - IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType, - WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType, - ProcessIDType; - - /// Whether Objective-C's built-in boolean type should be signed char. - /// - /// Otherwise, when this flag is not set, the normal built-in boolean type is - /// used. - unsigned UseSignedCharForObjCBool : 1; - - /// Control whether the alignment of bit-field types is respected when laying - /// out structures. If true, then the alignment of the bit-field type will be - /// used to (a) impact the alignment of the containing structure, and (b) - /// ensure that the individual bit-field will not straddle an alignment - /// boundary. - unsigned UseBitFieldTypeAlignment : 1; - - /// Whether zero length bitfields (e.g., int : 0;) force alignment of - /// the next bitfield. - /// - /// If the alignment of the zero length bitfield is greater than the member - /// that follows it, `bar', `bar' will be aligned as the type of the - /// zero-length bitfield. - unsigned UseZeroLengthBitfieldAlignment : 1; - - /// Whether explicit bit field alignment attributes are honored. - unsigned UseExplicitBitFieldAlignment : 1; - - /// If non-zero, specifies a fixed alignment value for bitfields that follow - /// zero length bitfield, regardless of the zero length bitfield type. - unsigned ZeroLengthBitfieldBoundary; - /// Specify if mangling based on address space map should be used or /// not for language specific address spaces bool UseAddrSpaceMapMangling; @@ -517,6 +527,9 @@ public: /// Determine whether the __float128 type is supported on this target. virtual bool hasFloat128Type() const { return HasFloat128; } + /// Determine whether the _Float16 type is supported on this target. + virtual bool hasFloat16Type() const { return HasFloat16; } + /// Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } @@ -529,7 +542,9 @@ public: /// getMinGlobalAlign - Return the minimum alignment of a global variable, /// unless its alignment is explicitly reduced via attributes. - unsigned getMinGlobalAlign() const { return MinGlobalAlign; } + virtual unsigned getMinGlobalAlign (uint64_t) const { + return MinGlobalAlign; + } /// Return the largest alignment for which a suitably-sized allocation with /// '::operator new(size_t)' is guaranteed to produce a correctly-aligned @@ -584,9 +599,11 @@ public: return *Float128Format; } - /// Return true if the 'long double' type should be mangled like - /// __float128. - virtual bool useFloat128ManglingForLongDouble() const { return false; } + /// Return the mangled code of long double. + virtual const char *getLongDoubleMangling() const { return "e"; } + + /// Return the mangled code of __float128. + virtual const char *getFloat128Mangling() const { return "g"; } /// Return the value for the C99 FLT_EVAL_METHOD macro. virtual unsigned getFloatEvalMethod() const { return 0; } @@ -622,6 +639,21 @@ public: /// types for the given target. unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; } + /// Return the alignment (in bits) of the thrown exception object. This is + /// only meaningful for targets that allocate C++ exceptions in a system + /// runtime, such as those using the Itanium C++ ABI. + virtual unsigned getExnObjectAlignment() const { + // Itanium says that an _Unwind_Exception has to be "double-word" + // aligned (and thus the end of it is also so-aligned), meaning 16 + // bytes. Of course, that was written for the actual Itanium, + // which is a 64-bit platform. Classically, the ABI doesn't really + // specify the alignment on other platforms, but in practice + // libUnwind declares the struct with __attribute__((aligned)), so + // we assume that alignment here. (It's generally 16 bytes, but + // some targets overwrite it.) + return getDefaultAlignForAttributeAligned(); + } + /// Return the size of intmax_t and uintmax_t for this target, in bits. unsigned getIntMaxTWidth() const { return getTypeWidth(IntMaxType); @@ -803,6 +835,7 @@ public: struct { int Min; int Max; + bool isConstrained; } ImmRange; llvm::SmallSet<int, 4> ImmSet; @@ -813,6 +846,7 @@ public: : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()), Name(Name.str()) { ImmRange.Min = ImmRange.Max = 0; + ImmRange.isConstrained = false; } const std::string &getConstraintStr() const { return ConstraintStr; } @@ -841,8 +875,11 @@ public: return (Flags & CI_ImmediateConstant) != 0; } bool isValidAsmImmediate(const llvm::APInt &Value) const { - return (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)) || - ImmSet.count(Value.getZExtValue()) != 0; + if (!ImmSet.empty()) + return Value.isSignedIntN(32) && + ImmSet.count(Value.getZExtValue()) != 0; + return !ImmRange.isConstrained || + (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)); } void setIsReadWrite() { Flags |= CI_ReadWrite; } @@ -854,6 +891,7 @@ public: Flags |= CI_ImmediateConstant; ImmRange.Min = Min; ImmRange.Max = Max; + ImmRange.isConstrained = true; } void setRequiresImmediate(llvm::ArrayRef<int> Exacts) { Flags |= CI_ImmediateConstant; @@ -866,8 +904,6 @@ public: } void setRequiresImmediate() { Flags |= CI_ImmediateConstant; - ImmRange.Min = INT_MIN; - ImmRange.Max = INT_MAX; } /// Indicate that this is an input operand that is tied to @@ -1332,7 +1368,11 @@ public: return true; } + virtual void setAuxTarget(const TargetInfo *Aux) {} + protected: + /// Copy type and layout related info. + void copyAuxTarget(const TargetInfo *Aux); virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return PointerWidth; } diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h index fcccc5331a97..bbe86aebb074 100644 --- a/include/clang/Basic/TargetOptions.h +++ b/include/clang/Basic/TargetOptions.h @@ -1,9 +1,8 @@ //===--- TargetOptions.h ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -76,6 +75,11 @@ public: std::string CodeModel; /// The version of the SDK which was used during the compilation. + /// The option is used for two different purposes: + /// * on darwin the version is propagated to LLVM where it's used + /// to support SDK Version metadata (See D55673). + /// * CUDA compilation uses it to control parts of CUDA compilation + /// in clang that depend on specific version of the CUDA SDK. llvm::VersionTuple SDKVersion; }; diff --git a/include/clang/Basic/TemplateKinds.h b/include/clang/Basic/TemplateKinds.h index a0bc362e7a44..62e484ce42ea 100644 --- a/include/clang/Basic/TemplateKinds.h +++ b/include/clang/Basic/TemplateKinds.h @@ -1,9 +1,8 @@ //===--- TemplateKinds.h - Enum values for C++ Template Kinds ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -22,7 +21,8 @@ enum TemplateNameKind { /// The name does not refer to a template. TNK_Non_template = 0, /// The name refers to a function template or a set of overloaded - /// functions that includes at least one function template. + /// functions that includes at least one function template, or (in C++20) + /// refers to a set of non-template functions but is followed by a '<'. TNK_Function_template, /// The name refers to a template whose specialization produces a /// type. The template itself could be a class template, template @@ -43,10 +43,14 @@ enum TemplateNameKind { /// whether the template name is assumed to refer to a type template or a /// function template depends on the context in which the template /// name occurs. - TNK_Dependent_template_name + TNK_Dependent_template_name, + /// Lookup for the name failed, but we're assuming it was a template name + /// anyway. In C++20, this is mandatory in order to parse ADL-only function + /// template specialization calls. + TNK_Undeclared_template, + /// The name refers to a concept. + TNK_Concept_template, }; } #endif - - diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index e4616c9a6ab4..55e94d387c9d 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -1,9 +1,8 @@ //===--- TokenKinds.def - C Family Token Kind Database ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -33,6 +32,9 @@ #ifndef CONCEPTS_KEYWORD #define CONCEPTS_KEYWORD(X) CXX2A_KEYWORD(X,KEYCONCEPTS) #endif +#ifndef COROUTINES_KEYWORD +#define COROUTINES_KEYWORD(X) CXX2A_KEYWORD(X,KEYCOROUTINES) +#endif #ifndef MODULES_KEYWORD #define MODULES_KEYWORD(X) KEYWORD(X,KEYMODULES) #endif @@ -152,7 +154,9 @@ TOK(utf32_char_constant) // U'a' // C99 6.4.5: String Literals. TOK(string_literal) // "foo" TOK(wide_string_literal) // L"foo" -TOK(angle_string_literal)// <foo> + +// C11 6.4.7: Header Names +TOK(header_name) // <foo>, or "foo" lexed as a header-name // C++11 String Literals. TOK(utf8_string_literal) // u8"foo" @@ -244,18 +248,17 @@ PUNCTUATOR(caretcaret, "^^") // are enabled. // KEYGNU - This is a keyword if GNU extensions are enabled // KEYMS - This is a keyword if Microsoft extensions are enabled +// KEYMSCOMPAT - This is a keyword if Microsoft compatibility mode is enabled // KEYNOMS18 - This is a keyword that must never be enabled under // MSVC <= v18. // KEYOPENCLC - This is a keyword in OpenCL C -// KEYOPENCLCXX - This is a keyword in OpenCL C++ -// KEYNOOPENCL - This is a keyword that is not supported in OpenCL C -// nor in OpenCL C++. +// KEYOPENCLCXX - This is a keyword in C++ for OpenCL +// KEYNOOPENCL - This is a keyword that is not supported in OpenCL // KEYALTIVEC - This is a keyword in AltiVec // KEYZVECTOR - This is a keyword for the System z vector extensions, // which are heavily based on AltiVec // KEYBORLAND - This is a keyword if Borland extensions are enabled -// KEYCOROUTINES - This is a keyword if support for the C++ coroutines -// TS is enabled +// KEYCOROUTINES - This is a keyword if support for C++ coroutines is enabled // BOOLSUPPORT - This is a keyword if 'bool' is a built-in type // HALFSUPPORT - This is a keyword if 'half' is a built-in type // WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type @@ -364,24 +367,25 @@ CXX11_KEYWORD(constexpr , 0) CXX11_KEYWORD(decltype , 0) CXX11_KEYWORD(noexcept , 0) CXX11_KEYWORD(nullptr , 0) -CXX11_KEYWORD(static_assert , 0) +CXX11_KEYWORD(static_assert , KEYMSCOMPAT) CXX11_KEYWORD(thread_local , 0) // C++2a / concepts TS keywords CONCEPTS_KEYWORD(concept) CONCEPTS_KEYWORD(requires) -// C++ coroutines TS keywords -KEYWORD(co_await , KEYCOROUTINES) -KEYWORD(co_return , KEYCOROUTINES) -KEYWORD(co_yield , KEYCOROUTINES) +// C++2a / coroutines TS keywords +COROUTINES_KEYWORD(co_await) +COROUTINES_KEYWORD(co_return) +COROUTINES_KEYWORD(co_yield) // C++ modules TS keywords MODULES_KEYWORD(module) MODULES_KEYWORD(import) -// C++ char8_t proposal -KEYWORD(char8_t , CHAR8SUPPORT) +// C++20 keywords. +CXX2A_KEYWORD(char8_t , CHAR8SUPPORT) +CXX2A_KEYWORD(consteval , 0) // C11 Extension KEYWORD(_Float16 , KEYALL) @@ -400,6 +404,11 @@ KEYWORD(__alignof , KEYALL) KEYWORD(__attribute , KEYALL) KEYWORD(__builtin_choose_expr , KEYALL) KEYWORD(__builtin_offsetof , KEYALL) +KEYWORD(__builtin_FILE , KEYALL) +KEYWORD(__builtin_FUNCTION , KEYALL) +KEYWORD(__builtin_LINE , KEYALL) +KEYWORD(__builtin_COLUMN , KEYALL) + // __builtin_types_compatible_p is a GNU C extension that we handle like a C++ // type trait. TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX) @@ -535,11 +544,11 @@ KEYWORD(__local , KEYOPENCLC | KEYOPENCLCXX) KEYWORD(__constant , KEYOPENCLC | KEYOPENCLCXX) KEYWORD(__private , KEYOPENCLC | KEYOPENCLCXX) KEYWORD(__generic , KEYOPENCLC | KEYOPENCLCXX) -ALIAS("global", __global , KEYOPENCLC) -ALIAS("local", __local , KEYOPENCLC) -ALIAS("constant", __constant , KEYOPENCLC) +ALIAS("global", __global , KEYOPENCLC | KEYOPENCLCXX) +ALIAS("local", __local , KEYOPENCLC | KEYOPENCLCXX) +ALIAS("constant", __constant , KEYOPENCLC | KEYOPENCLCXX) ALIAS("private", __private , KEYOPENCLC) -ALIAS("generic", __generic , KEYOPENCLC) +ALIAS("generic", __generic , KEYOPENCLC | KEYOPENCLCXX) // OpenCL function qualifiers KEYWORD(__kernel , KEYOPENCLC | KEYOPENCLCXX) ALIAS("kernel", __kernel , KEYOPENCLC | KEYOPENCLCXX) @@ -551,15 +560,15 @@ ALIAS("read_only", __read_only , KEYOPENCLC | KEYOPENCLCXX) ALIAS("write_only", __write_only , KEYOPENCLC | KEYOPENCLCXX) ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX) // OpenCL builtins -KEYWORD(__builtin_astype , KEYOPENCLC) +KEYWORD(__builtin_astype , KEYOPENCLC | KEYOPENCLCXX) KEYWORD(vec_step , KEYOPENCLC | KEYALTIVEC | KEYZVECTOR) -#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC) +#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX) #include "clang/Basic/OpenCLImageTypes.def" // OpenMP Type Traits KEYWORD(__builtin_omp_required_simd_align, KEYALL) -KEYWORD(pipe , KEYOPENCLC) +KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX) // Borland Extensions. KEYWORD(__pascal , KEYALL) @@ -660,7 +669,7 @@ ALIAS("_pascal" , __pascal , KEYBORLAND) KEYWORD(__builtin_convertvector , KEYALL) ALIAS("__char16_t" , char16_t , KEYCXX) ALIAS("__char32_t" , char32_t , KEYCXX) - +KEYWORD(__builtin_bit_cast , KEYALL) KEYWORD(__builtin_available , KEYALL) // Clang-specific keywords enabled only in testing. @@ -823,6 +832,10 @@ ANNOTATION(module_include) ANNOTATION(module_begin) ANNOTATION(module_end) +// Annotation for a header_name token that has been looked up and transformed +// into the name of a header unit. +ANNOTATION(header_unit) + #undef ANNOTATION #undef TESTING_KEYWORD #undef OBJC_AT_KEYWORD diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h index e046f0027044..1d5be5f9152e 100644 --- a/include/clang/Basic/TokenKinds.h +++ b/include/clang/Basic/TokenKinds.h @@ -1,9 +1,8 @@ //===--- TokenKinds.h - Enum values for C Token Kinds -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -87,7 +86,7 @@ inline bool isLiteral(TokenKind K) { return K == tok::numeric_constant || K == tok::char_constant || K == tok::wide_char_constant || K == tok::utf8_char_constant || K == tok::utf16_char_constant || K == tok::utf32_char_constant || - isStringLiteral(K) || K == tok::angle_string_literal; + isStringLiteral(K) || K == tok::header_name; } /// Return true if this is any of tok::annot_* kinds. diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h index 8b8b2cbbd4a7..7c1b571f640c 100644 --- a/include/clang/Basic/TypeTraits.h +++ b/include/clang/Basic/TypeTraits.h @@ -1,9 +1,8 @@ //===--- TypeTraits.h - C++ Type Traits Support Enumerations ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h index 6d625c6ddb80..2881d8db954e 100644 --- a/include/clang/Basic/Version.h +++ b/include/clang/Basic/Version.h @@ -1,9 +1,8 @@ //===- Version.h - Clang Version Number -------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/Visibility.h b/include/clang/Basic/Visibility.h index c5ab62436fe0..57d9754ae4a9 100644 --- a/include/clang/Basic/Visibility.h +++ b/include/clang/Basic/Visibility.h @@ -1,9 +1,8 @@ //===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Basic/X86Target.def b/include/clang/Basic/X86Target.def index 8c203c4db21e..94ccb9fd8b2f 100644 --- a/include/clang/Basic/X86Target.def +++ b/include/clang/Basic/X86Target.def @@ -1,9 +1,8 @@ //===--- X86Target.def - X86 Feature/Processor Database ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -67,7 +66,7 @@ PROC(PentiumMMX, "pentium-mmx", PROC_32_BIT) /// i686-generation processors, P6 / Pentium M microarchitecture based. //@{ PROC(PentiumPro, "pentiumpro", PROC_32_BIT) -PROC_ALIAS(PentiumPro, "i686") +PROC(i686, "i686", PROC_32_BIT) PROC(Pentium2, "pentium2", PROC_32_BIT) PROC(Pentium3, "pentium3", PROC_32_BIT) PROC_ALIAS(Pentium3, "pentium3m") @@ -158,6 +157,10 @@ PROC_ALIAS(SkylakeServer, "skx") /// Cascadelake Server microarchitecture based processors. PROC_WITH_FEAT(Cascadelake, "cascadelake", PROC_64_BIT, FEATURE_AVX512VNNI) +/// \name Cooperlake Server +/// Cooperlake Server microarchitecture based processors. +PROC_WITH_FEAT(Cooperlake, "cooperlake", PROC_64_BIT, FEATURE_AVX512BF16) + /// \name Cannonlake Client /// Cannonlake client microarchitecture based processors. PROC_WITH_FEAT(Cannonlake, "cannonlake", PROC_64_BIT, FEATURE_AVX512VBMI) @@ -237,6 +240,7 @@ PROC_WITH_FEAT(BDVER4, "bdver4", PROC_64_BIT, FEATURE_AVX2) /// Zen architecture processors. //@{ PROC_WITH_FEAT(ZNVER1, "znver1", PROC_64_BIT, FEATURE_AVX2) +PROC_WITH_FEAT(ZNVER2, "znver2", PROC_64_BIT, FEATURE_AVX2) //@} /// This specification is deprecated and will be removed in the future. @@ -292,6 +296,7 @@ FEATURE(FEATURE_GFNI) FEATURE(FEATURE_VPCLMULQDQ) FEATURE(FEATURE_AVX512VNNI) FEATURE(FEATURE_AVX512BITALG) +FEATURE(FEATURE_AVX512BF16) // FIXME: When commented out features are supported in LLVM, enable them here. @@ -301,7 +306,7 @@ CPU_SPECIFIC("pentium_pro", 'C', "+cmov") CPU_SPECIFIC("pentium_mmx", 'D', "+mmx") CPU_SPECIFIC("pentium_ii", 'E', "+cmov,+mmx") CPU_SPECIFIC("pentium_iii", 'H', "+cmov,+mmx,+sse") -CPU_SPECIFIC("pentium_iii_no_xmm_regs", 'H',"+cmov,+sse") +CPU_SPECIFIC_ALIAS("pentium_iii_no_xmm_regs", "pentium_iii") CPU_SPECIFIC("pentium_4", 'J', "+cmov,+mmx,+sse,+sse2") CPU_SPECIFIC("pentium_m", 'K', "+cmov,+mmx,+sse,+sse2") CPU_SPECIFIC("pentium_4_sse3", 'L', "+cmov,+mmx,+sse,+sse2,+sse3") diff --git a/include/clang/Basic/XRayInstr.h b/include/clang/Basic/XRayInstr.h index 6efefcb33ac8..48e88848f580 100644 --- a/include/clang/Basic/XRayInstr.h +++ b/include/clang/Basic/XRayInstr.h @@ -1,9 +1,8 @@ //===--- XRayInstr.h --------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/XRayLists.h b/include/clang/Basic/XRayLists.h index 244b1d533b7c..cf464f9e5478 100644 --- a/include/clang/Basic/XRayLists.h +++ b/include/clang/Basic/XRayLists.h @@ -1,9 +1,8 @@ //===--- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/arm_fp16.td b/include/clang/Basic/arm_fp16.td index bc15a22d84a6..ca33a8d2ec0b 100644 --- a/include/clang/Basic/arm_fp16.td +++ b/include/clang/Basic/arm_fp16.td @@ -1,9 +1,8 @@ //===--- arm_fp16.td - ARM FP16 compiler interface ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td index af049be7e295..428c22d1a011 100644 --- a/include/clang/Basic/arm_neon.td +++ b/include/clang/Basic/arm_neon.td @@ -1,9 +1,8 @@ //===--- arm_neon.td - ARM NEON compiler interface ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -704,11 +703,11 @@ def QNEG : SInst<"vqneg", "dd", "lQl">; //////////////////////////////////////////////////////////////////////////////// // Signed Saturating Accumulated of Unsigned Value -def SUQADD : SInst<"vuqadd", "ddd", "csilQcQsQiQl">; +def SUQADD : SInst<"vuqadd", "ddu", "csilQcQsQiQl">; //////////////////////////////////////////////////////////////////////////////// // Unsigned Saturating Accumulated of Signed Value -def USQADD : SInst<"vsqadd", "ddd", "UcUsUiUlQUcQUsQUiQUl">; +def USQADD : SInst<"vsqadd", "ddx", "UcUsUiUlQUcQUsQUiQUl">; //////////////////////////////////////////////////////////////////////////////// // Reciprocal/Sqrt @@ -1071,16 +1070,16 @@ def VUZP2 : SOpInst<"vuzp2", "ddd", //////////////////////////////////////////////////////////////////////////////// // Table lookup let InstName = "vtbl" in { -def VQTBL1_A64 : WInst<"vqtbl1", "djt", "UccPcQUcQcQPc">; -def VQTBL2_A64 : WInst<"vqtbl2", "dBt", "UccPcQUcQcQPc">; -def VQTBL3_A64 : WInst<"vqtbl3", "dCt", "UccPcQUcQcQPc">; -def VQTBL4_A64 : WInst<"vqtbl4", "dDt", "UccPcQUcQcQPc">; +def VQTBL1_A64 : WInst<"vqtbl1", "dju", "UccPcQUcQcQPc">; +def VQTBL2_A64 : WInst<"vqtbl2", "dBu", "UccPcQUcQcQPc">; +def VQTBL3_A64 : WInst<"vqtbl3", "dCu", "UccPcQUcQcQPc">; +def VQTBL4_A64 : WInst<"vqtbl4", "dDu", "UccPcQUcQcQPc">; } let InstName = "vtbx" in { -def VQTBX1_A64 : WInst<"vqtbx1", "ddjt", "UccPcQUcQcQPc">; -def VQTBX2_A64 : WInst<"vqtbx2", "ddBt", "UccPcQUcQcQPc">; -def VQTBX3_A64 : WInst<"vqtbx3", "ddCt", "UccPcQUcQcQPc">; -def VQTBX4_A64 : WInst<"vqtbx4", "ddDt", "UccPcQUcQcQPc">; +def VQTBX1_A64 : WInst<"vqtbx1", "ddju", "UccPcQUcQcQPc">; +def VQTBX2_A64 : WInst<"vqtbx2", "ddBu", "UccPcQUcQcQPc">; +def VQTBX3_A64 : WInst<"vqtbx3", "ddCu", "UccPcQUcQcQPc">; +def VQTBX4_A64 : WInst<"vqtbx4", "ddDu", "UccPcQUcQcQPc">; } //////////////////////////////////////////////////////////////////////////////// @@ -1334,11 +1333,11 @@ def SCALAR_SQNEG : SInst<"vqneg", "ss", "ScSsSiSl">; //////////////////////////////////////////////////////////////////////////////// // Scalar Signed Saturating Accumulated of Unsigned Value -def SCALAR_SUQADD : SInst<"vuqadd", "sss", "ScSsSiSl">; +def SCALAR_SUQADD : SInst<"vuqadd", "ssb", "ScSsSiSl">; //////////////////////////////////////////////////////////////////////////////// // Scalar Unsigned Saturating Accumulated of Signed Value -def SCALAR_USQADD : SInst<"vsqadd", "sss", "SUcSUsSUiSUl">; +def SCALAR_USQADD : SInst<"vsqadd", "ss$", "SUcSUsSUiSUl">; //////////////////////////////////////////////////////////////////////////////// // Signed Saturating Doubling Multiply-Add Long @@ -1652,18 +1651,18 @@ let ArchGuard = "defined(__ARM_FEATURE_DOTPROD) && defined(__aarch64__)" in { // v8.2-A FP16 fused multiply-add long instructions. let ArchGuard = "defined(__ARM_FEATURE_FP16FML) && defined(__aarch64__)" in { - def VFMLAL_LOW : SInst<"vfmlal_low", "ffHH", "UiQUi">; - def VFMLSL_LOW : SInst<"vfmlsl_low", "ffHH", "UiQUi">; - def VFMLAL_HIGH : SInst<"vfmlal_high", "ffHH", "UiQUi">; - def VFMLSL_HIGH : SInst<"vfmlsl_high", "ffHH", "UiQUi">; - - def VFMLAL_LANE_LOW : SOpInst<"vfmlal_lane_low", "ffH0i", "UiQUi", OP_FMLAL_LN>; - def VFMLSL_LANE_LOW : SOpInst<"vfmlsl_lane_low", "ffH0i", "UiQUi", OP_FMLSL_LN>; - def VFMLAL_LANE_HIGH : SOpInst<"vfmlal_lane_high", "ffH0i", "UiQUi", OP_FMLAL_LN_Hi>; - def VFMLSL_LANE_HIGH : SOpInst<"vfmlsl_lane_high", "ffH0i", "UiQUi", OP_FMLSL_LN_Hi>; - - def VFMLAL_LANEQ_LOW : SOpInst<"vfmlal_laneq_low", "ffH1i", "UiQUi", OP_FMLAL_LN>; - def VFMLSL_LANEQ_LOW : SOpInst<"vfmlsl_laneq_low", "ffH1i", "UiQUi", OP_FMLSL_LN>; - def VFMLAL_LANEQ_HIGH : SOpInst<"vfmlal_laneq_high", "ffH1i", "UiQUi", OP_FMLAL_LN_Hi>; - def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "ffH1i", "UiQUi", OP_FMLSL_LN_Hi>; + def VFMLAL_LOW : SInst<"vfmlal_low", "ffHH", "hQh">; + def VFMLSL_LOW : SInst<"vfmlsl_low", "ffHH", "hQh">; + def VFMLAL_HIGH : SInst<"vfmlal_high", "ffHH", "hQh">; + def VFMLSL_HIGH : SInst<"vfmlsl_high", "ffHH", "hQh">; + + def VFMLAL_LANE_LOW : SOpInst<"vfmlal_lane_low", "ffH0i", "hQh", OP_FMLAL_LN>; + def VFMLSL_LANE_LOW : SOpInst<"vfmlsl_lane_low", "ffH0i", "hQh", OP_FMLSL_LN>; + def VFMLAL_LANE_HIGH : SOpInst<"vfmlal_lane_high", "ffH0i", "hQh", OP_FMLAL_LN_Hi>; + def VFMLSL_LANE_HIGH : SOpInst<"vfmlsl_lane_high", "ffH0i", "hQh", OP_FMLSL_LN_Hi>; + + def VFMLAL_LANEQ_LOW : SOpInst<"vfmlal_laneq_low", "ffH1i", "hQh", OP_FMLAL_LN>; + def VFMLSL_LANEQ_LOW : SOpInst<"vfmlsl_laneq_low", "ffH1i", "hQh", OP_FMLSL_LN>; + def VFMLAL_LANEQ_HIGH : SOpInst<"vfmlal_laneq_high", "ffH1i", "hQh", OP_FMLAL_LN_Hi>; + def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "ffH1i", "hQh", OP_FMLSL_LN_Hi>; } diff --git a/include/clang/Basic/arm_neon_incl.td b/include/clang/Basic/arm_neon_incl.td index 09df22ea5ca2..4314ed1b8da7 100644 --- a/include/clang/Basic/arm_neon_incl.td +++ b/include/clang/Basic/arm_neon_incl.td @@ -1,9 +1,8 @@ //===--- arm_neon_incl.td - ARM NEON compiler interface ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h index 3d1221a43b14..01b1f5bbd6ee 100644 --- a/include/clang/CodeGen/BackendUtil.h +++ b/include/clang/CodeGen/BackendUtil.h @@ -1,9 +1,8 @@ //===--- BackendUtil.h - LLVM Backend Utilities -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h index 58d1f0d71c74..1f81072e23d0 100644 --- a/include/clang/CodeGen/CGFunctionInfo.h +++ b/include/clang/CodeGen/CGFunctionInfo.h @@ -1,9 +1,8 @@ //==-- CGFunctionInfo.h - Representation of function argument/return types -==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -96,7 +95,6 @@ private: bool InReg : 1; // isDirect() || isExtend() || isIndirect() bool CanBeFlattened: 1; // isDirect() bool SignExt : 1; // isExtend() - bool SuppressSRet : 1; // isIndirect() bool canHavePaddingType() const { return isDirect() || isExtend() || isIndirect() || isExpand(); @@ -112,14 +110,13 @@ private: } ABIArgInfo(Kind K) - : TheKind(K), PaddingInReg(false), InReg(false), SuppressSRet(false) { + : TheKind(K), PaddingInReg(false), InReg(false) { } public: ABIArgInfo() : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0), - TheKind(Direct), PaddingInReg(false), InReg(false), - SuppressSRet(false) {} + TheKind(Direct), PaddingInReg(false), InReg(false) {} static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0, llvm::Type *Padding = nullptr, @@ -408,16 +405,6 @@ public: CanBeFlattened = Flatten; } - bool getSuppressSRet() const { - assert(isIndirect() && "Invalid kind!"); - return SuppressSRet; - } - - void setSuppressSRet(bool Suppress) { - assert(isIndirect() && "Invalid kind!"); - SuppressSRet = Suppress; - } - void dump() const; }; @@ -441,31 +428,30 @@ public: /// /// If FD is not null, this will consider pass_object_size params in FD. static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, - unsigned additional, - const FunctionDecl *FD) { + unsigned additional) { if (!prototype->isVariadic()) return All; - if (FD) - additional += - llvm::count_if(FD->parameters(), [](const ParmVarDecl *PVD) { - return PVD->hasAttr<PassObjectSizeAttr>(); + + if (prototype->hasExtParameterInfos()) + additional += llvm::count_if( + prototype->getExtParameterInfos(), + [](const FunctionProtoType::ExtParameterInfo &ExtInfo) { + return ExtInfo.hasPassObjectSize(); }); + return RequiredArgs(prototype->getNumParams() + additional); } - static RequiredArgs forPrototype(const FunctionProtoType *prototype, - const FunctionDecl *FD) { - return forPrototypePlus(prototype, 0, FD); + static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, + unsigned additional) { + return forPrototypePlus(prototype.getTypePtr(), additional); } - static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype, - const FunctionDecl *FD) { - return forPrototype(prototype.getTypePtr(), FD); + static RequiredArgs forPrototype(const FunctionProtoType *prototype) { + return forPrototypePlus(prototype, 0); } - static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, - unsigned additional, - const FunctionDecl *FD) { - return forPrototypePlus(prototype.getTypePtr(), additional, FD); + static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { + return forPrototypePlus(prototype.getTypePtr(), 0); } bool allowsOptionalArgs() const { return NumRequired != ~0U; } diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h index 53619fa8ef65..31f0cea57232 100644 --- a/include/clang/CodeGen/CodeGenABITypes.h +++ b/include/clang/CodeGen/CodeGenABITypes.h @@ -1,9 +1,8 @@ //==---- CodeGenABITypes.h - Convert Clang types to LLVM types for ABI -----==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -31,6 +30,7 @@ namespace llvm { class DataLayout; class Module; + class Function; class FunctionType; class Type; } @@ -55,8 +55,7 @@ const CGFunctionInfo &arrangeObjCMessageSendSignature(CodeGenModule &CGM, QualType receiverType); const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM, - CanQual<FunctionProtoType> Ty, - const FunctionDecl *FD); + CanQual<FunctionProtoType> Ty); const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM, CanQual<FunctionNoProtoType> Ty); @@ -85,6 +84,59 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, QualType T); unsigned getLLVMFieldNumber(CodeGenModule &CGM, const RecordDecl *RD, const FieldDecl *FD); +/// Returns the default constructor for a C struct with non-trivially copyable +/// fields, generating it if necessary. The returned function uses the `cdecl` +/// calling convention, returns void, and takes a single argument that is a +/// pointer to the address of the struct. +llvm::Function *getNonTrivialCStructDefaultConstructor(CodeGenModule &GCM, + CharUnits DstAlignment, + bool IsVolatile, + QualType QT); + +/// Returns the copy constructor for a C struct with non-trivially copyable +/// fields, generating it if necessary. The returned function uses the `cdecl` +/// calling convention, returns void, and takes two arguments: pointers to the +/// addresses of the destination and source structs, respectively. +llvm::Function *getNonTrivialCStructCopyConstructor(CodeGenModule &CGM, + CharUnits DstAlignment, + CharUnits SrcAlignment, + bool IsVolatile, + QualType QT); + +/// Returns the move constructor for a C struct with non-trivially copyable +/// fields, generating it if necessary. The returned function uses the `cdecl` +/// calling convention, returns void, and takes two arguments: pointers to the +/// addresses of the destination and source structs, respectively. +llvm::Function *getNonTrivialCStructMoveConstructor(CodeGenModule &CGM, + CharUnits DstAlignment, + CharUnits SrcAlignment, + bool IsVolatile, + QualType QT); + +/// Returns the copy assignment operator for a C struct with non-trivially +/// copyable fields, generating it if necessary. The returned function uses the +/// `cdecl` calling convention, returns void, and takes two arguments: pointers +/// to the addresses of the destination and source structs, respectively. +llvm::Function *getNonTrivialCStructCopyAssignmentOperator( + CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, + bool IsVolatile, QualType QT); + +/// Return the move assignment operator for a C struct with non-trivially +/// copyable fields, generating it if necessary. The returned function uses the +/// `cdecl` calling convention, returns void, and takes two arguments: pointers +/// to the addresses of the destination and source structs, respectively. +llvm::Function *getNonTrivialCStructMoveAssignmentOperator( + CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, + bool IsVolatile, QualType QT); + +/// Returns the destructor for a C struct with non-trivially copyable fields, +/// generating it if necessary. The returned function uses the `cdecl` calling +/// convention, returns void, and takes a single argument that is a pointer to +/// the address of the struct. +llvm::Function *getNonTrivialCStructDestructor(CodeGenModule &CGM, + CharUnits DstAlignment, + bool IsVolatile, QualType QT); + } // end namespace CodeGen } // end namespace clang diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h index 5a18a9de030b..1db904ea974c 100644 --- a/include/clang/CodeGen/CodeGenAction.h +++ b/include/clang/CodeGen/CodeGenAction.h @@ -1,9 +1,8 @@ //===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/CodeGen/ConstantInitBuilder.h b/include/clang/CodeGen/ConstantInitBuilder.h index f2e78adb8ceb..fd07e91ba6ae 100644 --- a/include/clang/CodeGen/ConstantInitBuilder.h +++ b/include/clang/CodeGen/ConstantInitBuilder.h @@ -1,9 +1,8 @@ //===- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/CodeGen/ConstantInitFuture.h b/include/clang/CodeGen/ConstantInitFuture.h index f1a7e2264fc6..b08f52872290 100644 --- a/include/clang/CodeGen/ConstantInitFuture.h +++ b/include/clang/CodeGen/ConstantInitFuture.h @@ -1,9 +1,8 @@ //===- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h index e110f6fd30c1..f9d056ed8b1e 100644 --- a/include/clang/CodeGen/ModuleBuilder.h +++ b/include/clang/CodeGen/ModuleBuilder.h @@ -1,9 +1,8 @@ //===--- CodeGen/ModuleBuilder.h - Build LLVM from ASTs ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h index 67be6718fec4..8821cd70362e 100644 --- a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h +++ b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h @@ -1,9 +1,8 @@ //===-- CodeGen/ObjectFilePCHContainerOperations.h - ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/CodeGen/SwiftCallingConv.h b/include/clang/CodeGen/SwiftCallingConv.h index 5aa9be2d67c1..2c5e9a6de7e2 100644 --- a/include/clang/CodeGen/SwiftCallingConv.h +++ b/include/clang/CodeGen/SwiftCallingConv.h @@ -1,9 +1,8 @@ //==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/CrossTU/CrossTUDiagnostic.h b/include/clang/CrossTU/CrossTUDiagnostic.h index 56c83a5ad25c..95a648a56082 100644 --- a/include/clang/CrossTU/CrossTUDiagnostic.h +++ b/include/clang/CrossTU/CrossTUDiagnostic.h @@ -1,9 +1,8 @@ //===--- CrossTUDiagnostic.h - Diagnostics for Cross TU ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h index 52e3ae27490f..d64329cdff3e 100644 --- a/include/clang/CrossTU/CrossTranslationUnit.h +++ b/include/clang/CrossTU/CrossTranslationUnit.h @@ -1,9 +1,8 @@ //===--- CrossTranslationUnit.h - -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -15,7 +14,7 @@ #ifndef LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H #define LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H -#include "clang/AST/ASTImporterLookupTable.h" +#include "clang/AST/ASTImporterSharedState.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" @@ -29,6 +28,7 @@ class ASTImporter; class ASTUnit; class DeclContext; class FunctionDecl; +class VarDecl; class NamedDecl; class TranslationUnitDecl; @@ -44,7 +44,9 @@ enum class index_error_code { failed_to_get_external_ast, failed_to_generate_usr, triple_mismatch, - lang_mismatch + lang_mismatch, + lang_dialect_mismatch, + load_threshold_reached }; class IndexError : public llvm::ErrorInfo<IndexError> { @@ -87,6 +89,9 @@ parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir); std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index); +// Returns true if the variable or any field of a record variable is const. +bool containsConst(const VarDecl *VD, const ASTContext &ACtx); + /// This class is used for tools that requires cross translation /// unit capability. /// @@ -102,16 +107,16 @@ public: CrossTranslationUnitContext(CompilerInstance &CI); ~CrossTranslationUnitContext(); - /// This function loads a function definition from an external AST - /// file and merge it into the original AST. + /// This function loads a function or variable definition from an + /// external AST file and merges it into the original AST. /// - /// This method should only be used on functions that have no definitions in + /// This method should only be used on functions that have no definitions or + /// variables that have no initializer in /// the current translation unit. A function definition with the same /// declaration will be looked up in the index file which should be in the /// \p CrossTUDir directory, called \p IndexName. In case the declaration is /// found in the index the corresponding AST file will be loaded and the - /// definition of the function will be merged into the original AST using - /// the AST Importer. + /// definition will be merged into the original AST using the AST Importer. /// /// \return The declaration with the definition will be returned. /// If no suitable definition is found in the index file or multiple @@ -121,17 +126,20 @@ public: llvm::Expected<const FunctionDecl *> getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir, StringRef IndexName, bool DisplayCTUProgress = false); + llvm::Expected<const VarDecl *> + getCrossTUDefinition(const VarDecl *VD, StringRef CrossTUDir, + StringRef IndexName, bool DisplayCTUProgress = false); - /// This function loads a function definition from an external AST - /// file. + /// This function loads a definition from an external AST file. /// - /// A function definition with the same declaration will be looked up in the + /// A definition with the same declaration will be looked up in the /// index file which should be in the \p CrossTUDir directory, called /// \p IndexName. In case the declaration is found in the index the - /// corresponding AST file will be loaded. + /// corresponding AST file will be loaded. If the number of TUs imported + /// reaches \p CTULoadTreshold, no loading is performed. /// /// \return Returns a pointer to the ASTUnit that contains the definition of - /// the looked up function or an Error. + /// the looked up name or an Error. /// The returned pointer is never a nullptr. /// /// Note that the AST files should also be in the \p CrossTUDir. @@ -146,27 +154,40 @@ public: /// /// \return Returns the resulting definition or an error. llvm::Expected<const FunctionDecl *> importDefinition(const FunctionDecl *FD); + llvm::Expected<const VarDecl *> importDefinition(const VarDecl *VD); - /// Get a name to identify a function. + /// Get a name to identify a named decl. static std::string getLookupName(const NamedDecl *ND); /// Emit diagnostics for the user for potential configuration errors. void emitCrossTUDiagnostics(const IndexError &IE); private: - void lazyInitLookupTable(TranslationUnitDecl *ToTU); + void lazyInitImporterSharedSt(TranslationUnitDecl *ToTU); ASTImporter &getOrCreateASTImporter(ASTContext &From); - const FunctionDecl *findFunctionInDeclContext(const DeclContext *DC, - StringRef LookupFnName); + template <typename T> + llvm::Expected<const T *> getCrossTUDefinitionImpl(const T *D, + StringRef CrossTUDir, + StringRef IndexName, + bool DisplayCTUProgress); + template <typename T> + const T *findDefInDeclContext(const DeclContext *DC, + StringRef LookupName); + template <typename T> + llvm::Expected<const T *> importDefinitionImpl(const T *D); llvm::StringMap<std::unique_ptr<clang::ASTUnit>> FileASTUnitMap; - llvm::StringMap<clang::ASTUnit *> FunctionASTUnitMap; - llvm::StringMap<std::string> FunctionFileMap; + llvm::StringMap<clang::ASTUnit *> NameASTUnitMap; + llvm::StringMap<std::string> NameFileMap; llvm::DenseMap<TranslationUnitDecl *, std::unique_ptr<ASTImporter>> ASTUnitImporterMap; CompilerInstance &CI; ASTContext &Context; - std::unique_ptr<ASTImporterLookupTable> LookupTable; + std::shared_ptr<ASTImporterSharedState> ImporterSharedSt; + /// \p CTULoadTreshold should serve as an upper limit to the number of TUs + /// imported in order to reduce the memory footprint of CTU analysis. + const unsigned CTULoadThreshold; + unsigned NumASTLoaded{0u}; }; } // namespace cross_tu diff --git a/include/clang/DirectoryWatcher/DirectoryWatcher.h b/include/clang/DirectoryWatcher/DirectoryWatcher.h new file mode 100644 index 000000000000..e74443e0bc81 --- /dev/null +++ b/include/clang/DirectoryWatcher/DirectoryWatcher.h @@ -0,0 +1,122 @@ +//===- DirectoryWatcher.h - Listens for directory file changes --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DIRECTORYWATCHER_DIRECTORYWATCHER_H +#define LLVM_CLANG_DIRECTORYWATCHER_DIRECTORYWATCHER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include <functional> +#include <memory> +#include <string> + +namespace clang { +/// Provides notifications for file changes in a directory. +/// +/// Invokes client-provided function on every filesystem event in the watched +/// directory. Initially the the watched directory is scanned and for every file +/// found, an event is synthesized as if the file was added. +/// +/// This is not a general purpose directory monitoring tool - list of +/// limitations follows. +/// +/// Only flat directories with no subdirectories are supported. In case +/// subdirectories are present the behavior is unspecified - events *might* be +/// passed to Receiver on macOS (due to FSEvents being used) while they +/// *probably* won't be passed on Linux (due to inotify being used). +/// +/// Known potential inconsistencies +/// - For files that are deleted befor the initial scan processed them, clients +/// might receive Removed notification without any prior Added notification. +/// - Multiple notifications might be produced when a file is added to the +/// watched directory during the initial scan. We are choosing the lesser evil +/// here as the only known alternative strategy would be to invalidate the +/// watcher instance and force user to create a new one whenever filesystem +/// event occurs during the initial scan but that would introduce continuous +/// restarting failure mode (watched directory is not always "owned" by the same +/// process that is consuming it). Since existing clients can handle duplicate +/// events well, we decided for simplicity. +/// +/// Notifications are provided only for changes done through local user-space +/// filesystem interface. Specifically, it's unspecified if notification would +/// be provided in case of a: +/// - a file mmap-ed and changed +/// - a file changed via remote (NFS) or virtual (/proc) FS access to monitored +/// directory +/// - another filesystem mounted to the watched directory +/// +/// No support for LLVM VFS. +/// +/// It is unspecified whether notifications for files being deleted are sent in +/// case the whole watched directory is sent. +/// +/// Directories containing "too many" files and/or receiving events "too +/// frequently" are not supported - if the initial scan can't be finished before +/// the watcher instance gets invalidated (see WatcherGotInvalidated) there's no +/// good error handling strategy - the only option for client is to destroy the +/// watcher, restart watching with new instance and hope it won't repeat. +class DirectoryWatcher { +public: + struct Event { + enum class EventKind { + Removed, + /// Content of a file was modified. + Modified, + /// The watched directory got deleted. + WatchedDirRemoved, + /// The DirectoryWatcher that originated this event is no longer valid and + /// its behavior is unspecified. + /// + /// The prime case is kernel signalling to OS-specific implementation of + /// DirectoryWatcher some resource limit being hit. + /// *Usually* kernel starts dropping or squashing events together after + /// that and so would DirectoryWatcher. This means that *some* events + /// might still be passed to Receiver but this behavior is unspecified. + /// + /// Another case is after the watched directory itself is deleted. + /// WatcherGotInvalidated will be received at least once during + /// DirectoryWatcher instance lifetime - when handling errors this is done + /// on best effort basis, when an instance is being destroyed then this is + /// guaranteed. + /// + /// The only proper response to this kind of event is to destruct the + /// originating DirectoryWatcher instance and create a new one. + WatcherGotInvalidated + }; + + EventKind Kind; + /// Filename that this event is related to or an empty string in + /// case this event is related to the watched directory itself. + std::string Filename; + + Event(EventKind Kind, llvm::StringRef Filename) + : Kind(Kind), Filename(Filename) {} + }; + + /// Returns nullptr if \param Path doesn't exist or isn't a directory. + /// Returns nullptr if OS kernel API told us we can't start watching. In such + /// case it's unclear whether just retrying has any chance to succeeed. + static std::unique_ptr<DirectoryWatcher> + create(llvm::StringRef Path, + std::function<void(llvm::ArrayRef<DirectoryWatcher::Event> Events, + bool IsInitial)> + Receiver, + bool WaitForInitialSync); + + virtual ~DirectoryWatcher() = default; + DirectoryWatcher(const DirectoryWatcher &) = delete; + DirectoryWatcher &operator=(const DirectoryWatcher &) = delete; + DirectoryWatcher(DirectoryWatcher &&) = default; + +protected: + DirectoryWatcher() = default; +}; + +} // namespace clang + +#endif // LLVM_CLANG_DIRECTORYWATCHER_DIRECTORYWATCHER_H diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h index f4aaa6c544ac..c1ff0b1a6023 100644 --- a/include/clang/Driver/Action.h +++ b/include/clang/Driver/Action.h @@ -1,9 +1,8 @@ //===- Action.h - Abstract compilation steps --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 07c76884063f..1f6c000ecf6a 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -1,9 +1,8 @@ //===--- CC1Options.td - Options for clang -cc1 ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -108,7 +107,7 @@ def analyzer_checker : Separate<["-"], "analyzer-checker">, ValuesCode<[{ const char *Values = #define GET_CHECKERS - #define CHECKER(FULLNAME, CLASS, HT, DOC_URI) FULLNAME "," + #define CHECKER(FULLNAME, CLASS, HT, DOC_URI, IS_HIDDEN) FULLNAME "," #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef GET_CHECKERS #define GET_PACKAGES @@ -131,6 +130,15 @@ def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">, def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">, HelpText<"Display the list of analyzer checkers that are available">; +def analyzer_checker_help_alpha : Flag<["-"], "analyzer-checker-help-alpha">, + HelpText<"Display the list of in development analyzer checkers. These " + "are NOT considered safe, they are unstable and will emit incorrect " + "reports. Enable ONLY FOR DEVELOPMENT purposes">; + +def analyzer_checker_help_developer : Flag<["-"], "analyzer-checker-help-developer">, + HelpText<"Display the list of developer-only checkers such as modeling " + "and debug checkers">; + def analyzer_config_help : Flag<["-"], "analyzer-config-help">, HelpText<"Display the list of -analyzer-config options">; @@ -140,12 +148,27 @@ def analyzer_list_enabled_checkers : Flag<["-"], "analyzer-list-enabled-checkers def analyzer_config : Separate<["-"], "analyzer-config">, HelpText<"Choose analyzer options to enable">; +def analyzer_checker_option_help : Flag<["-"], "analyzer-checker-option-help">, + HelpText<"Display the list of checker and package options">; + +def analyzer_checker_option_help_alpha : Flag<["-"], "analyzer-checker-option-help-alpha">, + HelpText<"Display the list of in development checker and package options. " + "These are NOT considered safe, they are unstable and will emit " + "incorrect reports. Enable ONLY FOR DEVELOPMENT purposes">; + +def analyzer_checker_option_help_developer : Flag<["-"], "analyzer-checker-option-help-developer">, + HelpText<"Display the list of checker and package options meant for " + "development purposes only">; + def analyzer_config_compatibility_mode : Separate<["-"], "analyzer-config-compatibility-mode">, HelpText<"Don't emit errors on invalid analyzer-config inputs">; def analyzer_config_compatibility_mode_EQ : Joined<["-"], "analyzer-config-compatibility-mode=">, Alias<analyzer_config_compatibility_mode>; +def analyzer_werror : Flag<["-"], "analyzer-werror">, + HelpText<"Emit analyzer results as errors rather than warnings">; + //===----------------------------------------------------------------------===// // Migrator Options //===----------------------------------------------------------------------===// @@ -167,15 +190,13 @@ def default_function_attr : Separate<["-"], "default-function-attr">, HelpText<"Apply given attribute to all functions">; def dwarf_version_EQ : Joined<["-"], "dwarf-version=">; def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">; -def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">, - HelpText<"The compilation directory to embed in the debug info.">; def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, HelpText<"The string to embed in the Dwarf debug flags record.">; def record_command_line : Separate<["-"], "record-command-line">, HelpText<"The string to embed in the .LLVM.command.line section.">; def compress_debug_sections : Flag<["-", "--"], "compress-debug-sections">, HelpText<"DWARF debug sections compression">; -def compress_debug_sections_EQ : Joined<["-"], "compress-debug-sections=">, +def compress_debug_sections_EQ : Joined<["-", "--"], "compress-debug-sections=">, HelpText<"DWARF debug sections compression type">; def mno_exec_stack : Flag<["-"], "mnoexecstack">, HelpText<"Mark the file as not needing an executable stack">; @@ -209,8 +230,6 @@ def disable_red_zone : Flag<["-"], "disable-red-zone">, HelpText<"Do not emit code that uses the red zone.">; def dwarf_column_info : Flag<["-"], "dwarf-column-info">, HelpText<"Turn on column location information.">; -def split_dwarf : Flag<["-"], "split-dwarf">, - HelpText<"Split out the dwarf .dwo sections">; def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">, HelpText<"Generate debug info with external references to clang modules" " or precompiled headers">; @@ -279,6 +298,8 @@ def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">, "precision">; def mreassociate : Flag<["-"], "mreassociate">, HelpText<"Allow reassociation transformations for floating-point instructions">; +def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">, + HelpText<"Use IEEE 754 quadruple-precision for long double">; def mfloat_abi : Separate<["-"], "mfloat-abi">, HelpText<"The float ABI to use">; def mtp : Separate<["-"], "mtp">, @@ -365,6 +386,8 @@ def flto_unit: Flag<["-"], "flto-unit">, 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">; +def femit_debug_entry_values : Flag<["-"], "femit-debug-entry-values">, + HelpText<"Enables debug info about call site parameter's entry values">; def fdebug_pass_manager : Flag<["-"], "fdebug-pass-manager">, HelpText<"Prints debug information for the new pass manager">; def fno_debug_pass_manager : Flag<["-"], "fno-debug-pass-manager">, @@ -554,8 +577,14 @@ 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_EQ : Joined<["-"], "ast-dump=">, + HelpText<"Build ASTs and then debug dump them in the specified format. " + "Supported formats include: default, json">; def ast_dump_all : Flag<["-"], "ast-dump-all">, HelpText<"Build ASTs and then debug dump them, forcing deserialization">; +def ast_dump_all_EQ : Joined<["-"], "ast-dump-all=">, + HelpText<"Build ASTs and then debug dump them in the specified format, " + "forcing deserialization. Supported formats include: default, json">; def templight_dump : Flag<["-"], "templight-dump">, HelpText<"Dump templight information to stdout">; def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">, @@ -586,6 +615,9 @@ def migrate : Flag<["-"], "migrate">, HelpText<"Migrate source code">; def compiler_options_dump : Flag<["-"], "compiler-options-dump">, HelpText<"Dump the compiler configuration options">; +def print_dependency_directives_minimized_source : Flag<["-"], + "print-dependency-directives-minimized-source">, + HelpText<"Print the output of the dependency directives source minimizer">; } def emit_llvm_uselists : Flag<["-"], "emit-llvm-uselists">, @@ -604,6 +636,10 @@ def arcmt_migrate : Flag<["-"], "arcmt-migrate">, def opt_record_file : Separate<["-"], "opt-record-file">, HelpText<"File name to use for YAML optimization record output">; +def opt_record_passes : Separate<["-"], "opt-record-passes">, + HelpText<"Only record remark information for passes whose names match the given regular expression">; +def opt_record_format : Separate<["-"], "opt-record-format">, + HelpText<"The format used for serializing remarks (default: YAML)">; def print_stats : Flag<["-"], "print-stats">, HelpText<"Print performance metrics and statistics">; @@ -649,7 +685,7 @@ def version : Flag<["-"], "version">, HelpText<"Print the compiler version">; def main_file_name : Separate<["-"], "main-file-name">, HelpText<"Main file name to use for debug info">; -def split_dwarf_file : Separate<["-"], "split-dwarf-file">, +def split_dwarf_output : Separate<["-"], "split-dwarf-output">, HelpText<"File name to use for split dwarf debug info output">; } @@ -658,10 +694,8 @@ def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, HelpText<"Weakly link in the blocks runtime">; def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">, HelpText<"Assume all functions with C linkage do not unwind">; -def enable_split_dwarf : Flag<["-"], "enable-split-dwarf">, - HelpText<"Use DWARF fission in 'split' mode">; -def enable_split_dwarf_EQ : Joined<["-"], "enable-split-dwarf=">, - HelpText<"Set DWARF fission mode to either 'split' or 'single'">, Values<"split,single">; +def split_dwarf_file : Separate<["-"], "split-dwarf-file">, + HelpText<"Name of the split dwarf debug info file to encode in the object file">; def fno_wchar : Flag<["-"], "fno-wchar">, HelpText<"Disable C++ builtin type wchar_t">; def fconstant_string_class : Separate<["-"], "fconstant-string-class">, @@ -703,6 +737,8 @@ def fvisibility : Separate<["-"], "fvisibility">, HelpText<"Default type and symbol visibility">; def ftype_visibility : Separate<["-"], "ftype-visibility">, HelpText<"Default type visibility">; +def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-to-externs">, + HelpText<"Apply global symbol visibility to external declarations without an explicit visibility">; def ftemplate_depth : Separate<["-"], "ftemplate-depth">, HelpText<"Maximum depth of recursive template instantiation">; def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">, @@ -748,7 +784,9 @@ def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-r def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">, HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">; def finclude_default_header : Flag<["-"], "finclude-default-header">, - HelpText<"Include the default header file for OpenCL">; + HelpText<"Include default header file for OpenCL">; +def fdeclare_opencl_builtins : Flag<["-"], "fdeclare-opencl-builtins">, + HelpText<"Add OpenCL builtin function declarations (experimental)">; def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">, HelpText<"Preserve 3-component vector type">; def fwchar_type_EQ : Joined<["-"], "fwchar-type=">, @@ -835,8 +873,14 @@ def fopenmp_is_device : Flag<["-"], "fopenmp-is-device">, def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">, HelpText<"Path to the IR file produced by the frontend for the host.">; -} // let Flags = [CC1Option] +//===----------------------------------------------------------------------===// +// SYCL Options +//===----------------------------------------------------------------------===// + +def fsycl_is_device : Flag<["-"], "fsycl-is-device">, + HelpText<"Generate code for SYCL device.">; +} // let Flags = [CC1Option] //===----------------------------------------------------------------------===// // cc1as-only Options diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td index 3e0dc2db7d07..a0af3035ea46 100644 --- a/include/clang/Driver/CLCompatOptions.td +++ b/include/clang/Driver/CLCompatOptions.td @@ -1,9 +1,8 @@ //===--- CLCompatOptions.td - Options for clang-cl ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -53,20 +52,21 @@ class CLRemainingArgsJoined<string name> : Option<["/", "-"], name, // already in the right group.) def _SLASH_Brepro : CLFlag<"Brepro">, - HelpText<"Emit an object file which can be reproduced over time">, + HelpText<"Do not write current time into COFF output (breaks link.exe /incremental)">, Alias<mno_incremental_linker_compatible>; def _SLASH_Brepro_ : CLFlag<"Brepro-">, - HelpText<"Emit an object file which cannot be reproduced over time">, + HelpText<"Write current time into COFF output (default)">, Alias<mincremental_linker_compatible>; def _SLASH_C : CLFlag<"C">, - HelpText<"Don't discard comments when preprocessing">, Alias<C>; + HelpText<"Do not discard comments when preprocessing">, Alias<C>; def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>; def _SLASH_d1PP : CLFlag<"d1PP">, HelpText<"Retain macro definitions in /E mode">, Alias<dD>; def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">, - HelpText<"Dump record layout information">, Alias<fdump_record_layouts>; + HelpText<"Dump record layout information">, + Alias<Xclang>, AliasArgs<["-fdump-record-layouts"]>; def _SLASH_diagnostics_caret : CLFlag<"diagnostics:caret">, - HelpText<"Enable caret and column diagnostics (on by default)">; + HelpText<"Enable caret and column diagnostics (default)">; def _SLASH_diagnostics_column : CLFlag<"diagnostics:column">, HelpText<"Disable caret diagnostics but keep column info">; def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">, @@ -83,12 +83,14 @@ def _SLASH_fp_precise : CLFlag<"fp:precise">, def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias<fno_fast_math>; def _SLASH_GA : CLFlag<"GA">, Alias<ftlsmodel_EQ>, AliasArgs<["local-exec"]>, HelpText<"Assume thread-local variables are defined in the executable">; -def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable emission of RTTI data">; -def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">; -def _SLASH_GF : CLIgnoredFlag<"GF">, HelpText<"Enable string pooling (default)">; +def _SLASH_GR : CLFlag<"GR">, HelpText<"Emit RTTI data (default)">; +def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Do not emit RTTI data">; +def _SLASH_GF : CLIgnoredFlag<"GF">, + HelpText<"Enable string pooling (default)">; def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, Alias<fwritable_strings>; -def _SLASH_GS : CLFlag<"GS">, HelpText<"Enable buffer security check (default)">; +def _SLASH_GS : CLFlag<"GS">, + HelpText<"Enable buffer security check (default)">; def _SLASH_GS_ : CLFlag<"GS-">, HelpText<"Disable buffer security check">; def : CLFlag<"Gs">, HelpText<"Use stack probes (default)">, Alias<mstack_probe_size>, AliasArgs<["4096"]>; @@ -97,12 +99,12 @@ def _SLASH_Gs : CLJoined<"Gs">, def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">, Alias<ffunction_sections>; def _SLASH_Gy_ : CLFlag<"Gy-">, - HelpText<"Don't put each function in its own section (default)">, + HelpText<"Do not put each function in its own section (default)">, Alias<fno_function_sections>; def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">, Alias<fdata_sections>; def _SLASH_Gw_ : CLFlag<"Gw-">, - HelpText<"Don't put each data item in its own section">, + HelpText<"Do not put each data item in its own section (default)">, Alias<fno_data_sections>; def _SLASH_help : CLFlag<"help">, Alias<help>, HelpText<"Display available options">; @@ -118,16 +120,14 @@ def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">, def _SLASH_O : CLJoined<"O">, HelpText<"Set multiple /O flags at once; e.g. '/O2y-' for '/O2 /Oy-'">, MetaVarName<"<flags>">; -// FIXME: Not sure why we have -O0 here; MSVC doesn't support that. -def : CLFlag<"O0">, Alias<O0>, HelpText<"Disable optimization">; def : CLFlag<"O1">, Alias<_SLASH_O>, AliasArgs<["1"]>, - HelpText<"Optimize for size (same as /Og /Os /Oy /Ob2 /GF /Gy)">; + HelpText<"Optimize for size (like /Og /Os /Oy /Ob2 /GF /Gy)">; def : CLFlag<"O2">, Alias<_SLASH_O>, AliasArgs<["2"]>, - HelpText<"Optimize for speed (same as /Og /Oi /Ot /Oy /Ob2 /GF /Gy)">; + HelpText<"Optimize for speed (like /Og /Oi /Ot /Oy /Ob2 /GF /Gy)">; def : CLFlag<"Ob0">, Alias<_SLASH_O>, AliasArgs<["b0"]>, HelpText<"Disable function inlining">; def : CLFlag<"Ob1">, Alias<_SLASH_O>, AliasArgs<["b1"]>, - HelpText<"Only inline functions which are (explicitly or implicitly) marked inline">; + HelpText<"Only inline functions explicitly or implicitly marked inline">; def : CLFlag<"Ob2">, Alias<_SLASH_O>, AliasArgs<["b2"]>, HelpText<"Inline functions as deemed beneficial by the compiler">; def : CLFlag<"Od">, Alias<_SLASH_O>, AliasArgs<["d"]>, @@ -143,7 +143,7 @@ def : CLFlag<"Os">, Alias<_SLASH_O>, AliasArgs<["s"]>, def : CLFlag<"Ot">, Alias<_SLASH_O>, AliasArgs<["t"]>, HelpText<"Optimize for speed">; def : CLFlag<"Ox">, Alias<_SLASH_O>, AliasArgs<["x"]>, - HelpText<"Deprecated (same as /Og /Oi /Ot /Oy /Ob2); use /O2 instead">; + HelpText<"Deprecated (like /Og /Oi /Ot /Oy /Ob2); use /O2">; def : CLFlag<"Oy">, Alias<_SLASH_O>, AliasArgs<["y"]>, HelpText<"Enable frame pointer omission (x86 only)">; def : CLFlag<"Oy-">, Alias<_SLASH_O>, AliasArgs<["y-"]>, @@ -161,13 +161,15 @@ def _SLASH_showIncludes : CLFlag<"showIncludes">, def _SLASH_showFilenames : CLFlag<"showFilenames">, HelpText<"Print the name of each compiled file">; def _SLASH_showFilenames_ : CLFlag<"showFilenames-">, - HelpText<"Don't print the name of each compiled file (default)">; + HelpText<"Do not print the name of each compiled file (default)">; def _SLASH_source_charset : CLCompileJoined<"source-charset:">, - HelpText<"Source encoding, supports only UTF-8">, Alias<finput_charset_EQ>; + HelpText<"Set source encoding, supports only UTF-8">, + Alias<finput_charset_EQ>; def _SLASH_execution_charset : CLCompileJoined<"execution-charset:">, - HelpText<"Runtime encoding, supports only UTF-8">, Alias<fexec_charset_EQ>; + HelpText<"Set runtime encoding, supports only UTF-8">, + Alias<fexec_charset_EQ>; def _SLASH_std : CLCompileJoined<"std:">, - HelpText<"Language standard to compile for">; + HelpText<"Set C++ version (c++14,c++17,c++latest)">; def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">, MetaVarName<"<macro>">, Alias<U>; def _SLASH_validate_charset : CLFlag<"validate-charset">, @@ -183,7 +185,8 @@ def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Weverything">, Alias<W_Joined>, AliasArgs<["everything"]>; def _SLASH_WX : CLFlag<"WX">, HelpText<"Treat warnings as errors">, Alias<W_Joined>, AliasArgs<["error"]>; -def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">, +def _SLASH_WX_ : CLFlag<"WX-">, + HelpText<"Do not treat warnings as errors (default)">, Alias<W_Joined>, AliasArgs<["no-error"]>; def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>; def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>, @@ -199,8 +202,7 @@ def _SLASH_wd4996 : CLFlag<"wd4996">, Alias<W_Joined>, def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">, Alias<vtordisp_mode_EQ>; def _SLASH_X : CLFlag<"X">, - HelpText<"Don't add %INCLUDE% to the include search path">, - Alias<nostdlibinc>; + HelpText<"Do not add %INCLUDE% to include search path">, Alias<nostdlibinc>; def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">, HelpText<"Enable C++14 sized global deallocation functions">, Alias<fsized_deallocation>; @@ -213,6 +215,12 @@ def _SLASH_Zc_alignedNew : CLFlag<"Zc:alignedNew">, def _SLASH_Zc_alignedNew_ : CLFlag<"Zc:alignedNew-">, HelpText<"Disable C++17 aligned allocation functions">, Alias<fno_aligned_allocation>; +def _SLASH_Zc_char8_t : CLFlag<"Zc:char8_t">, + HelpText<"Enable char8_t from C++2a">, + Alias<fchar8__t>; +def _SLASH_Zc_char8_t_ : CLFlag<"Zc:char8_t-">, + HelpText<"Disable char8_t from c++2a">, + Alias<fno_char8__t>; def _SLASH_Zc_strictStrings : CLFlag<"Zc:strictStrings">, HelpText<"Treat string literals as const">, Alias<W_Joined>, AliasArgs<["error=c++11-compat-deprecated-writable-strings"]>; @@ -230,19 +238,19 @@ def _SLASH_Zc_twoPhase : CLFlag<"Zc:twoPhase">, HelpText<"Enable two-phase name lookup in templates">, Alias<fno_delayed_template_parsing>; def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">, - HelpText<"Disable two-phase name lookup in templates">, + HelpText<"Disable two-phase name lookup in templates (default)">, Alias<fdelayed_template_parsing>; def _SLASH_Z7 : CLFlag<"Z7">, HelpText<"Enable CodeView debug information in object files">; def _SLASH_Zd : CLFlag<"Zd">, HelpText<"Emit debug line number tables only">; def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, - HelpText<"Alias for /Z7. Does not produce PDBs.">; + HelpText<"Like /Z7">; def _SLASH_Zp : CLJoined<"Zp">, - HelpText<"Specify the default maximum struct packing alignment">, + HelpText<"Set default maximum struct packing alignment">, Alias<fpack_struct_EQ>; def _SLASH_Zp_flag : CLFlag<"Zp">, - HelpText<"Set the default maximum struct packing alignment to 1">, + HelpText<"Set default maximum struct packing alignment to 1">, Alias<fpack_struct_EQ>, AliasArgs<["1"]>; def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">, Alias<fsyntax_only>; @@ -257,35 +265,35 @@ def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>; def _SLASH_volatile_Group : OptionGroup<"</volatile group>">, Group<cl_compile_Group>; -def _SLASH_EH : CLJoined<"EH">, HelpText<"Exception handling model">; +def _SLASH_EH : CLJoined<"EH">, HelpText<"Set exception handling model">; def _SLASH_EP : CLFlag<"EP">, HelpText<"Disable linemarker output and preprocess to stdout">; def _SLASH_FA : CLFlag<"FA">, HelpText<"Output assembly code file during compilation">; def _SLASH_Fa : CLJoined<"Fa">, - HelpText<"Output assembly code to this file during compilation (with /FA)">, - MetaVarName<"<file or directory>">; + HelpText<"Set assembly output file name (with /FA)">, + MetaVarName<"<file or dir/>">; def _SLASH_fallback : CLCompileFlag<"fallback">, HelpText<"Fall back to cl.exe if clang-cl fails to compile">; def _SLASH_FI : CLJoinedOrSeparate<"FI">, HelpText<"Include file before parsing">, Alias<include_>; def _SLASH_Fe : CLJoined<"Fe">, - HelpText<"Set output executable file or directory (ends in / or \\)">, - MetaVarName<"<file or directory>">; + HelpText<"Set output executable file name">, + MetaVarName<"<file or dir/>">; def _SLASH_Fi : CLCompileJoined<"Fi">, HelpText<"Set preprocess output file name (with /P)">, MetaVarName<"<file>">; def _SLASH_Fo : CLCompileJoined<"Fo">, - HelpText<"Set output object file, or directory (ends in / or \\) (with /c)">, - MetaVarName<"<file or directory>">; + HelpText<"Set output object file (with /c)">, + MetaVarName<"<file or dir/>">; def _SLASH_guard : CLJoined<"guard:">, HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks">; def _SLASH_GX : CLFlag<"GX">, - HelpText<"Enable exception handling">; + HelpText<"Deprecated; use /EHsc">; def _SLASH_GX_ : CLFlag<"GX-">, - HelpText<"Disable exception handling">; + HelpText<"Deprecated (like not passing /EH)">; def _SLASH_imsvc : CLJoinedOrSeparate<"imsvc">, - HelpText<"Add directory to system include search path, as if part of %INCLUDE%">, + HelpText<"Add <dir> to system include search path, as if in %INCLUDE%">, MetaVarName<"<dir>">; def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">; def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">; @@ -300,14 +308,14 @@ def _SLASH_MT : Option<["/", "-"], "MT", KIND_FLAG>, Group<_SLASH_M_Group>, def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>, Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">; def _SLASH_o : CLJoinedOrSeparate<"o">, - HelpText<"Set output file or directory (ends in / or \\)">, - MetaVarName<"<file or directory>">; + HelpText<"Deprecated (set output file name); use /Fe or /Fe">, + MetaVarName<"<file or dir/>">; def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">; def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">, - HelpText<"Specify a C source file">, MetaVarName<"<filename>">; + HelpText<"Treat <file> as C source file">, MetaVarName<"<file>">; def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">; def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">, - HelpText<"Specify a C++ source file">, MetaVarName<"<filename>">; + HelpText<"Treat <file> as C++ source file">, MetaVarName<"<file>">; def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">; def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>, Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>, @@ -330,7 +338,7 @@ def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>, def _SLASH_clang : CLJoined<"clang:">, HelpText<"Pass <arg> to the clang driver">, MetaVarName<"<arg>">; def _SLASH_Zl : CLFlag<"Zl">, - HelpText<"Don't mention any default libraries in the object file">; + HelpText<"Do not let object file auto-link default libraries">; def _SLASH_Yc : CLJoined<"Yc">, HelpText<"Generate a pch file for all code up to and including <filename>">, @@ -344,9 +352,9 @@ def _SLASH_Y_ : CLFlag<"Y-">, def _SLASH_Zc_dllexportInlines : CLFlag<"Zc:dllexportInlines">, HelpText<"dllexport/dllimport inline member functions of dllexport/import classes (default)">; def _SLASH_Zc_dllexportInlines_ : CLFlag<"Zc:dllexportInlines-">, - HelpText<"Don't dllexport/dllimport inline member functions of dllexport/import classes">; + HelpText<"Do not dllexport/dllimport inline member functions of dllexport/import classes">; def _SLASH_Fp : CLJoined<"Fp">, - HelpText<"Set pch filename (with /Yc and /Yu)">, MetaVarName<"<filename>">; + HelpText<"Set pch file name (with /Yc and /Yu)">, MetaVarName<"<file>">; def _SLASH_Gd : CLFlag<"Gd">, HelpText<"Set __cdecl as a default calling convention">; @@ -395,14 +403,17 @@ def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; // Unsupported: -def _SLASH_AI : CLJoined<"AI">; +def _SLASH_await : CLFlag<"await">; +def _SLASH_constexpr : CLJoined<"constexpr:">; +def _SLASH_AI : CLJoinedOrSeparate<"AI">; def _SLASH_Bt : CLFlag<"Bt">; def _SLASH_Bt_plus : CLFlag<"Bt+">; def _SLASH_clr : CLJoined<"clr">; +def _SLASH_d2 : CLJoined<"d2">; def _SLASH_doc : CLJoined<"doc">; def _SLASH_FA_joined : CLJoined<"FA">; def _SLASH_favor : CLJoined<"favor">; -def _SLASH_F : CLFlag<"F">; +def _SLASH_F : CLJoinedOrSeparate<"F">; def _SLASH_Fm : CLJoined<"Fm">; def _SLASH_Fr : CLJoined<"Fr">; def _SLASH_FR : CLJoined<"FR">; @@ -426,10 +437,14 @@ def _SLASH_kernel : CLFlag<"kernel">; def _SLASH_LN : CLFlag<"LN">; def _SLASH_MP : CLJoined<"MP">; def _SLASH_openmp : CLFlag<"openmp">; +def _SLASH_openmp_experimental : CLFlag<"openmp:experimental">; def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">; def _SLASH_QIfist : CLFlag<"QIfist">; def _SLASH_Qimprecise_fwaits : CLFlag<"Qimprecise_fwaits">; def _SLASH_Qpar : CLFlag<"Qpar">; +def _SLASH_Qpar_report : CLJoined<"Qpar-report">; +def _SLASH_Qsafe_fp_loads : CLFlag<"Qsafe_fp_loads">; +def _SLASH_Qspectre : CLFlag<"Qspectre">; def _SLASH_Qvec_report : CLJoined<"Qvec-report">; def _SLASH_u : CLFlag<"u">; def _SLASH_V : CLFlag<"V">; diff --git a/include/clang/Driver/ClangOptionDocs.td b/include/clang/Driver/ClangOptionDocs.td index 97c44692d257..55136421614d 100644 --- a/include/clang/Driver/ClangOptionDocs.td +++ b/include/clang/Driver/ClangOptionDocs.td @@ -1,9 +1,8 @@ //==--- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h index 20eb07f6de8b..33ae133e0562 100644 --- a/include/clang/Driver/Compilation.h +++ b/include/clang/Driver/Compilation.h @@ -1,9 +1,8 @@ //===- Compilation.h - Compilation Task Data Structure ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/DarwinSDKInfo.h b/include/clang/Driver/DarwinSDKInfo.h index 4ffb02fea345..f7075a8d3b7f 100644 --- a/include/clang/Driver/DarwinSDKInfo.h +++ b/include/clang/Driver/DarwinSDKInfo.h @@ -1,9 +1,8 @@ //===--- DarwinSDKInfo.h - SDK Information parser for darwin ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/Distro.h b/include/clang/Driver/Distro.h index 5651ebb6d42c..67dc764fb7d1 100644 --- a/include/clang/Driver/Distro.h +++ b/include/clang/Driver/Distro.h @@ -1,9 +1,8 @@ //===--- Distro.h - Linux distribution detection support --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -34,6 +33,7 @@ public: DebianJessie, DebianStretch, DebianBuster, + DebianBullseye, Exherbo, RHEL5, RHEL6, @@ -64,6 +64,7 @@ public: UbuntuBionic, UbuntuCosmic, UbuntuDisco, + UbuntuEoan, UnknownDistro }; @@ -113,11 +114,11 @@ public: } bool IsDebian() const { - return DistroVal >= DebianLenny && DistroVal <= DebianBuster; + return DistroVal >= DebianLenny && DistroVal <= DebianBullseye; } bool IsUbuntu() const { - return DistroVal >= UbuntuHardy && DistroVal <= UbuntuDisco; + return DistroVal >= UbuntuHardy && DistroVal <= UbuntuEoan; } bool IsAlpineLinux() const { diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 494336d672c2..f9528641073a 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -1,9 +1,8 @@ //===--- Driver.h - Clang GCC Compatible Driver -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -236,9 +235,6 @@ private: /// Certain options suppress the 'no input files' warning. unsigned SuppressMissingInputWarning : 1; - std::list<std::string> TempFiles; - std::list<std::string> ResultFiles; - /// Cache of all the ToolChains in use by the driver. /// /// This maps from the string representation of a triple to a ToolChain @@ -278,6 +274,12 @@ private: SmallString<128> &CrashDiagDir); public: + + /// Takes the path to a binary that's either in bin/ or lib/ and returns + /// the path to clang's resource directory. + static std::string GetResourcesPath(StringRef BinaryPath, + StringRef CustomResourceDir = ""); + Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); @@ -389,6 +391,14 @@ public: void BuildUniversalActions(Compilation &C, const ToolChain &TC, const InputList &BAInputs) const; + /// Check that the file referenced by Value exists. If it doesn't, + /// issue a diagnostic and return false. + /// If TypoCorrect is true and the file does not exist, see if it looks + /// like a likely typo for a flag and if so print a "did you mean" blurb. + bool DiagnoseInputExistence(const llvm::opt::DerivedArgList &Args, + StringRef Value, types::ID Ty, + bool TypoCorrect) const; + /// BuildJobs - Bind actions to concrete tools and translate /// arguments to form the list of jobs to run. /// diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h index ad160ec6c64f..ec2f8b403b0b 100644 --- a/include/clang/Driver/DriverDiagnostic.h +++ b/include/clang/Driver/DriverDiagnostic.h @@ -1,9 +1,8 @@ //===--- DiagnosticDriver.h - Diagnostics for libdriver ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h index 870a31c52093..41d972280852 100644 --- a/include/clang/Driver/Job.h +++ b/include/clang/Driver/Job.h @@ -1,9 +1,8 @@ //===- Job.h - Commands to Execute ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h index 132d981854fc..abf0d5fa6ea2 100644 --- a/include/clang/Driver/Multilib.h +++ b/include/clang/Driver/Multilib.h @@ -1,9 +1,8 @@ //===- Multilib.h -----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -35,10 +34,11 @@ private: std::string OSSuffix; std::string IncludeSuffix; flags_list Flags; + int Priority; public: Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {}, - StringRef IncludeSuffix = {}); + StringRef IncludeSuffix = {}, int Priority = 0); /// Get the detected GCC installation path suffix for the multi-arch /// target variant. Always starts with a '/', unless empty @@ -78,6 +78,10 @@ public: const flags_list &flags() const { return Flags; } flags_list &flags() { return Flags; } + /// Returns the multilib priority. When more than one multilib matches flags, + /// the one with the highest priority is selected, with 0 being the default. + int priority() const { return Priority; } + /// Add a flag to the flags list /// \p Flag must be a flag accepted by the driver with its leading '-' removed, /// and replaced with either: diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h index 2da3cb4828c8..f8963d48112a 100644 --- a/include/clang/Driver/Options.h +++ b/include/clang/Driver/Options.h @@ -1,9 +1,8 @@ //===--- Options.h - Option info & table ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index f02a7190f5a7..dfd27fab796e 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -1,9 +1,8 @@ //===--- Options.td - Options for clang -----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -552,9 +551,9 @@ def cuda_compile_host_device : Flag<["--"], "cuda-compile-host-device">, HelpText<"Compile CUDA code for both host and device (default). Has no " "effect on non-CUDA compilations.">; def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">, Flags<[DriverOption]>, - HelpText<"Include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; + HelpText<"Include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">, Flags<[DriverOption]>, - HelpText<"Do not include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; + HelpText<"Do not include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>, HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">; def hip_link : Flag<["--"], "hip-link">, @@ -624,6 +623,9 @@ def emit_ast : Flag<["-"], "emit-ast">, HelpText<"Emit Clang AST files for source inputs">; def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option]>, Group<Action_Group>, HelpText<"Use the LLVM representation for assembler and object files">; +def emit_iterface_stubs : Flag<["-"], "emit-interface-stubs">, Flags<[CC1Option]>, Group<Action_Group>, + HelpText<"Generate Inteface Stub Files.">; +def iterface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">, Flags<[CC1Option]>; def exported__symbols__list : Separate<["-"], "exported_symbols_list">; def e : JoinedOrSeparate<["-"], "e">, Group<Link_Group>; def fPIC : Flag<["-"], "fPIC">, Group<f_Group>; @@ -714,11 +716,14 @@ def fauto_profile_accurate : Flag<["-"], "fauto-profile-accurate">, Group<f_Group>, Alias<fprofile_sample_accurate>; def fno_auto_profile_accurate : Flag<["-"], "fno-auto-profile-accurate">, Group<f_Group>, Alias<fno_profile_sample_accurate>; -def fdebug_info_for_profiling : Flag<["-"], "fdebug-info-for-profiling">, Group<f_Group>, - Flags<[CC1Option]>, +def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">, + Group<f_Group>, Flags<[CC1Option, CC1AsOption, CoreOption]>, + HelpText<"The compilation directory to embed in the debug info.">; +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]>, +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]>, @@ -743,24 +748,30 @@ def fno_coverage_mapping : Flag<["-"], "fno-coverage-mapping">, Group<f_Group>, Flags<[DriverOption, CoreOption]>, HelpText<"Disable code coverage analysis">; def fprofile_generate : Flag<["-"], "fprofile-generate">, - Group<f_Group>, Flags<[DriverOption]>, + Group<f_Group>, Flags<[CoreOption]>, HelpText<"Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">; def fprofile_generate_EQ : Joined<["-"], "fprofile-generate=">, - Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<directory>">, + Group<f_Group>, Flags<[CoreOption]>, MetaVarName<"<directory>">, HelpText<"Generate instrumented code to collect execution counts into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">; +def fcs_profile_generate : Flag<["-"], "fcs-profile-generate">, + Group<f_Group>, Flags<[CoreOption]>, + HelpText<"Generate instrumented code to collect context sensitive execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">; +def fcs_profile_generate_EQ : Joined<["-"], "fcs-profile-generate=">, + Group<f_Group>, Flags<[CoreOption]>, MetaVarName<"<directory>">, + HelpText<"Generate instrumented code to collect context sensitive execution counts into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">; def fprofile_use : Flag<["-"], "fprofile-use">, Group<f_Group>, Alias<fprofile_instr_use>; def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<pathname>">, HelpText<"Use instrumentation data for profile-guided optimization. If pathname is a directory, it reads from <pathname>/default.profdata. Otherwise, it reads from file <pathname>.">; def fno_profile_instr_generate : Flag<["-"], "fno-profile-instr-generate">, - Group<f_Group>, Flags<[DriverOption]>, + Group<f_Group>, Flags<[CoreOption]>, HelpText<"Disable generation of profile instrumentation.">; def fno_profile_generate : Flag<["-"], "fno-profile-generate">, - Group<f_Group>, Flags<[DriverOption]>, + Group<f_Group>, Flags<[CoreOption]>, HelpText<"Disable generation of profile instrumentation.">; def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">, - Group<f_Group>, Flags<[DriverOption]>, + Group<f_Group>, Flags<[CoreOption]>, HelpText<"Disable using instrumentation data for profile-guided optimization">; def fno_profile_use : Flag<["-"], "fno-profile-use">, Alias<fno_profile_instr_use>; @@ -770,6 +781,9 @@ def fprofile_filter_files_EQ : Joined<["-"], "fprofile-filter-files=">, def fprofile_exclude_files_EQ : Joined<["-"], "fprofile-exclude-files=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>, HelpText<"Instrument only functions from files where names don't match all the regexes separated by a semi-colon">; +def forder_file_instrumentation : Flag<["-"], "forder-file-instrumentation">, + Group<f_Group>, Flags<[CC1Option, CoreOption]>, + HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">; def faddrsig : Flag<["-"], "faddrsig">, Group<f_Group>, Flags<[CoreOption, CC1Option]>, HelpText<"Emit an address-significance table">; @@ -902,7 +916,7 @@ def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>; def fmath_errno : Flag<["-"], "fmath-errno">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Require math functions to indicate errors by setting errno">; def fno_math_errno : Flag<["-"], "fno-math-errno">, Group<f_Group>; -def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>; +def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>, Flags<[CoreOption]>; def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>; def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>; def fjump_tables : Flag<["-"], "fjump-tables">, Group<f_Group>; @@ -927,6 +941,8 @@ def fno_cxx_static_destructors : Flag<["-"], "fno-c++-static-destructors">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disable C++ static destructor registration">; +def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>, + Flags<[CC1Option]>; // Begin sanitizer flags. These should all be core options exposed in all driver // modes. @@ -1240,6 +1256,8 @@ def fno_fine_grained_bitfield_accesses : Flag<["-"], 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 fapple_link_rtlib : Flag<["-"], "fapple-link-rtlib">, Group<f_Group>, + HelpText<"Force linking the clang builtins runtime library">; def flto_EQ : Joined<["-"], "flto=">, Flags<[CoreOption, CC1Option]>, Group<f_Group>, HelpText<"Set LTO mode to either 'full' or 'thin'">, Values<"thin,full">; def flto : Flag<["-"], "flto">, Flags<[CoreOption, CC1Option]>, Group<f_Group>, @@ -1252,7 +1270,7 @@ def flto_jobs_EQ : Joined<["-"], "flto-jobs=">, "of 0 means the number of threads will be derived from " "the number of CPUs detected)">; def fthinlto_index_EQ : Joined<["-"], "fthinlto-index=">, - Flags<[CC1Option]>, Group<f_Group>, + Flags<[CoreOption, CC1Option]>, Group<f_Group>, HelpText<"Perform ThinLTO importing using provided function summary index">; def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">, Group<f_Group>, Flags<[DriverOption, CoreOption]>; @@ -1408,7 +1426,7 @@ def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-m Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Disables an experimental new pass manager in LLVM.">; def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Use the given vector functions library">, Values<"Accelerate,SVML,none">; + HelpText<"Use the given vector functions library">, Values<"Accelerate,MASSV,SVML,none">; def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>, HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">, Flags<[CC1Option]>; def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>, @@ -1574,6 +1592,8 @@ def fopenmp_cuda_number_of_sm_EQ : Joined<["-"], "fopenmp-cuda-number-of-sm=">, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; def fopenmp_cuda_blocks_per_sm_EQ : Joined<["-"], "fopenmp-cuda-blocks-per-sm=">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; +def fopenmp_cuda_teams_reduction_recs_num_EQ : Joined<["-"], "fopenmp-cuda-teams-reduction-recs-num=">, Group<f_Group>, + Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; def fopenmp_optimistic_collapse : Flag<["-"], "fopenmp-optimistic-collapse">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; def fno_openmp_optimistic_collapse : Flag<["-"], "fno-openmp-optimistic-collapse">, Group<f_Group>, @@ -1607,12 +1627,15 @@ def fplt : Flag<["-"], "fplt">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use the PLT to make function calls">; def fno_plt : Flag<["-"], "fno-plt">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not use the PLT to make function calls">; -def fropi : Flag<["-"], "fropi">, Group<f_Group>; +def fropi : Flag<["-"], "fropi">, Group<f_Group>, Flags<[CC1Option]>; def fno_ropi : Flag<["-"], "fno-ropi">, Group<f_Group>; -def frwpi : Flag<["-"], "frwpi">, Group<f_Group>; +def frwpi : Flag<["-"], "frwpi">, Group<f_Group>, Flags<[CC1Option]>; def fno_rwpi : Flag<["-"], "fno-rwpi">, Group<f_Group>; def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<dsopath>">, HelpText<"Load the named plugin (dynamic shared object)">; +def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">, + Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<dsopath>">, + HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">; def fpreserve_as_comments : Flag<["-"], "fpreserve-as-comments">, Group<f_Group>; def fno_preserve_as_comments : Flag<["-"], "fno-preserve-as-comments">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not preserve comments in inline assembly">; @@ -1697,11 +1720,17 @@ def foperator_arrow_depth_EQ : Joined<["-"], "foperator-arrow-depth=">, def fsave_optimization_record : Flag<["-"], "fsave-optimization-record">, Group<f_Group>, HelpText<"Generate a YAML optimization record file">; +def fsave_optimization_record_EQ : Joined<["-"], "fsave-optimization-record=">, + Group<f_Group>, HelpText<"Generate an optimization record file in a specific format (default: YAML)">; def fno_save_optimization_record : Flag<["-"], "fno-save-optimization-record">, Group<f_Group>, Flags<[NoArgumentUnused]>; def foptimization_record_file_EQ : Joined<["-"], "foptimization-record-file=">, Group<f_Group>, HelpText<"Specify the file name of any generated YAML optimization record">; +def foptimization_record_passes_EQ : Joined<["-"], "foptimization-record-passes=">, + Group<f_Group>, + HelpText<"Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes)">; + def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>; def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>, @@ -1728,6 +1757,7 @@ def Wframe_larger_than_EQ : Joined<["-"], "Wframe-larger-than=">, Group<f_Group> def : Flag<["-"], "fterminated-vtables">, Alias<fapple_kext>; def fthreadsafe_statics : Flag<["-"], "fthreadsafe-statics">, Group<f_Group>; def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>, Flags<[CC1Option]>; +def ftime_trace : Flag<["-"], "ftime-trace">, Group<f_Group>, Flags<[CC1Option, CoreOption]>; def ftlsmodel_EQ : Joined<["-"], "ftls-model=">, Group<f_Group>, Flags<[CC1Option]>; def ftrapv : Flag<["-"], "ftrapv">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Trap on integer overflow">; @@ -1993,14 +2023,18 @@ def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group<clang_ignored_m_Grou def mfancy_math_387 : Flag<["-"], "mfancy-math-387">, Group<clang_ignored_m_Group>; def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_Group>, HelpText<"Generate branches with extended addressability, usually via indirect jumps.">; +def mlong_double_64 : Flag<["-"], "mlong-double-64">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Force long double to be 64 bits">; +def mlong_double_128 : Flag<["-"], "mlong-double-128">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Force long double to be 128 bits">; def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_Group>, HelpText<"Restore the default behaviour of not generating long calls">; def mexecute_only : Flag<["-"], "mexecute-only">, Group<m_arm_Features_Group>, HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group<m_arm_Features_Group>, HelpText<"Allow generation of data access to code sections (ARM only)">; -def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft, cp15">, - HelpText<"Read thread pointer from coprocessor register (ARM only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft,cp15,el0,el1,el2,el3">, + HelpText<"Thread pointer access method (AArch32/AArch64 only)">; def mpure_code : Flag<["-"], "mpure-code">, Alias<mexecute_only>; // Alias for GCC compatibility def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias<mno_execute_only>; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>; @@ -2100,6 +2134,10 @@ def mrelax : Flag<["-"], "mrelax">, Group<m_riscv_Features_Group>, HelpText<"Enable linker relaxation">; def mno_relax : Flag<["-"], "mno-relax">, Group<m_riscv_Features_Group>, HelpText<"Disable linker relaxation">; +def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>, + HelpText<"Enable using library calls for save and restore">; +def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>, + HelpText<"Disable using library calls for save and restore">; def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">; @@ -2123,6 +2161,9 @@ 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 mcmse : Flag<["-"], "mcmse">, Group<m_arm_Features_Group>, + Flags<[DriverOption,CC1Option]>, + HelpText<"Allow use of CMSE (Armv8-M Security Extensions)">; 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)">; @@ -2132,7 +2173,7 @@ def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">, def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">, Group<m_aarch64_Features_Group>, HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">; -foreach i = {1-7,18,20} in +foreach i = {1-7,9-15,18,20-28} in def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_aarch64_Features_Group>, HelpText<"Reserve the "#i#" register (AArch64 only)">; @@ -2156,6 +2197,16 @@ def msign_ext : Flag<["-"], "msign-ext">, Group<m_wasm_Features_Group>; def mno_sign_ext : Flag<["-"], "mno-sign-ext">, Group<m_wasm_Features_Group>; def mexception_handing : Flag<["-"], "mexception-handling">, Group<m_wasm_Features_Group>; def mno_exception_handing : Flag<["-"], "mno-exception-handling">, Group<m_wasm_Features_Group>; +def matomics : Flag<["-"], "matomics">, Group<m_wasm_Features_Group>; +def mno_atomics : Flag<["-"], "mno-atomics">, Group<m_wasm_Features_Group>; +def mbulk_memory : Flag<["-"], "mbulk-memory">, Group<m_wasm_Features_Group>; +def mno_bulk_memory : Flag<["-"], "mno-bulk-memory">, Group<m_wasm_Features_Group>; +def mmutable_globals : Flag<["-"], "mmutable-globals">, Group<m_wasm_Features_Group>; +def mno_mutable_globals : Flag<["-"], "mno-mutable-globals">, Group<m_wasm_Features_Group>; +def mmultivalue : Flag<["-"], "mmultivalue">, Group<m_wasm_Features_Group>; +def mno_multivalue : Flag<["-"], "mno-multivalue">, Group<m_wasm_Features_Group>; +def mtail_call : Flag<["-"], "mtail-call">, Group<m_wasm_Features_Group>; +def mno_tail_call : Flag<["-"], "mno-tail-call">, Group<m_wasm_Features_Group>; def mamdgpu_debugger_abi : Joined<["-"], "mamdgpu-debugger-abi=">, Flags<[HelpHidden]>, @@ -2176,6 +2227,16 @@ def msram_ecc : Flag<["-"], "msram-ecc">, Group<m_amdgpu_Features_Group>, def mno_sram_ecc : Flag<["-"], "mno-sram-ecc">, Group<m_amdgpu_Features_Group>, HelpText<"Disable SRAM ECC (AMDGPU only)">; +def mcumode : Flag<["-"], "mcumode">, Group<m_amdgpu_Features_Group>, + HelpText<"CU wavefront execution mode is used (AMDGPU only)">; +def mno_cumode : Flag<["-"], "mno-cumode">, Group<m_amdgpu_Features_Group>, + HelpText<"WGP wavefront execution mode is used (AMDGPU only)">; + +def mwavefrontsize64 : Flag<["-"], "mwavefrontsize64">, + Group<m_Group>, HelpText<"Wavefront size 64 is used">; +def mno_wavefrontsize64 : Flag<["-"], "mno-wavefrontsize64">, + Group<m_Group>, HelpText<"Wavefront size 32 is used">; + 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>; @@ -2418,6 +2479,14 @@ def modd_spreg : Flag<["-"], "modd-spreg">, Group<m_mips_Features_Group>, def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group<m_mips_Features_Group>, HelpText<"Disable odd single-precision floating point registers">, Flags<[HelpHidden]>; +def mrelax_pic_calls : Flag<["-"], "mrelax-pic-calls">, + Group<m_mips_Features_Group>, + HelpText<"Produce relaxation hints for linkers to try optimizing PIC " + "call sequences into direct calls (MIPS only)">, Flags<[HelpHidden]>; +def mno_relax_pic_calls : Flag<["-"], "mno-relax-pic-calls">, + Group<m_mips_Features_Group>, + HelpText<"Do not produce relaxation hints for linkers to try optimizing PIC " + "call sequences into direct calls (MIPS only)">, Flags<[HelpHidden]>; def mglibc : Flag<["-"], "mglibc">, Group<m_libc_Group>, Flags<[HelpHidden]>; def muclibc : Flag<["-"], "muclibc">, Group<m_libc_Group>, Flags<[HelpHidden]>; def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>, @@ -2445,6 +2514,7 @@ def nomultidefs : Flag<["-"], "nomultidefs">; def nopie : Flag<["-"], "nopie">; def no_pie : Flag<["-"], "no-pie">, Alias<nopie>; def noprebind : Flag<["-"], "noprebind">; +def noprofilelib : Flag<["-"], "noprofilelib">; def noseglinkedit : Flag<["-"], "noseglinkedit">; def nostartfiles : Flag<["-"], "nostartfiles">; def nostdinc : Flag<["-"], "nostdinc">, Flags<[CoreOption]>; @@ -2494,6 +2564,7 @@ def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>, def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>; def p : Flag<["-"], "p">; def pie : Flag<["-"], "pie">; +def static_pie : Flag<["-"], "static-pie">; def read__only__relocs : Separate<["-"], "read_only_relocs">; def remap : Flag<["-"], "remap">; def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>, @@ -2561,6 +2632,8 @@ def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>, }]>; def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>, HelpText<"C++ standard library to use">, Values<"libc++,libstdc++,platform">; +def unwindlib_EQ : Joined<["-", "--"], "unwindlib=">, Flags<[CC1Option]>, + HelpText<"Unwind library to use">, Values<"libgcc,unwindlib,platform">; def sub__library : JoinedOrSeparate<["-"], "sub_library">; def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">; def system_header_prefix : Joined<["--"], "system-header-prefix=">, @@ -2576,6 +2649,12 @@ def : Separate<["--"], "no-system-header-prefix">, Alias<no_system_header_prefix def s : Flag<["-"], "s">, Group<Link_Group>; def target : Joined<["--"], "target=">, Flags<[DriverOption, CoreOption]>, HelpText<"Generate code for the given target">; +def print_supported_cpus : Flag<["-", "--"], "print-supported-cpus">, + Group<CompileOnly_Group>, Flags<[CC1Option, CoreOption]>, + HelpText<"Print supported cpu models for the given target (if target is not specified," + " it will print the supported cpus for the default target)">; +def mcpu_EQ_QUESTION : Flag<["-"], "mcpu=?">, Alias<print_supported_cpus>; +def mtune_EQ_QUESTION : Flag<["-"], "mtune=?">, Alias<print_supported_cpus>; def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[DriverOption]>, HelpText<"Use the gcc toolchain at the given directory">; def time : Flag<["-"], "time">, @@ -2819,6 +2898,8 @@ def mavx2 : Flag<["-"], "mavx2">, Group<m_x86_Features_Group>; def mno_avx2 : Flag<["-"], "mno-avx2">, Group<m_x86_Features_Group>; def mavx512f : Flag<["-"], "mavx512f">, Group<m_x86_Features_Group>; def mno_avx512f : Flag<["-"], "mno-avx512f">, Group<m_x86_Features_Group>; +def mavx512bf16 : Flag<["-"], "mavx512bf16">, Group<m_x86_Features_Group>; +def mno_avx512bf16 : Flag<["-"], "mno-avx512bf16">, Group<m_x86_Features_Group>; def mavx512bitalg : Flag<["-"], "mavx512bitalg">, Group<m_x86_Features_Group>; def mno_avx512bitalg : Flag<["-"], "mno-avx512bitalg">, Group<m_x86_Features_Group>; def mavx512bw : Flag<["-"], "mavx512bw">, Group<m_x86_Features_Group>; @@ -2843,6 +2924,8 @@ def mavx512vnni : Flag<["-"], "mavx512vnni">, Group<m_x86_Features_Group>; def mno_avx512vnni : Flag<["-"], "mno-avx512vnni">, Group<m_x86_Features_Group>; def mavx512vpopcntdq : Flag<["-"], "mavx512vpopcntdq">, Group<m_x86_Features_Group>; def mno_avx512vpopcntdq : Flag<["-"], "mno-avx512vpopcntdq">, Group<m_x86_Features_Group>; +def mavx512vp2intersect : Flag<["-"], "mavx512vp2intersect">, Group<m_x86_Features_Group>; +def mno_avx512vp2intersect : Flag<["-"], "mno-avx512vp2intersect">, Group<m_x86_Features_Group>; def madx : Flag<["-"], "madx">, Group<m_x86_Features_Group>; def mno_adx : Flag<["-"], "mno-adx">, Group<m_x86_Features_Group>; def maes : Flag<["-"], "maes">, Group<m_x86_Features_Group>; @@ -2863,6 +2946,8 @@ def mclzero : Flag<["-"], "mclzero">, Group<m_x86_Features_Group>; def mno_clzero : Flag<["-"], "mno-clzero">, Group<m_x86_Features_Group>; def mcx16 : Flag<["-"], "mcx16">, Group<m_x86_Features_Group>; def mno_cx16 : Flag<["-"], "mno-cx16">, Group<m_x86_Features_Group>; +def menqcmd : Flag<["-"], "menqcmd">, Group<m_x86_Features_Group>; +def mno_enqcmd : Flag<["-"], "mno-enqcmd">, Group<m_x86_Features_Group>; def mf16c : Flag<["-"], "mf16c">, Group<m_x86_Features_Group>; def mno_f16c : Flag<["-"], "mno-f16c">, Group<m_x86_Features_Group>; def mfma : Flag<["-"], "mfma">, Group<m_x86_Features_Group>; diff --git a/include/clang/Driver/Phases.h b/include/clang/Driver/Phases.h index cd6b5b5c9f05..7199c657848c 100644 --- a/include/clang/Driver/Phases.h +++ b/include/clang/Driver/Phases.h @@ -1,9 +1,8 @@ //===--- Phases.h - Transformations on Driver Types -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h index e590a49deea3..957e752b6877 100644 --- a/include/clang/Driver/SanitizerArgs.h +++ b/include/clang/Driver/SanitizerArgs.h @@ -1,9 +1,8 @@ //===--- SanitizerArgs.h - Arguments for sanitizer tools -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_DRIVER_SANITIZERARGS_H @@ -39,6 +38,8 @@ class SanitizerArgs { bool AsanPoisonCustomArrayCookie = false; bool AsanGlobalsDeadStripping = false; bool AsanUseOdrIndicator = false; + bool AsanInvalidPointerCmp = false; + bool AsanInvalidPointerSub = false; std::string HwasanAbi; bool LinkCXXRuntimes = false; bool NeedPIE = false; @@ -74,9 +75,6 @@ class SanitizerArgs { bool needsCfiRt() const; bool needsCfiDiagRt() const; bool needsStatsRt() const { return Stats; } - bool needsEsanRt() const { - return Sanitizers.hasOneOf(SanitizerKind::Efficiency); - } bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); } bool requiresPIE() const; diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h index b02ac66d3b5c..8d0491606978 100644 --- a/include/clang/Driver/Tool.h +++ b/include/clang/Driver/Tool.h @@ -1,9 +1,8 @@ //===--- Tool.h - Compilation Tools -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index d5f75b827110..7dd3db376c8c 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -1,9 +1,8 @@ //===- ToolChain.h - Collections of tools for one platform ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -100,11 +99,19 @@ public: RLT_Libgcc }; + enum UnwindLibType { + UNW_None, + UNW_CompilerRT, + UNW_Libgcc + }; + enum RTTIMode { RM_Enabled, RM_Disabled, }; + enum FileType { FT_Object, FT_Static, FT_Shared }; + private: friend class RegisterEffectiveTriple; @@ -368,15 +375,25 @@ public: return ToolChain::CST_Libstdcxx; } + virtual UnwindLibType GetDefaultUnwindLibType() const { + return ToolChain::UNW_None; + } + virtual std::string getCompilerRTPath() const; virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, - bool Shared = false) const; + FileType Type = ToolChain::FT_Static) const; - const char *getCompilerRTArgString(const llvm::opt::ArgList &Args, - StringRef Component, - bool Shared = false) const; + const char * + getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, + FileType Type = ToolChain::FT_Static) const; + + // Returns target specific runtime path if it exists. + virtual Optional<std::string> getRuntimePath() const; + + // Returns target specific C++ library path if it exists. + virtual Optional<std::string> getCXXStdlibPath() const; // Returns <ResourceDir>/lib/<OSName>/<arch>. This is used by runtimes (such // as OpenMP) to find arch-specific libraries. @@ -401,6 +418,9 @@ public: /// Test whether this toolchain defaults to PIE. virtual bool isPIEDefault() const = 0; + /// Test whether this toolchaind defaults to non-executable stacks. + virtual bool isNoExecStackDefault() const; + /// Tests whether this toolchain forces its default for PIC, PIE or /// non-PIC. If this returns true, any PIC related flags should be ignored /// and instead the results of \c isPICDefault() and \c isPIEDefault() are @@ -512,6 +532,10 @@ public: // given compilation arguments. virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const; + // GetUnwindLibType - Determine the unwind library type to use with the + // given compilation arguments. + virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const; + /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set /// the include paths to use for the given C++ standard library type. virtual void @@ -564,7 +588,9 @@ public: virtual SanitizerMask getSupportedSanitizers() const; /// Return sanitizers which are enabled by default. - virtual SanitizerMask getDefaultSanitizers() const { return 0; } + virtual SanitizerMask getDefaultSanitizers() const { + return SanitizerMask(); + } }; /// Set a ToolChain's effective triple. Reset it when the registration object diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def index c25bc4b08084..b45789d4b314 100644 --- a/include/clang/Driver/Types.def +++ b/include/clang/Driver/Types.def @@ -1,9 +1,8 @@ //===--- Types.def - Driver Type info ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -89,6 +88,7 @@ TYPE("lto-bc", LTO_BC, INVALID, "o", "") // Misc. TYPE("ast", AST, INVALID, "ast", "u") +TYPE("ifs", IFS, INVALID, "ifs", "u") TYPE("pcm", ModuleFile, INVALID, "pcm", "u") TYPE("plist", Plist, INVALID, "plist", "") TYPE("rewritten-objc", RewrittenObjC,INVALID, "cpp", "") diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h index 5bc6668a0d1d..53afada7abca 100644 --- a/include/clang/Driver/Types.h +++ b/include/clang/Driver/Types.h @@ -1,9 +1,8 @@ //===--- Types.h - Input & Temporary Driver Types ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/Util.h b/include/clang/Driver/Util.h index 07495a18508c..6788420912a1 100644 --- a/include/clang/Driver/Util.h +++ b/include/clang/Driver/Util.h @@ -1,9 +1,8 @@ //===--- Util.h - Common Driver Utilities -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/XRayArgs.h b/include/clang/Driver/XRayArgs.h index c7ca94529175..fa2583f4b966 100644 --- a/include/clang/Driver/XRayArgs.h +++ b/include/clang/Driver/XRayArgs.h @@ -1,9 +1,8 @@ //===--- 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. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_DRIVER_XRAYARGS_H diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h index d6eb6cd84f93..f6c7988e28ee 100644 --- a/include/clang/Edit/Commit.h +++ b/include/clang/Edit/Commit.h @@ -1,9 +1,8 @@ //===- Commit.h - A unit of edits -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h index 52873c3c3841..60072f6758b1 100644 --- a/include/clang/Edit/EditedSource.h +++ b/include/clang/Edit/EditedSource.h @@ -1,9 +1,8 @@ //===- EditedSource.h - Collection of source edits --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Edit/EditsReceiver.h b/include/clang/Edit/EditsReceiver.h index 1bebbeb873a7..75e731640047 100644 --- a/include/clang/Edit/EditsReceiver.h +++ b/include/clang/Edit/EditsReceiver.h @@ -1,9 +1,8 @@ //===- EditedSource.h - Collection of source edits --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Edit/FileOffset.h b/include/clang/Edit/FileOffset.h index 02c1b96b3331..b1f6176bb1b3 100644 --- a/include/clang/Edit/FileOffset.h +++ b/include/clang/Edit/FileOffset.h @@ -1,9 +1,8 @@ //===- FileOffset.h - Offset in a file --------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Edit/Rewriters.h b/include/clang/Edit/Rewriters.h index 8338d71b3e52..210f9a898423 100644 --- a/include/clang/Edit/Rewriters.h +++ b/include/clang/Edit/Rewriters.h @@ -1,9 +1,8 @@ //===--- Rewriters.h - Rewritings ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index cb37b0c890c3..6388e4fc1727 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -1,9 +1,8 @@ //===--- Format.h - Format C++ code -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -80,6 +79,19 @@ struct FormatStyle { /// brackets. BracketAlignmentStyle AlignAfterOpenBracket; + /// \brief If ``true``, aligns consecutive C/C++ preprocessor macros. + /// + /// This will align C/C++ preprocessor macros of consecutive lines. + /// Will result in formattings like + /// \code + /// #define SHORT_NAME 42 + /// #define LONGER_NAME 0x007f + /// #define EVEN_LONGER_NAME (2) + /// #define foo(x) (x * x) + /// #define bar(y, z) (y + z) + /// \endcode + bool AlignConsecutiveMacros; + /// If ``true``, aligns consecutive assignments. /// /// This will align the assignment operators of consecutive lines. This @@ -155,6 +167,38 @@ struct FormatStyle { /// \endcode bool AlignTrailingComments; + /// \brief If a function call or braced initializer list doesn't fit on a + /// line, allow putting all arguments onto the next line, even if + /// ``BinPackArguments`` is ``false``. + /// \code + /// true: + /// callFunction( + /// a, b, c, d); + /// + /// false: + /// callFunction(a, + /// b, + /// c, + /// d); + /// \endcode + bool AllowAllArgumentsOnNextLine; + + /// \brief If a constructor definition with a member initializer list doesn't + /// fit on a single line, allow putting all member initializers onto the next + /// line, if ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is true. + /// Note that this parameter has no effect if + /// ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is false. + /// \code + /// true: + /// MyClass::MyClass() : + /// member0(0), member1(2) {} + /// + /// false: + /// MyClass::MyClass() : + /// member0(0), + /// member1(2) {} + bool AllowAllConstructorInitializersOnNextLine; + /// If the function declaration doesn't fit on a line, /// allow putting all parameters of a function declaration onto /// the next line even if ``BinPackParameters`` is ``false``. @@ -242,8 +286,71 @@ struct FormatStyle { /// single line. ShortFunctionStyle AllowShortFunctionsOnASingleLine; + /// Different styles for handling short if lines + enum ShortIfStyle { + /// Never put short ifs on the same line. + /// \code + /// if (a) + /// return ; + /// else { + /// return; + /// } + /// \endcode + SIS_Never, + /// Without else put short ifs on the same line only if + /// the else is not a compound statement. + /// \code + /// if (a) return; + /// else + /// return; + /// \endcode + SIS_WithoutElse, + /// Always put short ifs on the same line if + /// the else is not a compound statement or not. + /// \code + /// if (a) return; + /// else { + /// return; + /// } + /// \endcode + SIS_Always, + }; + /// If ``true``, ``if (a) return;`` can be put on a single line. - bool AllowShortIfStatementsOnASingleLine; + ShortIfStyle AllowShortIfStatementsOnASingleLine; + + /// Different styles for merging short lambdas containing at most one + /// statement. + enum ShortLambdaStyle { + /// Never merge lambdas into a single line. + SLS_None, + /// Only merge empty lambdas. + /// \code + /// auto lambda = [](int a) {} + /// auto lambda2 = [](int a) { + /// return a; + /// }; + /// \endcode + SLS_Empty, + /// Merge lambda into a single line if argument of a function. + /// \code + /// auto lambda = [](int a) { + /// return a; + /// }; + /// sort(a.begin(), a.end(), ()[] { return x < y; }) + /// \endcode + SLS_Inline, + /// Merge all lambdas fitting on a single line. + /// \code + /// auto lambda = [](int a) {} + /// auto lambda2 = [](int a) { return a; }; + /// \endcode + SLS_All, + }; + + /// Dependent on the value, ``auto lambda []() { return 0; }`` can be put on a + /// single line. + ShortLambdaStyle AllowShortLambdasOnASingleLine; /// If ``true``, ``while (true) continue;`` can be put on a single /// line. @@ -548,19 +655,28 @@ struct FormatStyle { BS_Stroustrup, /// Always break before braces. /// \code - /// try { + /// try + /// { /// foo(); /// } - /// catch () { + /// catch () + /// { /// } /// void foo() { bar(); } - /// class foo { + /// class foo + /// { /// }; - /// if (foo()) { + /// if (foo()) + /// { /// } - /// else { + /// else + /// { /// } - /// enum X : int { A, B }; + /// enum X : int + /// { + /// A, + /// B + /// }; /// \endcode BS_Allman, /// Always break before braces and add an extra level of indentation to @@ -621,6 +737,22 @@ struct FormatStyle { /// AfterClass: true /// \endcode struct BraceWrappingFlags { + /// Wrap case labels. + /// \code + /// false: true: + /// switch (foo) { vs. switch (foo) { + /// case 1: { case 1: + /// bar(); { + /// break; bar(); + /// } break; + /// default: { } + /// plop(); default: + /// } { + /// } plop(); + /// } + /// } + /// \endcode + bool AfterCaseLabel; /// Wrap class definitions. /// \code /// true: @@ -1029,7 +1161,7 @@ struct FormatStyle { /// true: false: /// namespace a { vs. namespace a { /// foo(); foo(); - /// } // namespace a; } + /// } // namespace a } /// \endcode bool FixNamespaceComments; @@ -1050,6 +1182,22 @@ struct FormatStyle { /// For example: BOOST_FOREACH. std::vector<std::string> ForEachMacros; + /// \brief A vector of macros that should be interpreted as type declarations + /// instead of as function calls. + /// + /// These are expected to be macros of the form: + /// \code + /// STACK_OF(...) + /// \endcode + /// + /// In the .clang-format configuration file, this can be configured like: + /// \code{.yaml} + /// TypenameMacros: ['STACK_OF', 'LIST'] + /// \endcode + /// + /// For example: OpenSSL STACK_OF, BSD LIST_ENTRY. + std::vector<std::string> TypenameMacros; + /// A vector of macros that should be interpreted as complete /// statements. /// @@ -1060,6 +1208,18 @@ struct FormatStyle { /// For example: Q_UNUSED std::vector<std::string> StatementMacros; + /// A vector of macros which are used to open namespace blocks. + /// + /// These are expected to be macros of the form: + /// \code + /// NAMESPACE(<namespace-name>, ...) { + /// <namespace-content> + /// } + /// \endcode + /// + /// For example: TESTSUITE + std::vector<std::string> NamespaceMacros; + tooling::IncludeStyle IncludeStyle; /// Indent case labels one level from the switch statement. @@ -1097,7 +1257,16 @@ struct FormatStyle { /// # endif /// #endif /// \endcode - PPDIS_AfterHash + PPDIS_AfterHash, + /// Indents directives before the hash. + /// \code + /// #if FOO + /// #if BAR + /// #include <foo> + /// #endif + /// #endif + /// \endcode + PPDIS_BeforeHash }; /// The preprocessor directive indenting style to use. @@ -1131,7 +1300,7 @@ struct FormatStyle { /// A vector of prefixes ordered by the desired groups for Java imports. /// - /// Each group is seperated by a newline. Static imports will also follow the + /// Each group is separated by a newline. Static imports will also follow the /// same grouping convention above all non-static imports. One group's prefix /// can be a subset of another - the longest prefix is always matched. Within /// a group, the imports are ordered lexicographically. @@ -1220,6 +1389,8 @@ struct FormatStyle { LK_None, /// Should be used for C, C++. LK_Cpp, + /// Should be used for C#. + LK_CSharp, /// Should be used for Java. LK_Java, /// Should be used for JavaScript. @@ -1236,6 +1407,7 @@ struct FormatStyle { LK_TextProto }; bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; } + bool isCSharp() const { return Language == LK_CSharp; } /// Language, this format style is targeted at. LanguageKind Language; @@ -1522,6 +1694,13 @@ struct FormatStyle { /// \endcode bool SpaceAfterCStyleCast; + /// If ``true``, a space is inserted after the logical not operator (``!``). + /// \code + /// true: false: + /// ! someExpression(); vs. !someExpression(); + /// \endcode + bool SpaceAfterLogicalNot; + /// If \c true, a space will be inserted after the 'template' keyword. /// \code /// true: false: @@ -1584,6 +1763,17 @@ struct FormatStyle { /// } /// \endcode SBPO_ControlStatements, + /// Put a space before opening parentheses only if the parentheses are not + /// empty i.e. '()' + /// \code + /// void() { + /// if (true) { + /// f(); + /// g (x, y, z); + /// } + /// } + /// \endcode + SBPO_NonEmptyParentheses, /// Always put a space before opening parentheses, except when it's /// prohibited by the syntax rules (in function-like macro definitions) or /// when determined by other style rules (after unary operators, opening @@ -1720,6 +1910,9 @@ struct FormatStyle { AlignEscapedNewlines == R.AlignEscapedNewlines && AlignOperands == R.AlignOperands && AlignTrailingComments == R.AlignTrailingComments && + AllowAllArgumentsOnNextLine == R.AllowAllArgumentsOnNextLine && + AllowAllConstructorInitializersOnNextLine == + R.AllowAllConstructorInitializersOnNextLine && AllowAllParametersOfDeclarationOnNextLine == R.AllowAllParametersOfDeclarationOnNextLine && AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine && @@ -1729,6 +1922,7 @@ struct FormatStyle { R.AllowShortFunctionsOnASingleLine && AllowShortIfStatementsOnASingleLine == R.AllowShortIfStatementsOnASingleLine && + AllowShortLambdasOnASingleLine == R.AllowShortLambdasOnASingleLine && AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine && AlwaysBreakAfterReturnType == R.AlwaysBreakAfterReturnType && AlwaysBreakBeforeMultilineStrings == @@ -1773,6 +1967,7 @@ struct FormatStyle { MacroBlockEnd == R.MacroBlockEnd && MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep && NamespaceIndentation == R.NamespaceIndentation && + NamespaceMacros == R.NamespaceMacros && ObjCBinPackProtocolList == R.ObjCBinPackProtocolList && ObjCBlockIndentWidth == R.ObjCBlockIndentWidth && ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty && @@ -1790,6 +1985,7 @@ struct FormatStyle { PointerAlignment == R.PointerAlignment && RawStringFormats == R.RawStringFormats && SpaceAfterCStyleCast == R.SpaceAfterCStyleCast && + SpaceAfterLogicalNot == R.SpaceAfterLogicalNot && SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword && SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators && SpaceBeforeCpp11BracedList == R.SpaceBeforeCpp11BracedList && @@ -1807,7 +2003,8 @@ struct FormatStyle { SpacesInParentheses == R.SpacesInParentheses && SpacesInSquareBrackets == R.SpacesInSquareBrackets && Standard == R.Standard && TabWidth == R.TabWidth && - StatementMacros == R.StatementMacros && UseTab == R.UseTab; + StatementMacros == R.StatementMacros && UseTab == R.UseTab && + TypenameMacros == R.TypenameMacros; } llvm::Optional<FormatStyle> GetLanguageStyle(LanguageKind Language) const; @@ -1850,7 +2047,8 @@ private: /// Returns a format style complying with the LLVM coding standards: /// http://llvm.org/docs/CodingStandards.html. -FormatStyle getLLVMStyle(); +FormatStyle getLLVMStyle( + FormatStyle::LanguageKind Language = FormatStyle::LanguageKind::LK_Cpp); /// Returns a format style complying with one of Google's style guides: /// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml. @@ -2051,6 +2249,8 @@ inline StringRef getLanguageName(FormatStyle::LanguageKind Language) { switch (Language) { case FormatStyle::LK_Cpp: return "C++"; + case FormatStyle::LK_CSharp: + return "CSharp"; case FormatStyle::LK_ObjC: return "Objective-C"; case FormatStyle::LK_Java: @@ -2059,6 +2259,8 @@ inline StringRef getLanguageName(FormatStyle::LanguageKind Language) { return "JavaScript"; case FormatStyle::LK_Proto: return "Proto"; + case FormatStyle::LK_TableGen: + return "TableGen"; case FormatStyle::LK_TextProto: return "TextProto"; default: diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h index c2144da054f0..af8c4a517dcd 100644 --- a/include/clang/Frontend/ASTConsumers.h +++ b/include/clang/Frontend/ASTConsumers.h @@ -1,9 +1,8 @@ //===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,6 +13,7 @@ #ifndef LLVM_CLANG_FRONTEND_ASTCONSUMERS_H #define LLVM_CLANG_FRONTEND_ASTCONSUMERS_H +#include "clang/AST/ASTDumperUtils.h" #include "clang/Basic/LLVM.h" #include <memory> @@ -36,10 +36,10 @@ std::unique_ptr<ASTConsumer> CreateASTPrinter(std::unique_ptr<raw_ostream> OS, // AST dumper: dumps the raw AST in human-readable form to the given output // stream, or stdout if OS is nullptr. -std::unique_ptr<ASTConsumer> CreateASTDumper(std::unique_ptr<raw_ostream> OS, - StringRef FilterString, - bool DumpDecls, bool Deserialize, - bool DumpLookups); +std::unique_ptr<ASTConsumer> +CreateASTDumper(std::unique_ptr<raw_ostream> OS, StringRef FilterString, + bool DumpDecls, bool Deserialize, bool DumpLookups, + ASTDumpOutputFormat Format); // AST Decl node lister: prints qualified names of all filterable AST Decl // nodes. diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index d0b532cf2d34..7fb1d2d93380 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -1,9 +1,8 @@ //===- ASTUnit.h - ASTUnit utility ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -72,7 +71,7 @@ class FileManager; class FrontendAction; class HeaderSearch; class InputKind; -class MemoryBufferCache; +class InMemoryModuleCache; class PCHContainerOperations; class PCHContainerReader; class Preprocessor; @@ -83,6 +82,9 @@ class TargetInfo; /// \brief Enumerates the available scopes for skipping function bodies. enum class SkipFunctionBodiesScope { None, Preamble, PreambleAndMainFile }; +/// \brief Enumerates the available kinds for capturing diagnostics. +enum class CaptureDiagsKind { None, All, AllWithoutNonErrorsFromIncludes }; + /// Utility class for loading a ASTContext from an AST file. class ASTUnit { public: @@ -108,7 +110,7 @@ private: IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; IntrusiveRefCntPtr<FileManager> FileMgr; IntrusiveRefCntPtr<SourceManager> SourceMgr; - IntrusiveRefCntPtr<MemoryBufferCache> PCMCache; + IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache; std::unique_ptr<HeaderSearch> HeaderInfo; IntrusiveRefCntPtr<TargetInfo> Target; std::shared_ptr<Preprocessor> PP; @@ -145,7 +147,7 @@ private: bool OnlyLocalDecls = false; /// Whether to capture any diagnostics produced. - bool CaptureDiagnostics = false; + CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None; /// Track whether the main file was loaded from an AST or not. bool MainFileIsAST; @@ -206,7 +208,10 @@ private: /// we'll attempt to rebuild the precompiled header. This way, if /// building the precompiled preamble fails, we won't try again for /// some number of calls. - unsigned PreambleRebuildCounter = 0; + unsigned PreambleRebuildCountdown = 0; + + /// Counter indicating how often the preamble was build in total. + unsigned PreambleCounter = 0; /// Cache pairs "filename - source location" /// @@ -248,7 +253,7 @@ private: bool UserFilesAreVolatile : 1; static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - ASTUnit &AST, bool CaptureDiagnostics); + ASTUnit &AST, CaptureDiagsKind CaptureDiagnostics); void TranslateStoredDiagnostics(FileManager &FileMgr, SourceManager &SrcMan, @@ -575,6 +580,8 @@ public: mapLocationToPreamble(R.getEnd())); } + unsigned getPreambleCounterForTests() const { return PreambleCounter; } + // Retrieve the diagnostics associated with this AST using stored_diag_iterator = StoredDiagnostic *; using stored_diag_const_iterator = const StoredDiagnostic *; @@ -657,8 +664,8 @@ public: /// Create a ASTUnit. Gets ownership of the passed CompilerInvocation. static std::unique_ptr<ASTUnit> create(std::shared_ptr<CompilerInvocation> CI, - IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool CaptureDiagnostics, - bool UserFilesAreVolatile); + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + CaptureDiagsKind CaptureDiagnostics, bool UserFilesAreVolatile); enum WhatToLoad { /// Load options and the preprocessor state. @@ -686,7 +693,8 @@ public: WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, const FileSystemOptions &FileSystemOpts, bool UseDebugInfo = false, bool OnlyLocalDecls = false, ArrayRef<RemappedFile> RemappedFiles = None, - bool CaptureDiagnostics = false, bool AllowPCHWithCompilerErrors = false, + CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, + bool AllowPCHWithCompilerErrors = false, bool UserFilesAreVolatile = false); private: @@ -744,7 +752,8 @@ public: IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FrontendAction *Action = nullptr, ASTUnit *Unit = nullptr, bool Persistent = true, StringRef ResourceFilesPath = StringRef(), - bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, + bool OnlyLocalDecls = false, + CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, unsigned PrecompilePreambleAfterNParses = 0, bool CacheCodeCompletionResults = false, bool IncludeBriefCommentsInCodeCompletion = false, @@ -769,7 +778,8 @@ public: std::shared_ptr<CompilerInvocation> CI, std::shared_ptr<PCHContainerOperations> PCHContainerOps, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr, - bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, + bool OnlyLocalDecls = false, + CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, unsigned PrecompilePreambleAfterNParses = 0, TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, @@ -809,7 +819,8 @@ public: const char **ArgBegin, const char **ArgEnd, std::shared_ptr<PCHContainerOperations> PCHContainerOps, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath, - bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, + bool OnlyLocalDecls = false, + CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, ArrayRef<RemappedFile> RemappedFiles = None, bool RemappedFilesKeepOriginalName = true, unsigned PrecompilePreambleAfterNParses = 0, diff --git a/include/clang/Frontend/ChainedDiagnosticConsumer.h b/include/clang/Frontend/ChainedDiagnosticConsumer.h index 04c6077dc35e..ca284560754f 100644 --- a/include/clang/Frontend/ChainedDiagnosticConsumer.h +++ b/include/clang/Frontend/ChainedDiagnosticConsumer.h @@ -1,9 +1,8 @@ //===- ChainedDiagnosticConsumer.h - Chain Diagnostic Clients ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h index 7ae98e079264..e95d100f6a76 100644 --- a/include/clang/Frontend/CommandLineSourceLoc.h +++ b/include/clang/Frontend/CommandLineSourceLoc.h @@ -1,10 +1,9 @@ //===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 83ce079d5e23..eb49c53ff40b 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -1,9 +1,8 @@ //===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -45,7 +44,7 @@ class ExternalASTSource; class FileEntry; class FileManager; class FrontendAction; -class MemoryBufferCache; +class InMemoryModuleCache; class Module; class Preprocessor; class Sema; @@ -83,9 +82,6 @@ class CompilerInstance : public ModuleLoader { /// Auxiliary Target info. IntrusiveRefCntPtr<TargetInfo> AuxTarget; - /// The virtual file system. - IntrusiveRefCntPtr<llvm::vfs::FileSystem> VirtualFileSystem; - /// The file manager. IntrusiveRefCntPtr<FileManager> FileMgr; @@ -93,7 +89,7 @@ class CompilerInstance : public ModuleLoader { IntrusiveRefCntPtr<SourceManager> SourceMgr; /// The cache of PCM files. - IntrusiveRefCntPtr<MemoryBufferCache> PCMCache; + IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache; /// The preprocessor. std::shared_ptr<Preprocessor> PP; @@ -128,9 +124,6 @@ class CompilerInstance : public ModuleLoader { /// The module provider. std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations; - /// The dependency file generator. - std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator; - std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors; /// The set of top-level modules that has already been loaded, @@ -193,7 +186,7 @@ public: explicit CompilerInstance( std::shared_ptr<PCHContainerOperations> PCHContainerOps = std::make_shared<PCHContainerOperations>(), - MemoryBufferCache *SharedPCMCache = nullptr); + InMemoryModuleCache *SharedModuleCache = nullptr); ~CompilerInstance() override; /// @name High-Level Operations @@ -383,20 +376,8 @@ public: /// @name Virtual File System /// { - bool hasVirtualFileSystem() const { return VirtualFileSystem != nullptr; } - llvm::vfs::FileSystem &getVirtualFileSystem() const { - assert(hasVirtualFileSystem() && - "Compiler instance has no virtual file system"); - return *VirtualFileSystem; - } - - /// Replace the current virtual file system. - /// - /// \note Most clients should use setFileManager, which will implicitly reset - /// the virtual file system to the one contained in the file manager. - void setVirtualFileSystem(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) { - VirtualFileSystem = std::move(FS); + return getFileManager().getVirtualFileSystem(); } /// } @@ -646,7 +627,8 @@ public: /// Create the file manager and replace any existing one with it. /// /// \return The new file manager on success, or null on failure. - FileManager *createFileManager(); + FileManager * + createFileManager(IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); /// Create the source manager and replace any existing one with it. void createSourceManager(FileManager &FileMgr); @@ -672,10 +654,10 @@ public: /// \return - The new object on success, or null on failure. static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource( StringRef Path, StringRef Sysroot, bool DisablePCHValidation, - bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, + bool AllowPCHWithCompilerErrors, Preprocessor &PP, + InMemoryModuleCache &ModuleCache, 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); @@ -814,7 +796,7 @@ public: void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS); - MemoryBufferCache &getPCMCache() const { return *PCMCache; } + InMemoryModuleCache &getModuleCache() const { return *ModuleCache; } }; } // end namespace clang diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h index a1874655b040..413134be4cef 100644 --- a/include/clang/Frontend/CompilerInvocation.h +++ b/include/clang/Frontend/CompilerInvocation.h @@ -1,9 +1,8 @@ //===- CompilerInvocation.h - Compiler Invocation Helper Data ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h index f419d2643649..7a4f3337936f 100644 --- a/include/clang/Frontend/DependencyOutputOptions.h +++ b/include/clang/Frontend/DependencyOutputOptions.h @@ -1,9 +1,8 @@ //===--- DependencyOutputOptions.h ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h index 3bbf37946d0b..b939ebe979e7 100644 --- a/include/clang/Frontend/DiagnosticRenderer.h +++ b/include/clang/Frontend/DiagnosticRenderer.h @@ -1,9 +1,8 @@ //===- DiagnosticRenderer.h - Diagnostic Pretty-Printing --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h index 22314386e060..e994e24cf5af 100644 --- a/include/clang/Frontend/FrontendAction.h +++ b/include/clang/Frontend/FrontendAction.h @@ -1,9 +1,8 @@ //===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -24,6 +23,7 @@ #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/FrontendOptions.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" #include <memory> #include <string> #include <vector> @@ -230,7 +230,7 @@ public: bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input); /// Set the source manager's main input file, and run the action. - bool Execute(); + llvm::Error Execute(); /// Perform any per-file post processing, deallocate per-file /// objects, and run statistics and output file cleanup code. @@ -305,6 +305,7 @@ class WrapperFrontendAction : public FrontendAction { std::unique_ptr<FrontendAction> WrappedAction; protected: + bool PrepareToExecuteAction(CompilerInstance &CI) override; std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override; bool BeginInvocation(CompilerInstance &CI) override; diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h index eb1cd688429d..6c7bc6046f33 100644 --- a/include/clang/Frontend/FrontendActions.h +++ b/include/clang/Frontend/FrontendActions.h @@ -1,9 +1,8 @@ //===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -75,12 +74,6 @@ protected: StringRef InFile) override; }; -class DeclContextPrintAction : public ASTFrontendAction { -protected: - std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override; -}; - class GeneratePCHAction : public ASTFrontendAction { protected: std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, @@ -126,6 +119,26 @@ protected: bool hasASTFileSupport() const override { return false; } }; +class GenerateInterfaceStubAction : public ASTFrontendAction { +protected: + TranslationUnitKind getTranslationUnitKind() override { return TU_Module; } + + bool hasASTFileSupport() const override { return false; } +}; + +// Support different interface stub formats this way: +class GenerateInterfaceYAMLExpV1Action : public GenerateInterfaceStubAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + +class GenerateInterfaceTBEExpV1Action : public GenerateInterfaceStubAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + class GenerateModuleFromModuleMapAction : public GenerateModuleAction { private: bool BeginSourceFileAction(CompilerInstance &CI) override; @@ -247,6 +260,17 @@ protected: bool usesPreprocessorOnly() const override { return true; } }; +class PrintDependencyDirectivesSourceMinimizerAction : public FrontendAction { +protected: + void ExecuteAction() override; + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &, + StringRef) override { + return nullptr; + } + + bool usesPreprocessorOnly() const override { return true; } +}; + //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/FrontendDiagnostic.h b/include/clang/Frontend/FrontendDiagnostic.h index 14a28845d45a..f41504d8026d 100644 --- a/include/clang/Frontend/FrontendDiagnostic.h +++ b/include/clang/Frontend/FrontendDiagnostic.h @@ -1,9 +1,8 @@ //===--- DiagnosticFrontend.h - Diagnostics for frontend --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 92191ebd12a6..a0acb1f066f2 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -1,15 +1,15 @@ //===- FrontendOptions.h ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H #define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H +#include "clang/AST/ASTDumperUtils.h" #include "clang/Frontend/CommandLineSourceLoc.h" #include "clang/Serialization/ModuleFileExtension.h" #include "clang/Sema/CodeCompleteOptions.h" @@ -88,6 +88,10 @@ enum ActionKind { /// Generate pre-compiled header. GeneratePCH, + /// Generate Interface Stub Files. + GenerateInterfaceYAMLExpV1, + GenerateInterfaceTBEExpV1, + /// Only execute frontend initialization. InitOnly, @@ -128,7 +132,10 @@ enum ActionKind { MigrateSource, /// Just lex, no output. - RunPreprocessorOnly + RunPreprocessorOnly, + + /// Print the output of the dependency directives source minimizer. + PrintDependencyDirectivesSourceMinimizerOutput }; } // namespace frontend @@ -203,7 +210,7 @@ class FrontendInputFile { /// The input, if it comes from a buffer rather than a file. This object /// does not own the buffer, and the caller is responsible for ensuring /// that it outlives any users. - llvm::MemoryBuffer *Buffer = nullptr; + const llvm::MemoryBuffer *Buffer = nullptr; /// The kind of input, e.g., C source, AST file, LLVM IR. InputKind Kind; @@ -215,7 +222,7 @@ public: FrontendInputFile() = default; FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false) : File(File.str()), Kind(Kind), IsSystem(IsSystem) {} - FrontendInputFile(llvm::MemoryBuffer *Buffer, InputKind Kind, + FrontendInputFile(const llvm::MemoryBuffer *Buffer, InputKind Kind, bool IsSystem = false) : Buffer(Buffer), Kind(Kind), IsSystem(IsSystem) {} @@ -232,7 +239,7 @@ public: return File; } - llvm::MemoryBuffer *getBuffer() const { + const llvm::MemoryBuffer *getBuffer() const { assert(isBuffer()); return Buffer; } @@ -257,6 +264,12 @@ public: /// Show timers for individual actions. unsigned ShowTimers : 1; + /// print the supported cpus for the current target + unsigned PrintSupportedCPUs : 1; + + /// Output time trace profile. + unsigned TimeTrace : 1; + /// Show the -version text. unsigned ShowVersion : 1; @@ -305,6 +318,9 @@ public: CodeCompleteOptions CodeCompleteOpts; + /// Specifies the output format of the AST. + ASTDumpOutputFormat ASTDumpFormat = ADOF_Default; + enum { ARCMT_None, ARCMT_Check, @@ -438,13 +454,14 @@ public: public: FrontendOptions() : DisableFree(false), RelocatablePCH(false), ShowHelp(false), - ShowStats(false), ShowTimers(false), ShowVersion(false), - FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false), - FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false), - SkipFunctionBodies(false), UseGlobalModuleIndex(true), - GenerateGlobalModuleIndex(true), ASTDumpDecls(false), - ASTDumpLookups(false), BuildingImplicitModule(false), - ModulesEmbedAllFiles(false), IncludeTimestamps(true) {} + ShowStats(false), ShowTimers(false), TimeTrace(false), + ShowVersion(false), FixWhatYouCan(false), FixOnlyWarnings(false), + FixAndRecompile(false), FixToTemporaries(false), + ARCMTMigrateEmitARCErrors(false), SkipFunctionBodies(false), + UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true), + ASTDumpDecls(false), ASTDumpLookups(false), + BuildingImplicitModule(false), ModulesEmbedAllFiles(false), + IncludeTimestamps(true) {} /// getInputKindForExtension - Return the appropriate input kind for a file /// extension. For example, "c" would return InputKind::C. diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h index 9a85e89d905d..810578534acb 100644 --- a/include/clang/Frontend/FrontendPluginRegistry.h +++ b/include/clang/Frontend/FrontendPluginRegistry.h @@ -1,9 +1,8 @@ //===- FrontendPluginRegistry.h ---------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h index 83e452d884b6..244f14c793de 100644 --- a/include/clang/Frontend/LangStandard.h +++ b/include/clang/Frontend/LangStandard.h @@ -1,9 +1,8 @@ //===--- LangStandard.h -----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -23,16 +22,17 @@ enum LangFeatures { C99 = (1 << 1), C11 = (1 << 2), C17 = (1 << 3), - CPlusPlus = (1 << 4), - CPlusPlus11 = (1 << 5), - CPlusPlus14 = (1 << 6), - CPlusPlus17 = (1 << 7), - CPlusPlus2a = (1 << 8), - Digraphs = (1 << 9), - GNUMode = (1 << 10), - HexFloat = (1 << 11), - ImplicitInt = (1 << 12), - OpenCL = (1 << 13) + C2x = (1 << 4), + CPlusPlus = (1 << 5), + CPlusPlus11 = (1 << 6), + CPlusPlus14 = (1 << 7), + CPlusPlus17 = (1 << 8), + CPlusPlus2a = (1 << 9), + Digraphs = (1 << 10), + GNUMode = (1 << 11), + HexFloat = (1 << 12), + ImplicitInt = (1 << 13), + OpenCL = (1 << 14) }; } @@ -74,6 +74,9 @@ public: /// isC17 - Language is a superset of C17. bool isC17() const { return Flags & frontend::C17; } + /// isC2x - Language is a superset of C2x. + bool isC2x() const { return Flags & frontend::C2x; } + /// isCPlusPlus - Language is a C++ variant. bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; } diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def index 0fdd35f32034..0964e9b90a03 100644 --- a/include/clang/Frontend/LangStandards.def +++ b/include/clang/Frontend/LangStandards.def @@ -1,9 +1,8 @@ //===-- LangStandards.def - Language Standard Data --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -89,6 +88,14 @@ LANGSTANDARD(gnu17, "gnu17", LineComment | C99 | C11 | C17 | Digraphs | GNUMode | HexFloat) LANGSTANDARD_ALIAS(gnu17, "gnu18") +// C2x modes +LANGSTANDARD(c2x, "c2x", + C, "Working Draft for ISO C2x", + LineComment | C99 | C11 | C17 | C2x | Digraphs | HexFloat) +LANGSTANDARD(gnu2x, "gnu2x", + C, "Working Draft for ISO C2x with GNU extensions", + LineComment | C99 | C11 | C17 | C2x | Digraphs | GNUMode | HexFloat) + // C++ modes LANGSTANDARD(cxx98, "c++98", CXX, "ISO C++ 1998 with amendments", @@ -159,8 +166,9 @@ LANGSTANDARD(opencl20, "cl2.0", OpenCL, "OpenCL 2.0", LineComment | C99 | Digraphs | HexFloat | OpenCL) LANGSTANDARD(openclcpp, "c++", - OpenCL, "OpenCL C++ 1.0", - LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs | OpenCL) + OpenCL, "C++ for OpenCL", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 | + Digraphs | HexFloat | OpenCL) LANGSTANDARD_ALIAS_DEPR(opencl10, "CL") LANGSTANDARD_ALIAS_DEPR(opencl11, "CL1.1") diff --git a/include/clang/Frontend/LayoutOverrideSource.h b/include/clang/Frontend/LayoutOverrideSource.h index 28e3cf005b30..ea1611470a76 100644 --- a/include/clang/Frontend/LayoutOverrideSource.h +++ b/include/clang/Frontend/LayoutOverrideSource.h @@ -1,9 +1,8 @@ //===--- LayoutOverrideSource.h --Override Record Layouts -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h index 3286ecf2cdd3..4816275cdc60 100644 --- a/include/clang/Frontend/LogDiagnosticPrinter.h +++ b/include/clang/Frontend/LogDiagnosticPrinter.h @@ -1,9 +1,8 @@ //===--- LogDiagnosticPrinter.h - Log Diagnostic Client ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/MigratorOptions.h b/include/clang/Frontend/MigratorOptions.h index 8eb71b13f885..cf50ffcf0c4f 100644 --- a/include/clang/Frontend/MigratorOptions.h +++ b/include/clang/Frontend/MigratorOptions.h @@ -1,9 +1,8 @@ //===--- MigratorOptions.h - MigratorOptions Options ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h index 214fefb219cd..ca6ed8310ae9 100644 --- a/include/clang/Frontend/MultiplexConsumer.h +++ b/include/clang/Frontend/MultiplexConsumer.h @@ -1,9 +1,8 @@ //===-- MultiplexConsumer.h - AST Consumer for PCH Generation ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Frontend/PCHContainerOperations.h b/include/clang/Frontend/PCHContainerOperations.h index 675efbaf56eb..fa977a63f32e 100644 --- a/include/clang/Frontend/PCHContainerOperations.h +++ b/include/clang/Frontend/PCHContainerOperations.h @@ -1,9 +1,8 @@ //===--- Frontend/PCHContainerOperations.h - PCH Containers -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/PrecompiledPreamble.h b/include/clang/Frontend/PrecompiledPreamble.h index 6c79895ce1b9..1a8a64951ec4 100644 --- a/include/clang/Frontend/PrecompiledPreamble.h +++ b/include/clang/Frontend/PrecompiledPreamble.h @@ -1,9 +1,8 @@ //===--- PrecompiledPreamble.h - Build precompiled preambles ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -284,13 +283,16 @@ public: /// Creates wrapper class for PPCallbacks so we can also process information /// about includes that are inside of a preamble virtual std::unique_ptr<PPCallbacks> createPPCallbacks(); + /// The returned CommentHandler will be added to the preprocessor if not null. + virtual CommentHandler *getCommentHandler(); }; enum class BuildPreambleError { CouldntCreateTempFile = 1, CouldntCreateTargetInfo, BeginSourceFileFailed, - CouldntEmitPCH + CouldntEmitPCH, + BadInputs }; class BuildPreambleErrorCategory final : public std::error_category { diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h index 94afcd06a398..72e5ad1137fb 100644 --- a/include/clang/Frontend/PreprocessorOutputOptions.h +++ b/include/clang/Frontend/PreprocessorOutputOptions.h @@ -1,9 +1,8 @@ //===--- PreprocessorOutputOptions.h ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h index dc68c32fb15a..58954dc6bafa 100644 --- a/include/clang/Frontend/SerializedDiagnosticPrinter.h +++ b/include/clang/Frontend/SerializedDiagnosticPrinter.h @@ -1,9 +1,8 @@ //===--- SerializedDiagnosticPrinter.h - Diagnostics serializer -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -12,7 +11,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Frontend/SerializedDiagnostics.h" -#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitstream/BitstreamWriter.h" namespace llvm { class raw_ostream; diff --git a/include/clang/Frontend/SerializedDiagnosticReader.h b/include/clang/Frontend/SerializedDiagnosticReader.h index 595bdf1f4d7a..309e0abb1461 100644 --- a/include/clang/Frontend/SerializedDiagnosticReader.h +++ b/include/clang/Frontend/SerializedDiagnosticReader.h @@ -1,9 +1,8 @@ //===- SerializedDiagnosticReader.h - Reads diagnostics ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -11,7 +10,7 @@ #define LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H #include "clang/Basic/LLVM.h" -#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitstream/BitstreamReader.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorOr.h" #include <system_error> diff --git a/include/clang/Frontend/SerializedDiagnostics.h b/include/clang/Frontend/SerializedDiagnostics.h index dacbc678b700..4e67fd13ac5b 100644 --- a/include/clang/Frontend/SerializedDiagnostics.h +++ b/include/clang/Frontend/SerializedDiagnostics.h @@ -1,16 +1,15 @@ //===--- SerializedDiagnostics.h - Common data for serialized diagnostics -===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_ #define LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_ -#include "llvm/Bitcode/BitCodes.h" +#include "llvm/Bitstream/BitCodes.h" namespace clang { namespace serialized_diags { diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h index 9f33b866a1eb..7cf54839afbe 100644 --- a/include/clang/Frontend/TextDiagnostic.h +++ b/include/clang/Frontend/TextDiagnostic.h @@ -1,9 +1,8 @@ //===--- TextDiagnostic.h - Text Diagnostic Pretty-Printing -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h index 2295f9dbf3bf..5945caf89743 100644 --- a/include/clang/Frontend/TextDiagnosticBuffer.h +++ b/include/clang/Frontend/TextDiagnosticBuffer.h @@ -1,9 +1,8 @@ //===- TextDiagnosticBuffer.h - Buffer Text Diagnostics ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h index 3cb4e02edf0d..ba756fa18c30 100644 --- a/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/include/clang/Frontend/TextDiagnosticPrinter.h @@ -1,9 +1,8 @@ //===--- TextDiagnosticPrinter.h - Text Diagnostic Client -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index 89a6b90f293f..74e563218c31 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -1,9 +1,8 @@ //===- Utils.h - Misc utilities for the front-end ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -16,6 +15,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LLVM.h" +#include "clang/Frontend/DependencyOutputOptions.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringMap.h" @@ -47,7 +47,6 @@ namespace clang { class ASTReader; class CompilerInstance; class CompilerInvocation; -class DependencyOutputOptions; class DiagnosticsEngine; class ExternalSemaSource; class FrontendOptions; @@ -78,8 +77,7 @@ void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, /// An interface for collecting the dependencies of a compilation. Users should /// use \c attachToPreprocessor and \c attachToASTReader to get all of the /// dependencies. -/// FIXME: Migrate DependencyFileGen and DependencyGraphGen to use this -/// interface. +/// FIXME: Migrate DependencyGraphGen to use this interface. class DependencyCollector { public: virtual ~DependencyCollector(); @@ -96,7 +94,7 @@ public: bool IsSystem, bool IsModuleFile, bool IsMissing); /// Called when the end of the main file is reached. - virtual void finishedMainFile() {} + virtual void finishedMainFile(DiagnosticsEngine &Diags) {} /// Return true if system files should be passed to sawDependency(). virtual bool needSystemDependencies() { return false; } @@ -107,25 +105,48 @@ public: void maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing); +protected: + /// Return true if the filename was added to the list of dependencies, false + /// otherwise. + bool addDependency(StringRef Filename); + private: llvm::StringSet<> Seen; std::vector<std::string> Dependencies; }; -/// Builds a depdenency file when attached to a Preprocessor (for includes) and +/// Builds a dependency file when attached to a Preprocessor (for includes) and /// ASTReader (for module imports), and writes it out at the end of processing /// a source file. Users should attach to the ast reader whenever a module is /// loaded. -class DependencyFileGenerator { - void *Impl; // Opaque implementation +class DependencyFileGenerator : public DependencyCollector { +public: + DependencyFileGenerator(const DependencyOutputOptions &Opts); - DependencyFileGenerator(void *Impl); + void attachToPreprocessor(Preprocessor &PP) override; -public: - static DependencyFileGenerator *CreateAndAttachToPreprocessor( - Preprocessor &PP, const DependencyOutputOptions &Opts); + void finishedMainFile(DiagnosticsEngine &Diags) override; - void AttachToASTReader(ASTReader &R); + bool needSystemDependencies() final override { return IncludeSystemHeaders; } + + bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem, + bool IsModuleFile, bool IsMissing) final override; + +protected: + void outputDependencyFile(llvm::raw_ostream &OS); + +private: + void outputDependencyFile(DiagnosticsEngine &Diags); + + std::string OutputFile; + std::vector<std::string> Targets; + bool IncludeSystemHeaders; + bool PhonyTarget; + bool AddMissingHeaderDeps; + bool SeenMissingHeader; + bool IncludeModuleFiles; + DependencyOutputFormat OutputFormat; + unsigned InputFileIndex; }; /// Collects the dependencies for imported modules into a directory. Users @@ -146,18 +167,18 @@ public: ~ModuleDependencyCollector() override { writeFileMap(); } StringRef getDest() { return DestDir; } - bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; } - void addFile(StringRef Filename, StringRef FileDst = {}); + virtual bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; } + virtual void addFile(StringRef Filename, StringRef FileDst = {}); - void addFileMapping(StringRef VPath, StringRef RPath) { + virtual void addFileMapping(StringRef VPath, StringRef RPath) { VFSWriter.addFileMapping(VPath, RPath); } void attachToPreprocessor(Preprocessor &PP) override; void attachToASTReader(ASTReader &R) override; - void writeFileMap(); - bool hasErrors() { return HasErrors; } + virtual void writeFileMap(); + virtual bool hasErrors() { return HasErrors; } }; /// AttachDependencyGraphGen - Create a dependency graph generator, and attach diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h index f36970f1eb39..965a14410832 100644 --- a/include/clang/Frontend/VerifyDiagnosticConsumer.h +++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h @@ -1,9 +1,8 @@ //===- VerifyDiagnosticConsumer.h - Verifying Diagnostic Client -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -34,7 +33,33 @@ class TextDiagnosticBuffer; /// markers in the input source to check that all the emitted diagnostics match /// those expected. /// -/// USING THE DIAGNOSTIC CHECKER: +/// INVOKING THE DIAGNOSTIC CHECKER: +/// +/// VerifyDiagnosticConsumer is typically invoked via the "-verify" option to +/// "clang -cc1". "-verify" is equivalent to "-verify=expected", so all +/// diagnostics are typically specified with the prefix "expected". For +/// example: +/// +/// \code +/// int A = B; // expected-error {{use of undeclared identifier 'B'}} +/// \endcode +/// +/// Custom prefixes can be specified as a comma-separated sequence. Each +/// prefix must start with a letter and contain only alphanumeric characters, +/// hyphens, and underscores. For example, given just "-verify=foo,bar", +/// the above diagnostic would be ignored, but the following diagnostics would +/// be recognized: +/// +/// \code +/// int A = B; // foo-error {{use of undeclared identifier 'B'}} +/// int C = D; // bar-error {{use of undeclared identifier 'D'}} +/// \endcode +/// +/// Multiple occurrences accumulate prefixes. For example, +/// "-verify -verify=foo,bar -verify=baz" is equivalent to +/// "-verify=expected,foo,bar,baz". +/// +/// SPECIFYING DIAGNOSTICS: /// /// Indicating that a line expects an error or a warning is simple. Put a /// comment on the line that has the diagnostic, use: @@ -82,6 +107,19 @@ class TextDiagnosticBuffer; /// the included file is, for example, a system header where the actual line /// number may change and is not critical). /// +/// As an alternative to specifying a fixed line number, the location of a +/// diagnostic can instead be indicated by a marker of the form "#<marker>". +/// Markers are specified by including them in a comment, and then referenced +/// by appending the marker to the diagnostic with "@#<marker>": +/// +/// \code +/// #warning some text // #1 +/// // expected-warning@#1 {{some text}} +/// \endcode +/// +/// The name of a marker used in a directive must be unique within the +/// compilation. +/// /// The simple syntax above allows each specification to match exactly one /// error. You can use the extended syntax to customize this. The extended /// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of @@ -213,11 +251,14 @@ public: HasOtherExpectedDirectives }; + class MarkerTracker; + private: DiagnosticsEngine &Diags; DiagnosticConsumer *PrimaryClient; std::unique_ptr<DiagnosticConsumer> PrimaryClientOwner; std::unique_ptr<TextDiagnosticBuffer> Buffer; + std::unique_ptr<MarkerTracker> Markers; const Preprocessor *CurrentPreprocessor = nullptr; const LangOptions *LangOpts = nullptr; SourceManager *SrcManager = nullptr; diff --git a/include/clang/FrontendTool/Utils.h b/include/clang/FrontendTool/Utils.h index 2e6b7b5076bb..22ddec041333 100644 --- a/include/clang/FrontendTool/Utils.h +++ b/include/clang/FrontendTool/Utils.h @@ -1,9 +1,8 @@ //===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Index/CodegenNameGenerator.h b/include/clang/Index/CodegenNameGenerator.h index e8dc196a204d..98b3a5de817a 100644 --- a/include/clang/Index/CodegenNameGenerator.h +++ b/include/clang/Index/CodegenNameGenerator.h @@ -1,9 +1,8 @@ //===- CodegenNameGenerator.h - Codegen name generation -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,6 +13,7 @@ #ifndef LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H #define LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H +#include "clang/AST/Mangle.h" #include "clang/Basic/LLVM.h" #include <memory> #include <string> @@ -43,7 +43,7 @@ public: private: struct Implementation; - std::unique_ptr<Implementation> Impl; + std::unique_ptr<ASTNameGenerator> Impl; }; } // namespace index diff --git a/include/clang/Index/CommentToXML.h b/include/clang/Index/CommentToXML.h index 04f9501288ba..66b8650c5efb 100644 --- a/include/clang/Index/CommentToXML.h +++ b/include/clang/Index/CommentToXML.h @@ -1,9 +1,8 @@ //===--- CommentToXML.h - Convert comments to XML representation ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Index/DeclOccurrence.h b/include/clang/Index/DeclOccurrence.h new file mode 100644 index 000000000000..16f03a84579e --- /dev/null +++ b/include/clang/Index/DeclOccurrence.h @@ -0,0 +1,41 @@ +//===- DeclOccurrence.h - An occurrence of a decl within a file -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_DECLOCCURRENCE_H +#define LLVM_CLANG_INDEX_DECLOCCURRENCE_H + +#include "clang/Basic/LLVM.h" +#include "clang/Index/IndexSymbol.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" + +namespace clang { +class Decl; + +namespace index { + +struct DeclOccurrence { + SymbolRoleSet Roles; + unsigned Offset; + const Decl *Dcl; + SmallVector<SymbolRelation, 3> Relations; + + DeclOccurrence(SymbolRoleSet R, unsigned Offset, const Decl *D, + ArrayRef<SymbolRelation> Relations) + : Roles(R), Offset(Offset), Dcl(D), + Relations(Relations.begin(), Relations.end()) {} + + friend bool operator<(const DeclOccurrence &LHS, const DeclOccurrence &RHS) { + return LHS.Offset < RHS.Offset; + } +}; + +} // namespace index +} // namespace clang + +#endif // LLVM_CLANG_INDEX_DECLOCCURRENCE_H diff --git a/include/clang/Index/IndexDataConsumer.h b/include/clang/Index/IndexDataConsumer.h index c79f6be3e13b..bc1d86696df9 100644 --- a/include/clang/Index/IndexDataConsumer.h +++ b/include/clang/Index/IndexDataConsumer.h @@ -1,9 +1,8 @@ //===--- IndexDataConsumer.h - Abstract index data consumer -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h index 8aaaa695456c..2e1e6005d68a 100644 --- a/include/clang/Index/IndexSymbol.h +++ b/include/clang/Index/IndexSymbol.h @@ -1,9 +1,8 @@ //===- IndexSymbol.h - Types and functions for indexing symbols -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -119,8 +118,12 @@ enum class SymbolRole : uint32_t { RelationContainedBy = 1 << 17, RelationIBTypeOf = 1 << 18, RelationSpecializationOf = 1 << 19, + + // Symbol only references the name of the object as written. For example, a + // constructor references the class declaration using that role. + NameReference = 1 << 20, }; -static const unsigned SymbolRoleBitNum = 20; +static const unsigned SymbolRoleBitNum = 21; typedef unsigned SymbolRoleSet; /// Represents a relation to another symbol for a symbol occurrence. diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h index 63e38975ce16..9756f3c539e6 100644 --- a/include/clang/Index/IndexingAction.h +++ b/include/clang/Index/IndexingAction.h @@ -1,9 +1,8 @@ //===--- IndexingAction.h - Frontend index action ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -45,6 +44,9 @@ struct IndexingOptions { // callback is not available (e.g. after parsing has finished). Note that // macro references are not available in Proprocessor. bool IndexMacrosInPreprocessor = false; + // Has no effect if IndexFunctionLocals are false. + bool IndexParametersInDeclarations = false; + bool IndexTemplateParameters = false; }; /// Creates a frontend action that indexes all symbols (macros and AST decls). diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h index f1389ecc9593..f89fc5cf4930 100644 --- a/include/clang/Index/USRGeneration.h +++ b/include/clang/Index/USRGeneration.h @@ -1,9 +1,8 @@ //===- USRGeneration.h - Routines for USR generation ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Lex/CodeCompletionHandler.h b/include/clang/Lex/CodeCompletionHandler.h index bef804beed00..bd3e05a36bb3 100644 --- a/include/clang/Lex/CodeCompletionHandler.h +++ b/include/clang/Lex/CodeCompletionHandler.h @@ -1,9 +1,8 @@ //===--- CodeCompletionHandler.h - Preprocessor code completion -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/DependencyDirectivesSourceMinimizer.h b/include/clang/Lex/DependencyDirectivesSourceMinimizer.h new file mode 100644 index 000000000000..41641078afe4 --- /dev/null +++ b/include/clang/Lex/DependencyDirectivesSourceMinimizer.h @@ -0,0 +1,88 @@ +//===- clang/Lex/DependencyDirectivesSourceMinimizer.h - ----------*- C++ -*-// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This is the interface for minimizing header and source files to the +/// minimum necessary preprocessor directives for evaluating includes. It +/// reduces the source down to #define, #include, #import, @import, and any +/// conditional preprocessor logic that contains one of those. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LEX_DEPENDENCY_DIRECTIVES_SOURCE_MINIMIZER_H +#define LLVM_CLANG_LEX_DEPENDENCY_DIRECTIVES_SOURCE_MINIMIZER_H + +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { + +class DiagnosticsEngine; + +namespace minimize_source_to_dependency_directives { + +/// Represents the kind of preprocessor directive or a module declaration that +/// is tracked by the source minimizer in its token output. +enum TokenKind { + pp_none, + pp_include, + pp___include_macros, + pp_define, + pp_undef, + pp_import, + pp_pragma_import, + pp_include_next, + pp_if, + pp_ifdef, + pp_ifndef, + pp_elif, + pp_else, + pp_endif, + decl_at_import, + pp_eof, +}; + +/// Represents a simplified token that's lexed as part of the source +/// minimization. It's used to track the location of various preprocessor +/// directives that could potentially have an effect on the depedencies. +struct Token { + /// The kind of token. + TokenKind K = pp_none; + + /// Offset into the output byte stream of where the directive begins. + int Offset = -1; + + Token(TokenKind K, int Offset) : K(K), Offset(Offset) {} +}; + +} // end namespace minimize_source_to_dependency_directives + +/// Minimize the input down to the preprocessor directives that might have +/// an effect on the dependencies for a compilation unit. +/// +/// This function deletes all non-preprocessor code, and strips anything that +/// can't affect what gets included. It canonicalizes whitespace where +/// convenient to stabilize the output against formatting changes in the input. +/// +/// Clears the output vectors at the beginning of the call. +/// +/// \returns false on success, true on error. If the diagnostic engine is not +/// null, an appropriate error is reported using the given input location +/// with the offset that corresponds to the minimizer's current buffer offset. +bool minimizeSourceToDependencyDirectives( + llvm::StringRef Input, llvm::SmallVectorImpl<char> &Output, + llvm::SmallVectorImpl<minimize_source_to_dependency_directives::Token> + &Tokens, + DiagnosticsEngine *Diags = nullptr, + SourceLocation InputSourceLoc = SourceLocation()); + +} // end namespace clang + +#endif // LLVM_CLANG_LEX_DEPENDENCY_DIRECTIVES_SOURCE_MINIMIZER_H diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h index bfb496be5072..7c556ac35175 100644 --- a/include/clang/Lex/DirectoryLookup.h +++ b/include/clang/Lex/DirectoryLookup.h @@ -1,9 +1,8 @@ //===--- DirectoryLookup.h - Info for searching for headers -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -171,6 +170,9 @@ public: /// set to true if the file is located in a framework that has been /// user-specified to be treated as a system framework. /// + /// \param [out] IsFrameworkFound For a framework directory set to true if + /// specified '.framework' directory is found. + /// /// \param [out] MappedName if this is a headermap which maps the filename to /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this /// vector and point Filename to it. @@ -181,6 +183,7 @@ public: Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, + bool &IsFrameworkFound, bool &HasBeenMapped, SmallVectorImpl<char> &MappedName) const; @@ -191,7 +194,8 @@ private: SmallVectorImpl<char> *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, - bool &InUserSpecifiedSystemFramework) const; + bool &InUserSpecifiedSystemFramework, + bool &IsFrameworkFound) const; }; diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h index d849bbd76188..685941b66bd8 100644 --- a/include/clang/Lex/ExternalPreprocessorSource.h +++ b/include/clang/Lex/ExternalPreprocessorSource.h @@ -1,9 +1,8 @@ //===- ExternalPreprocessorSource.h - Abstract Macro Interface --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h index 793e7edc2752..eca8755d4525 100644 --- a/include/clang/Lex/HeaderMap.h +++ b/include/clang/Lex/HeaderMap.h @@ -1,9 +1,8 @@ //===--- HeaderMap.h - A file that acts like dir of symlinks ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/HeaderMapTypes.h b/include/clang/Lex/HeaderMapTypes.h index fbaf4baee407..d8881d83d9bf 100644 --- a/include/clang/Lex/HeaderMapTypes.h +++ b/include/clang/Lex/HeaderMapTypes.h @@ -1,9 +1,8 @@ //===- HeaderMapTypes.h - Types for the header map format -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 7c69e219cb57..c5e66242444a 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -1,9 +1,8 @@ //===- HeaderSearch.h - Resolve Header File Locations -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -143,22 +142,22 @@ public: virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0; }; +/// This structure is used to record entries in our framework cache. +struct FrameworkCacheEntry { + /// The directory entry which should be used for the cached framework. + const DirectoryEntry *Directory; + + /// Whether this framework has been "user-specified" to be treated as if it + /// were a system framework (even if it was found outside a system framework + /// directory). + bool IsUserSpecifiedSystemFramework; +}; + /// Encapsulates the information needed to find the file referenced /// by a \#include or \#include_next, (sub-)framework lookup, etc. class HeaderSearch { friend class DirectoryLookup; - /// This structure is used to record entries in our framework cache. - struct FrameworkCacheEntry { - /// The directory entry which should be used for the cached framework. - const DirectoryEntry *Directory; - - /// Whether this framework has been "user-specified" to be treated as if it - /// were a system framework (even if it was found outside a system framework - /// directory). - bool IsUserSpecifiedSystemFramework; - }; - /// Header-search options used to initialize this header search. std::shared_ptr<HeaderSearchOptions> HSOpts; @@ -391,13 +390,19 @@ public: /// /// \param IsMapped If non-null, and the search involved header maps, set to /// true. + /// + /// \param IsFrameworkFound If non-null, will be set to true if a framework is + /// found in any of searched SearchDirs. Will be set to false if a framework + /// is found only through header maps. Doesn't guarantee the requested file is + /// found. const FileEntry *LookupFile( StringRef Filename, SourceLocation IncludeLoc, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, - bool *IsMapped, bool SkipCache = false, bool BuildSystemModule = false); + bool *IsMapped, bool *IsFrameworkFound, bool SkipCache = false, + bool BuildSystemModule = false); /// Look up a subframework for the specified \#include file. /// @@ -702,21 +707,31 @@ public: /// Retrieve a uniqued framework name. StringRef getUniqueFrameworkName(StringRef Framework); - /// Suggest a path by which the specified file could be found, for - /// use in diagnostics to suggest a #include. + /// Suggest a path by which the specified file could be found, for use in + /// diagnostics to suggest a #include. Returned path will only contain forward + /// slashes as separators. MainFile is the absolute path of the file that we + /// are generating the diagnostics for. It will try to shorten the path using + /// MainFile location, if none of the include search directories were prefix + /// of File. /// /// \param IsSystem If non-null, filled in to indicate whether the suggested /// path is relative to a system header directory. std::string suggestPathToFileForDiagnostics(const FileEntry *File, + llvm::StringRef MainFile, bool *IsSystem = nullptr); - /// Suggest a path by which the specified file could be found, for - /// use in diagnostics to suggest a #include. + /// Suggest a path by which the specified file could be found, for use in + /// diagnostics to suggest a #include. Returned path will only contain forward + /// slashes as separators. MainFile is the absolute path of the file that we + /// are generating the diagnostics for. It will try to shorten the path using + /// MainFile location, if none of the include search directories were prefix + /// of File. /// /// \param WorkingDir If non-empty, this will be prepended to search directory /// paths that are relative. std::string suggestPathToFileForDiagnostics(llvm::StringRef File, llvm::StringRef WorkingDir, + llvm::StringRef MainFile, bool *IsSystem = nullptr); void PrintStats(); diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h index e5b52b30323f..ed128bce485f 100644 --- a/include/clang/Lex/HeaderSearchOptions.h +++ b/include/clang/Lex/HeaderSearchOptions.h @@ -1,9 +1,8 @@ //===- HeaderSearchOptions.h ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h index 3a677b834543..86ce162c37ff 100644 --- a/include/clang/Lex/LexDiagnostic.h +++ b/include/clang/Lex/LexDiagnostic.h @@ -1,9 +1,8 @@ //===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index a9b10b627320..69cfe62e4bdb 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -1,9 +1,8 @@ //===- Lexer.h - C Language Family Lexer ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -383,7 +382,7 @@ public: SourceLocation End = getLocForEndOfToken(Range.getEnd(), 0, SM, LangOpts); return End.isInvalid() ? CharSourceRange() : CharSourceRange::getCharRange( - Range.getBegin(), End.getLocWithOffset(-1)); + Range.getBegin(), End); } static CharSourceRange getAsCharRange(CharSourceRange Range, const SourceManager &SM, diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index 3843a5afd2b0..b9d64c24a00b 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -1,9 +1,8 @@ //===--- LiteralSupport.h ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h index 853eee2fd779..8806f2d8c656 100644 --- a/include/clang/Lex/MacroArgs.h +++ b/include/clang/Lex/MacroArgs.h @@ -1,9 +1,8 @@ //===--- MacroArgs.h - Formal argument info for Macros ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -113,18 +112,19 @@ public: bool isVarargsElidedUse() const { return VarargsElided; } /// Returns true if the macro was defined with a variadic (ellipsis) parameter - /// AND was invoked with at least one token supplied as a variadic argument. + /// AND was invoked with at least one token supplied as a variadic argument + /// (after pre-expansion). /// /// \code /// #define F(a) a /// #define V(a, ...) __VA_OPT__(a) - /// F() <-- returns false on this invocation. - /// V(,a) <-- returns true on this invocation. - /// V(,) <-- returns false on this invocation. + /// F() <-- returns false on this invocation. + /// V(,a) <-- returns true on this invocation. + /// V(,) <-- returns false on this invocation. + /// V(,F()) <-- returns false on this invocation. /// \endcode /// - - bool invokedWithVariadicArgument(const MacroInfo *const MI) const; + bool invokedWithVariadicArgument(const MacroInfo *const MI, Preprocessor &PP); /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of /// tokens into the literal string token that should be produced by the C # diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index a06de132b496..550abf35c841 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -1,9 +1,8 @@ //===- MacroInfo.h - Information about #defined identifiers -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h index 05396dd20597..c93501acb9c2 100644 --- a/include/clang/Lex/ModuleLoader.h +++ b/include/clang/Lex/ModuleLoader.h @@ -1,9 +1,8 @@ //===- ModuleLoader.h - Module Loader Interface -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index a38c8d7819db..36e97a16223b 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -1,9 +1,8 @@ //===- ModuleMap.h - Describe the layout of modules -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -521,14 +520,18 @@ public: bool IsFramework, bool IsExplicit); - /// Create a 'global module' for a C++ Modules TS module interface unit. + /// Create a global module fragment for a C++ module unit. /// - /// We model the global module as a submodule of the module interface unit. - /// Unfortunately, we can't create the module interface unit's Module until - /// later, because we don't know what it will be called. - Module *createGlobalModuleForInterfaceUnit(SourceLocation Loc); + /// We model the global module fragment as a submodule of the module + /// interface unit. Unfortunately, we can't create the module interface + /// unit's Module until later, because we don't know what it will be called. + Module *createGlobalModuleFragmentForModuleUnit(SourceLocation Loc); + + /// Create a global module fragment for a C++ module interface unit. + Module *createPrivateModuleFragmentForInterfaceUnit(Module *Parent, + SourceLocation Loc); - /// Create a new module for a C++ Modules TS module interface unit. + /// Create a new module for a C++ module interface unit. /// The module must not already exist, and will be configured for the current /// compilation. /// diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h index ac0dcc7b51c2..7ceb7e53c75d 100644 --- a/include/clang/Lex/MultipleIncludeOpt.h +++ b/include/clang/Lex/MultipleIncludeOpt.h @@ -1,9 +1,8 @@ //===--- MultipleIncludeOpt.h - Header Multiple-Include Optzn ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index 2448b34c8af4..f3f3796b1a30 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -1,9 +1,8 @@ //===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -133,6 +132,28 @@ public: SrcMgr::CharacteristicKind FileType) { } + /// Callback invoked whenever a submodule was entered. + /// + /// \param M The submodule we have entered. + /// + /// \param ImportLoc The location of import directive token. + /// + /// \param ForPragma If entering from pragma directive. + /// + virtual void EnteredSubmodule(Module *M, SourceLocation ImportLoc, + bool ForPragma) { } + + /// Callback invoked whenever a submodule was left. + /// + /// \param M The submodule we have left. + /// + /// \param ImportLoc The location of import directive token. + /// + /// \param ForPragma If entering from pragma directive. + /// + virtual void LeftSubmodule(Module *M, SourceLocation ImportLoc, + bool ForPragma) { } + /// Callback invoked whenever there was an explicit module-import /// syntax. /// @@ -240,6 +261,14 @@ public: virtual void PragmaWarningPop(SourceLocation Loc) { } + /// Callback invoked when a \#pragma execution_character_set(push) directive + /// is read. + virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {} + + /// Callback invoked when a \#pragma execution_character_set(pop) directive + /// is read. + virtual void PragmaExecCharsetPop(SourceLocation Loc) {} + /// Callback invoked when a \#pragma clang assume_nonnull begin directive /// is read. virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {} @@ -388,6 +417,18 @@ public: Imported, FileType); } + void EnteredSubmodule(Module *M, SourceLocation ImportLoc, + bool ForPragma) override { + First->EnteredSubmodule(M, ImportLoc, ForPragma); + Second->EnteredSubmodule(M, ImportLoc, ForPragma); + } + + void LeftSubmodule(Module *M, SourceLocation ImportLoc, + bool ForPragma) override { + First->LeftSubmodule(M, ImportLoc, ForPragma); + Second->LeftSubmodule(M, ImportLoc, ForPragma); + } + void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported) override { First->moduleImport(ImportLoc, Path, Imported); @@ -478,6 +519,16 @@ public: Second->PragmaWarningPop(Loc); } + void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override { + First->PragmaExecCharsetPush(Loc, Str); + Second->PragmaExecCharsetPush(Loc, Str); + } + + void PragmaExecCharsetPop(SourceLocation Loc) override { + First->PragmaExecCharsetPop(Loc); + Second->PragmaExecCharsetPop(Loc); + } + void PragmaAssumeNonNullBegin(SourceLocation Loc) override { First->PragmaAssumeNonNullBegin(Loc); Second->PragmaAssumeNonNullBegin(Loc); diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h index a2ccf1407f79..077437435303 100644 --- a/include/clang/Lex/PPConditionalDirectiveRecord.h +++ b/include/clang/Lex/PPConditionalDirectiveRecord.h @@ -1,9 +1,8 @@ //===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h index fb2942f0916b..e9434269c19c 100644 --- a/include/clang/Lex/Pragma.h +++ b/include/clang/Lex/Pragma.h @@ -1,9 +1,8 @@ //===- Pragma.h - Pragma registration and handling --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -15,6 +14,7 @@ #define LLVM_CLANG_LEX_PRAGMA_H #include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include <string> @@ -47,6 +47,12 @@ class Token; PIK___pragma }; + /// Describes how and where the pragma was introduced. + struct PragmaIntroducer { + PragmaIntroducerKind Kind; + SourceLocation Loc; + }; + /// PragmaHandler - Instances of this interface defined to handle the various /// pragmas that the language front-end uses. Each handler optionally has a /// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with @@ -65,7 +71,7 @@ public: virtual ~PragmaHandler(); StringRef getName() const { return Name; } - virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstToken) = 0; /// getIfNamespace - If this is a namespace, return it. This is equivalent to @@ -79,7 +85,7 @@ class EmptyPragmaHandler : public PragmaHandler { public: explicit EmptyPragmaHandler(StringRef Name = StringRef()); - void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstToken) override; }; @@ -112,7 +118,7 @@ public: bool IsEmpty() const { return Handlers.empty(); } - void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) override; PragmaNamespace *getIfNamespace() override { return this; } diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index 027dd3ac5d55..11607811dc8f 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -1,9 +1,8 @@ //===- PreprocessingRecord.h - Record of Preprocessing ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 64ddb5307fb0..f65b0cda462f 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -1,9 +1,8 @@ //===- Preprocessor.h - C Language Family Preprocessor ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -34,6 +33,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerUnion.h" @@ -49,8 +49,8 @@ #include <cassert> #include <cstddef> #include <cstdint> -#include <memory> #include <map> +#include <memory> #include <string> #include <utility> #include <vector> @@ -72,7 +72,6 @@ class FileEntry; class FileManager; class HeaderSearch; class MacroArgs; -class MemoryBufferCache; class PragmaHandler; class PragmaNamespace; class PreprocessingRecord; @@ -126,6 +125,7 @@ class Preprocessor { friend class VAOptDefinitionContext; friend class VariadicMacroScopeGuard; + llvm::unique_function<void(const clang::Token &)> OnToken; std::shared_ptr<PreprocessorOptions> PPOpts; DiagnosticsEngine *Diags; LangOptions &LangOpts; @@ -133,7 +133,6 @@ class Preprocessor { const TargetInfo *AuxTarget = nullptr; FileManager &FileMgr; SourceManager &SourceMgr; - MemoryBufferCache &PCMCache; std::unique_ptr<ScratchBuffer> ScratchBuf; HeaderSearch &HeaderInfo; ModuleLoader &TheModuleLoader; @@ -150,6 +149,7 @@ class Preprocessor { IdentifierInfo *Ident__DATE__, *Ident__TIME__; // __DATE__, __TIME__ IdentifierInfo *Ident__INCLUDE_LEVEL__; // __INCLUDE_LEVEL__ IdentifierInfo *Ident__BASE_FILE__; // __BASE_FILE__ + IdentifierInfo *Ident__FILE_NAME__; // __FILE_NAME__ IdentifierInfo *Ident__TIMESTAMP__; // __TIMESTAMP__ IdentifierInfo *Ident__COUNTER__; // __COUNTER__ IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma @@ -174,6 +174,9 @@ class Preprocessor { IdentifierInfo *Ident__is_target_os; // __is_target_os IdentifierInfo *Ident__is_target_environment; // __is_target_environment + // Weak, only valid (and set) while InMacroArgs is true. + Token* ArgMacro; + SourceLocation DATELoc, TIMELoc; // Next __COUNTER__ value, starts at 0. @@ -285,6 +288,84 @@ class Preprocessor { /// Whether the last token we lexed was an '@'. bool LastTokenWasAt = false; + /// A position within a C++20 import-seq. + class ImportSeq { + public: + enum State : int { + // Positive values represent a number of unclosed brackets. + AtTopLevel = 0, + AfterTopLevelTokenSeq = -1, + AfterExport = -2, + AfterImportSeq = -3, + }; + + ImportSeq(State S) : S(S) {} + + /// Saw any kind of open bracket. + void handleOpenBracket() { + S = static_cast<State>(std::max<int>(S, 0) + 1); + } + /// Saw any kind of close bracket other than '}'. + void handleCloseBracket() { + S = static_cast<State>(std::max<int>(S, 1) - 1); + } + /// Saw a close brace. + void handleCloseBrace() { + handleCloseBracket(); + if (S == AtTopLevel && !AfterHeaderName) + S = AfterTopLevelTokenSeq; + } + /// Saw a semicolon. + void handleSemi() { + if (atTopLevel()) { + S = AfterTopLevelTokenSeq; + AfterHeaderName = false; + } + } + + /// Saw an 'export' identifier. + void handleExport() { + if (S == AfterTopLevelTokenSeq) + S = AfterExport; + else if (S <= 0) + S = AtTopLevel; + } + /// Saw an 'import' identifier. + void handleImport() { + if (S == AfterTopLevelTokenSeq || S == AfterExport) + S = AfterImportSeq; + else if (S <= 0) + S = AtTopLevel; + } + + /// Saw a 'header-name' token; do not recognize any more 'import' tokens + /// until we reach a top-level semicolon. + void handleHeaderName() { + if (S == AfterImportSeq) + AfterHeaderName = true; + handleMisc(); + } + + /// Saw any other token. + void handleMisc() { + if (S <= 0) + S = AtTopLevel; + } + + bool atTopLevel() { return S <= 0; } + bool afterImportSeq() { return S == AfterImportSeq; } + + private: + State S; + /// Whether we're in the pp-import-suffix following the header-name in a + /// pp-import. If so, a close-brace is not sufficient to end the + /// top-level-token-seq of an import-seq. + bool AfterHeaderName = false; + }; + + /// Our current position within a C++20 import-seq. + ImportSeq ImportSeqState = ImportSeq::AfterTopLevelTokenSeq; + /// Whether the module import expects an identifier next. Otherwise, /// it expects a '.' or ';'. bool ModuleImportExpectsIdentifier = false; @@ -323,6 +404,14 @@ class Preprocessor { /// to avoid hitting the same error over and over again. bool HasReachedMaxIncludeDepth = false; + /// The number of currently-active calls to Lex. + /// + /// Lex is reentrant, and asking for an (end-of-phase-4) token can often + /// require asking for multiple additional tokens. This counter makes it + /// possible for Lex to detect whether it's producing a token for the end + /// of phase 4 of translation or for some other situation. + unsigned LexLevel = 0; + public: struct PreambleSkipInfo { SourceLocation HashTokenLoc; @@ -777,7 +866,6 @@ private: 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, @@ -817,7 +905,6 @@ public: 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; } @@ -913,6 +1000,13 @@ public: } /// \} + /// Register a function that would be called on each token in the final + /// expanded token stream. + /// This also reports annotation tokens produced by the parser. + void setTokenWatcher(llvm::unique_function<void(const clang::Token &)> F) { + OnToken = std::move(F); + } + bool isMacroDefined(StringRef Id) { return isMacroDefined(&Identifiers.get(Id)); } @@ -1197,6 +1291,7 @@ public: void EnterMacro(Token &Tok, SourceLocation ILEnd, MacroInfo *Macro, MacroArgs *Args); +private: /// Add a "macro" context to the top of the include stack, /// which will cause the lexer to start returning the specified tokens. /// @@ -1208,18 +1303,24 @@ public: /// of tokens has a permanent owner somewhere, so they do not need to be /// copied. If it is true, it assumes the array of tokens is allocated with /// \c new[] and the Preprocessor will delete[] it. -private: + /// + /// If \p IsReinject the resulting tokens will have Token::IsReinjected flag + /// set, see the flag documentation for details. void EnterTokenStream(const Token *Toks, unsigned NumToks, - bool DisableMacroExpansion, bool OwnsTokens); + bool DisableMacroExpansion, bool OwnsTokens, + bool IsReinject); public: void EnterTokenStream(std::unique_ptr<Token[]> Toks, unsigned NumToks, - bool DisableMacroExpansion) { - EnterTokenStream(Toks.release(), NumToks, DisableMacroExpansion, true); + bool DisableMacroExpansion, bool IsReinject) { + EnterTokenStream(Toks.release(), NumToks, DisableMacroExpansion, true, + IsReinject); } - void EnterTokenStream(ArrayRef<Token> Toks, bool DisableMacroExpansion) { - EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false); + void EnterTokenStream(ArrayRef<Token> Toks, bool DisableMacroExpansion, + bool IsReinject) { + EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false, + IsReinject); } /// Pop the current lexer/macro exp off the top of the lexer stack. @@ -1246,24 +1347,6 @@ public: /// Disable the last EnableBacktrackAtThisPos call. void CommitBacktrackedTokens(); - struct CachedTokensRange { - CachedTokensTy::size_type Begin, End; - }; - -private: - /// A range of cached tokens that should be erased after lexing - /// when backtracking requires the erasure of such cached tokens. - Optional<CachedTokensRange> CachedTokenRangeToErase; - -public: - /// Returns the range of cached tokens that were lexed since - /// EnableBacktrackAtThisPos() was previously called. - CachedTokensRange LastCachedTokenRange(); - - /// Erase the range of cached tokens that were lexed since - /// EnableBacktrackAtThisPos() was previously called. - void EraseCachedTokens(CachedTokensRange TokenRange); - /// Make Preprocessor re-lex the tokens that were lexed since /// EnableBacktrackAtThisPos() was previously called. void Backtrack(); @@ -1275,7 +1358,11 @@ public: /// Lex the next token for this preprocessor. void Lex(Token &Result); - void LexAfterModuleImport(Token &Result); + /// Lex a token, forming a header-name token if possible. + bool LexHeaderName(Token &Result, bool AllowMacroExpansion = true); + + bool LexAfterModuleImport(Token &Result); + void CollectPpImportSuffix(SmallVectorImpl<Token> &Toks); void makeModuleVisible(Module *M, SourceLocation Loc); @@ -1352,6 +1439,7 @@ public: /// tokens after phase 5. As such, it is equivalent to using /// 'Lex', not 'LexUnexpandedToken'. const Token &LookAhead(unsigned N) { + assert(LexLevel == 0 && "cannot use lookahead while lexing"); if (CachedLexPos + N < CachedTokens.size()) return CachedTokens[CachedLexPos+N]; else @@ -1377,9 +1465,20 @@ public: /// /// If BackTrack() is called afterwards, the token will remain at the /// insertion point. - void EnterToken(const Token &Tok) { - EnterCachingLexMode(); - CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok); + /// If \p IsReinject is true, resulting token will have Token::IsReinjected + /// flag set. See the flag documentation for details. + void EnterToken(const Token &Tok, bool IsReinject) { + if (LexLevel) { + // It's not correct in general to enter caching lex mode while in the + // middle of a nested lexing action. + auto TokCopy = llvm::make_unique<Token[]>(1); + TokCopy[0] = Tok; + EnterTokenStream(std::move(TokCopy), 1, true, IsReinject); + } else { + EnterCachingLexMode(); + assert(IsReinject && "new tokens in the middle of cached stream"); + CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok); + } } /// We notify the Preprocessor that if it is caching tokens (because @@ -1813,11 +1912,15 @@ public: /// If not, emit a diagnostic and consume up until the eod. /// If \p EnableMacros is true, then we consider macros that expand to zero /// tokens as being ok. - void CheckEndOfDirective(const char *DirType, bool EnableMacros = false); + /// + /// \return The location of the end of the directive (the terminating + /// newline). + SourceLocation CheckEndOfDirective(const char *DirType, + bool EnableMacros = false); /// Read and discard all tokens remaining on the current line until - /// the tok::eod token is found. - void DiscardUntilEndOfDirective(); + /// the tok::eod token is found. Returns the range of the skipped tokens. + SourceRange DiscardUntilEndOfDirective(); /// Returns true if the preprocessor has seen a use of /// __DATE__ or __TIME__ in the file so far. @@ -1855,7 +1958,8 @@ public: SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, ModuleMap::KnownHeader *SuggestedModule, - bool *IsMapped, bool SkipCache = false); + bool *IsMapped, bool *IsFrameworkFound, + bool SkipCache = false); /// Get the DirectoryLookup structure used to find the current /// FileEntry, if CurLexer is non-null and if applicable. @@ -1867,22 +1971,6 @@ public: /// Return true if we're in the top-level file, not in a \#include. bool isInPrimaryFile() const; - /// Handle cases where the \#include name is expanded - /// from a macro as multiple tokens, which need to be glued together. - /// - /// This occurs for code like: - /// \code - /// \#define FOO <x/y.h> - /// \#include FOO - /// \endcode - /// because in this case, "<x/y.h>" is returned as 7 tokens, not one. - /// - /// This code concatenates and consumes tokens up to the '>' token. It - /// returns false if the > was found, otherwise it returns true if it finds - /// and consumes the EOD marker. - bool ConcatenateIncludeName(SmallString<128> &FilenameBuffer, - SourceLocation &End); - /// Lex an on-off-switch (C99 6.10.6p2) and verify that it is /// followed by EOD. Return true if the token is not a valid on-off-switch. bool LexOnOffSwitch(tok::OnOffSwitch &Result); @@ -1982,6 +2070,9 @@ private: /// True if the expression contained identifiers that were undefined. bool IncludedUndefinedIds; + + /// The source range for the expression. + SourceRange ExprRange; }; /// Evaluate an integer constant expression that may occur after a @@ -2073,6 +2164,7 @@ private: } void EnterCachingLexMode(); + void EnterCachingLexModeUnchecked(); void ExitCachingLexMode() { if (InCachingLexMode()) @@ -2093,12 +2185,32 @@ private: void HandleMacroPublicDirective(Token &Tok); void HandleMacroPrivateDirective(); + /// An additional notification that can be produced by a header inclusion or + /// import to tell the parser what happened. + struct ImportAction { + enum ActionKind { + None, + ModuleBegin, + ModuleImport, + SkippedModuleImport, + } Kind; + Module *ModuleForHeader = nullptr; + + ImportAction(ActionKind AK, Module *Mod = nullptr) + : Kind(AK), ModuleForHeader(Mod) { + assert((AK == None || Mod) && "no module for module action"); + } + }; + // File inclusion. - void HandleIncludeDirective(SourceLocation HashLoc, - Token &Tok, + void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok, + const DirectoryLookup *LookupFrom = nullptr, + const FileEntry *LookupFromFile = nullptr); + ImportAction + HandleHeaderIncludeOrImport(SourceLocation HashLoc, Token &IncludeTok, + Token &FilenameTok, SourceLocation EndLoc, const DirectoryLookup *LookupFrom = nullptr, - const FileEntry *LookupFromFile = nullptr, - bool isImport = false); + const FileEntry *LookupFromFile = nullptr); void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok); void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok); void HandleImportDirective(SourceLocation HashLoc, Token &Tok); @@ -2179,8 +2291,7 @@ private: void HandleElifDirective(Token &ElifToken, const Token &HashToken); // Pragmas. - void HandlePragmaDirective(SourceLocation IntroducerLoc, - PragmaIntroducerKind Introducer); + void HandlePragmaDirective(PragmaIntroducer Introducer); public: void HandlePragmaOnce(Token &OnceTok); diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h index de918a215302..03b1cc2c10e2 100644 --- a/include/clang/Lex/PreprocessorLexer.h +++ b/include/clang/Lex/PreprocessorLexer.h @@ -1,9 +1,8 @@ //===- PreprocessorLexer.h - C Language Family Lexer ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -49,8 +48,7 @@ protected: /// True when parsing \#XXX; turns '\\n' into a tok::eod token. bool ParsingPreprocessorDirective = false; - /// True after \#include; turns \<xx> into a tok::angle_string_literal - /// token. + /// True after \#include; turns \<xx> or "xxx" into a tok::header_name token. bool ParsingFilename = false; /// True if in raw mode. @@ -130,11 +128,7 @@ public: //===--------------------------------------------------------------------===// // Misc. lexing methods. - /// After the preprocessor has parsed a \#include, lex and - /// (potentially) macro expand the filename. - /// - /// If the sequence parsed is not lexically legal, emit a diagnostic and - /// return a result EOD token. + /// Lex a token, producing a header-name token if possible. void LexIncludeFilename(Token &FilenameTok); /// Inform the lexer whether or not we are currently lexing a diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h index f1ac72c47428..1480548c7fbe 100644 --- a/include/clang/Lex/PreprocessorOptions.h +++ b/include/clang/Lex/PreprocessorOptions.h @@ -1,9 +1,8 @@ //===- PreprocessorOptions.h ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h index a3d6096821e7..f526f22cb723 100644 --- a/include/clang/Lex/ScratchBuffer.h +++ b/include/clang/Lex/ScratchBuffer.h @@ -1,9 +1,8 @@ //===--- ScratchBuffer.h - Scratch space for forming tokens -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h index 85bef728197d..89042a674fec 100644 --- a/include/clang/Lex/Token.h +++ b/include/clang/Lex/Token.h @@ -1,9 +1,8 @@ //===--- Token.h - Token interface ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -71,20 +70,23 @@ class Token { public: // Various flags set per token: enum TokenFlags { - StartOfLine = 0x01, // At start of line or only after whitespace - // (considering the line after macro expansion). - LeadingSpace = 0x02, // Whitespace exists before this token (considering - // whitespace after macro expansion). - DisableExpand = 0x04, // This identifier may never be macro expanded. - NeedsCleaning = 0x08, // Contained an escaped newline or trigraph. + StartOfLine = 0x01, // At start of line or only after whitespace + // (considering the line after macro expansion). + LeadingSpace = 0x02, // Whitespace exists before this token (considering + // whitespace after macro expansion). + DisableExpand = 0x04, // This identifier may never be macro expanded. + NeedsCleaning = 0x08, // Contained an escaped newline or trigraph. LeadingEmptyMacro = 0x10, // Empty macro exists before this token. - HasUDSuffix = 0x20, // This string or character literal has a ud-suffix. - HasUCN = 0x40, // This identifier contains a UCN. - IgnoredComma = 0x80, // This comma is not a macro argument separator (MS). + HasUDSuffix = 0x20, // This string or character literal has a ud-suffix. + HasUCN = 0x40, // This identifier contains a UCN. + IgnoredComma = 0x80, // This comma is not a macro argument separator (MS). StringifiedInMacro = 0x100, // This string or character literal is formed by // macro stringizing or charizing operator. CommaAfterElided = 0x200, // The comma following this token was elided (MS). IsEditorPlaceholder = 0x400, // This identifier is a placeholder. + IsReinjected = 0x800, // A phase 4 token that was produced before and + // re-added, e.g. via EnterTokenStream. Annotation + // tokens are *not* reinjected. }; tok::TokenKind getKind() const { return Kind; } @@ -329,9 +331,4 @@ struct PPConditionalInfo { } // end namespace clang -namespace llvm { - template <> - struct isPodLike<clang::Token> { static const bool value = true; }; -} // end namespace llvm - #endif // LLVM_CLANG_LEX_TOKEN_H diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h index 3199e36f0d26..bd431725d496 100644 --- a/include/clang/Lex/TokenConcatenation.h +++ b/include/clang/Lex/TokenConcatenation.h @@ -1,9 +1,8 @@ //===--- TokenConcatenation.h - Token Concatenation Avoidance ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h index 6aae9eec7bfa..4d229ae61067 100644 --- a/include/clang/Lex/TokenLexer.h +++ b/include/clang/Lex/TokenLexer.h @@ -1,9 +1,8 @@ //===- TokenLexer.h - Lex from a token buffer -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -97,6 +96,10 @@ class TokenLexer { /// should not be subject to further macro expansion. bool DisableMacroExpansion : 1; + /// When true, the produced tokens have Token::IsReinjected flag set. + /// See the flag documentation for details. + bool IsReinject : 1; + public: /// Create a TokenLexer for the specified macro with the specified actual /// arguments. Note that this ctor takes ownership of the ActualArgs pointer. @@ -112,9 +115,9 @@ public: /// specified, this takes ownership of the tokens and delete[]'s them when /// the token lexer is empty. TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion, - bool ownsTokens, Preprocessor &pp) + bool ownsTokens, bool isReinject, Preprocessor &pp) : PP(pp), OwnsTokens(false) { - Init(TokArray, NumToks, DisableExpansion, ownsTokens); + Init(TokArray, NumToks, DisableExpansion, ownsTokens, isReinject); } TokenLexer(const TokenLexer &) = delete; @@ -133,8 +136,8 @@ public: /// /// DisableExpansion is true when macro expansion of tokens lexed from this /// stream should be disabled. - void Init(const Token *TokArray, unsigned NumToks, - bool DisableMacroExpansion, bool OwnsTokens); + void Init(const Token *TokArray, unsigned NumToks, bool DisableMacroExpansion, + bool OwnsTokens, bool IsReinject); /// If the next token lexed will pop this macro off the /// expansion stack, return 2. If the next unexpanded token is a '(', return diff --git a/include/clang/Lex/VariadicMacroSupport.h b/include/clang/Lex/VariadicMacroSupport.h index 3a7a955953f4..989e0ac703c9 100644 --- a/include/clang/Lex/VariadicMacroSupport.h +++ b/include/clang/Lex/VariadicMacroSupport.h @@ -1,9 +1,8 @@ //===- VariadicMacroSupport.h - state machines and scope guards -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -114,6 +113,8 @@ namespace clang { UnmatchedOpeningParens.push_back(LParenLoc); } + /// Are we at the top level within the __VA_OPT__? + bool isAtTopLevel() const { return UnmatchedOpeningParens.size() == 1; } }; /// A class for tracking whether we're inside a VA_OPT during a @@ -136,7 +137,8 @@ namespace clang { unsigned StringifyBefore : 1; unsigned CharifyBefore : 1; - + unsigned BeginsWithPlaceholder : 1; + unsigned EndsWithPlaceholder : 1; bool hasStringifyBefore() const { assert(!isReset() && @@ -152,7 +154,8 @@ namespace clang { public: VAOptExpansionContext(Preprocessor &PP) : VAOptDefinitionContext(PP), LeadingSpaceForStringifiedToken(false), - StringifyBefore(false), CharifyBefore(false) { + StringifyBefore(false), CharifyBefore(false), + BeginsWithPlaceholder(false), EndsWithPlaceholder(false) { SyntheticEOFToken.startToken(); SyntheticEOFToken.setKind(tok::eof); } @@ -163,6 +166,8 @@ namespace clang { LeadingSpaceForStringifiedToken = false; StringifyBefore = false; CharifyBefore = false; + BeginsWithPlaceholder = false; + EndsWithPlaceholder = false; } const Token &getEOFTok() const { return SyntheticEOFToken; } @@ -175,8 +180,24 @@ namespace clang { LeadingSpaceForStringifiedToken = HasLeadingSpace; } + void hasPlaceholderAfterHashhashAtStart() { BeginsWithPlaceholder = true; } + void hasPlaceholderBeforeRParen() { + if (isAtTopLevel()) + EndsWithPlaceholder = true; + } + bool beginsWithPlaceholder() const { + assert(!isReset() && + "Must only be called if the state has not been reset"); + return BeginsWithPlaceholder; + } + bool endsWithPlaceholder() const { + assert(!isReset() && + "Must only be called if the state has not been reset"); + return EndsWithPlaceholder; + } + bool hasCharifyBefore() const { assert(!isReset() && "Must only be called if the state has not been reset"); diff --git a/include/clang/Parse/LoopHint.h b/include/clang/Parse/LoopHint.h index be133703268d..6e363f72b658 100644 --- a/include/clang/Parse/LoopHint.h +++ b/include/clang/Parse/LoopHint.h @@ -1,9 +1,8 @@ //===--- LoopHint.h - Types for LoopHint ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Parse/ParseAST.h b/include/clang/Parse/ParseAST.h index f6e78ac2ca56..3a21f04f2ba3 100644 --- a/include/clang/Parse/ParseAST.h +++ b/include/clang/Parse/ParseAST.h @@ -1,9 +1,8 @@ //===--- ParseAST.h - Define the ParseAST method ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h index c7c62688cbaa..f174464b7841 100644 --- a/include/clang/Parse/ParseDiagnostic.h +++ b/include/clang/Parse/ParseDiagnostic.h @@ -1,9 +1,8 @@ //===--- DiagnosticParse.h - Diagnostics for libparse -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 438ff0e2ed45..7c67c35f615a 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -1,9 +1,8 @@ //===--- Parser.h - C Language Parser ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -75,6 +74,10 @@ class Parser : public CodeCompletionHandler { // a statement). SourceLocation PrevTokLocation; + /// Tracks an expected type for the current token when parsing an expression. + /// Used by code completion for ranking. + PreferredTypeBuilder PreferredType; + unsigned short ParenCount = 0, BracketCount = 0, BraceCount = 0; unsigned short MisplacedModuleBeginCount = 0; @@ -147,11 +150,15 @@ class Parser : public CodeCompletionHandler { IdentifierInfo *Ident_language, *Ident_defined_in, *Ident_generated_declaration; - /// C++0x contextual keywords. + /// C++11 contextual keywords. mutable IdentifierInfo *Ident_final; mutable IdentifierInfo *Ident_GNU_final; mutable IdentifierInfo *Ident_override; + // C++2a contextual keywords. + mutable IdentifierInfo *Ident_import; + mutable IdentifierInfo *Ident_module; + // C++ type trait keywords that can be reverted to identifiers and still be // used as type traits. llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits; @@ -243,7 +250,13 @@ class Parser : public CodeCompletionHandler { Depth += D; AddedLevels += D; } + void setAddedDepth(unsigned D) { + Depth = Depth - AddedLevels + D; + AddedLevels = D; + } + unsigned getDepth() const { return Depth; } + unsigned getOriginalDepth() const { return Depth - AddedLevels; } }; /// Factory object for creating ParsedAttr objects. @@ -360,10 +373,28 @@ class Parser : public CodeCompletionHandler { /// just a regular sub-expression. SourceLocation ExprStatementTokLoc; - /// Tests whether an expression value is discarded based on token lookahead. - /// It will return true if the lexer is currently processing the }) - /// terminating a GNU statement expression and false otherwise. - bool isExprValueDiscarded(); + /// Flags describing a context in which we're parsing a statement. + enum class ParsedStmtContext { + /// This context permits declarations in language modes where declarations + /// are not statements. + AllowDeclarationsInC = 0x1, + /// This context permits standalone OpenMP directives. + AllowStandaloneOpenMPDirectives = 0x2, + /// This context is at the top level of a GNU statement expression. + InStmtExpr = 0x4, + + /// The context of a regular substatement. + SubStmt = 0, + /// The context of a compound-statement. + Compound = AllowDeclarationsInC | AllowStandaloneOpenMPDirectives, + + LLVM_MARK_AS_BITMASK_ENUM(InStmtExpr) + }; + + /// Act on an expression statement that might be the last statement in a + /// GNU statement expression. Checks whether we are actually at the end of + /// a statement expression and builds a suitable expression statement. + StmtResult handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx); public: Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies); @@ -403,7 +434,7 @@ public: /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if /// the EOF was encountered. - bool ParseTopLevelDecl(DeclGroupPtrTy &Result); + bool ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl = false); bool ParseTopLevelDecl() { DeclGroupPtrTy Result; return ParseTopLevelDecl(Result); @@ -505,9 +536,9 @@ private: /// token the current token. void UnconsumeToken(Token &Consumed) { Token Next = Tok; - PP.EnterToken(Consumed); + PP.EnterToken(Consumed, /*IsReinject*/true); PP.Lex(Tok); - PP.EnterToken(Next); + PP.EnterToken(Next, /*IsReinject*/true); } SourceLocation ConsumeAnnotationToken() { @@ -768,9 +799,8 @@ private: /// Annotation was successful. ANK_Success }; - AnnotatedNameKind - TryAnnotateName(bool IsAddressOfOperand, - std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr); + AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand, + CorrectionCandidateCallback *CCC = nullptr); /// Push a tok::annot_cxxscope token onto the token stream. void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation); @@ -841,6 +871,7 @@ private: /// class TentativeParsingAction { Parser &P; + PreferredTypeBuilder PrevPreferredType; Token PrevTok; size_t PrevTentativelyDeclaredIdentifierCount; unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount; @@ -848,6 +879,7 @@ private: public: explicit TentativeParsingAction(Parser& p) : P(p) { + PrevPreferredType = P.PreferredType; PrevTok = P.Tok; PrevTentativelyDeclaredIdentifierCount = P.TentativelyDeclaredIdentifiers.size(); @@ -867,6 +899,7 @@ private: void Revert() { assert(isActive && "Parsing action was finished!"); P.PP.Backtrack(); + P.PreferredType = PrevPreferredType; P.Tok = PrevTok; P.TentativelyDeclaredIdentifiers.resize( PrevTentativelyDeclaredIdentifierCount); @@ -1125,6 +1158,7 @@ private: Parser *Self; CachedTokens Toks; IdentifierInfo &AttrName; + IdentifierInfo *MacroII = nullptr; SourceLocation AttrNameLoc; SmallVector<Decl*, 2> Decls; @@ -1550,7 +1584,8 @@ private: ObjCImplParsingDataRAII *CurParsedObjCImpl; void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl); - DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc); + DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc, + ParsedAttributes &Attrs); DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd); Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc); Decl *ParseObjCPropertySynthesize(SourceLocation atLoc); @@ -1656,10 +1691,10 @@ private: typedef SmallVector<SourceLocation, 20> CommaLocsTy; /// ParseExpressionList - Used for C/C++ (argument-)expression-list. - bool ParseExpressionList( - SmallVectorImpl<Expr *> &Exprs, - SmallVectorImpl<SourceLocation> &CommaLocs, - llvm::function_ref<void()> Completer = llvm::function_ref<void()>()); + bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, + SmallVectorImpl<SourceLocation> &CommaLocs, + llvm::function_ref<void()> ExpressionStarts = + llvm::function_ref<void()>()); /// ParseSimpleExpressionList - A simple comma-separated list of expressions, /// used for misc language extensions. @@ -1717,21 +1752,37 @@ private: bool OnlyNamespace = false); //===--------------------------------------------------------------------===// - // C++0x 5.1.2: Lambda expressions + // C++11 5.1.2: Lambda expressions + + /// Result of tentatively parsing a lambda-introducer. + enum class LambdaIntroducerTentativeParse { + /// This appears to be a lambda-introducer, which has been fully parsed. + Success, + /// This is a lambda-introducer, but has not been fully parsed, and this + /// function needs to be called again to parse it. + Incomplete, + /// This is definitely an Objective-C message send expression, rather than + /// a lambda-introducer, attribute-specifier, or array designator. + MessageSend, + /// This is not a lambda-introducer. + Invalid, + }; // [...] () -> type {...} ExprResult ParseLambdaExpression(); ExprResult TryParseLambdaExpression(); - Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro, - bool *SkippedInits = nullptr); - bool TryParseLambdaIntroducer(LambdaIntroducer &Intro); - ExprResult ParseLambdaExpressionAfterIntroducer( - LambdaIntroducer &Intro); + bool + ParseLambdaIntroducer(LambdaIntroducer &Intro, + LambdaIntroducerTentativeParse *Tentative = nullptr); + ExprResult ParseLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro); //===--------------------------------------------------------------------===// // C++ 5.2p1: C++ Casts ExprResult ParseCXXCasts(); + /// Parse a __builtin_bit_cast(T, E), used to implement C++2a std::bit_cast. + ExprResult ParseBuiltinBitCast(); + //===--------------------------------------------------------------------===// // C++ 5.2p1: C++ Type Identification ExprResult ParseCXXTypeid(); @@ -1867,29 +1918,24 @@ private: /// A SmallVector of types. typedef SmallVector<ParsedType, 12> TypeVector; - StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr, - bool AllowOpenMPStandalone = false); - enum AllowedConstructsKind { - /// Allow any declarations, statements, OpenMP directives. - ACK_Any, - /// Allow only statements and non-standalone OpenMP directives. - ACK_StatementsOpenMPNonStandalone, - /// Allow statements and all executable OpenMP directives - ACK_StatementsOpenMPAnyExecutable - }; StmtResult - ParseStatementOrDeclaration(StmtVector &Stmts, AllowedConstructsKind Allowed, - SourceLocation *TrailingElseLoc = nullptr); + ParseStatement(SourceLocation *TrailingElseLoc = nullptr, + ParsedStmtContext StmtCtx = ParsedStmtContext::SubStmt); + StmtResult ParseStatementOrDeclaration( + StmtVector &Stmts, ParsedStmtContext StmtCtx, + SourceLocation *TrailingElseLoc = nullptr); StmtResult ParseStatementOrDeclarationAfterAttributes( StmtVector &Stmts, - AllowedConstructsKind Allowed, + ParsedStmtContext StmtCtx, SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs); - StmtResult ParseExprStatement(); - StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs); - StmtResult ParseCaseStatement(bool MissingCase = false, + StmtResult ParseExprStatement(ParsedStmtContext StmtCtx); + StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs, + ParsedStmtContext StmtCtx); + StmtResult ParseCaseStatement(ParsedStmtContext StmtCtx, + bool MissingCase = false, ExprResult Expr = ExprResult()); - StmtResult ParseDefaultStatement(); + StmtResult ParseDefaultStatement(ParsedStmtContext StmtCtx); StmtResult ParseCompoundStatement(bool isStmtExpr = false); StmtResult ParseCompoundStatement(bool isStmtExpr, unsigned ScopeFlags); @@ -1912,7 +1958,7 @@ private: StmtResult ParseAsmStatement(bool &msAsm); StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc); StmtResult ParsePragmaLoopHint(StmtVector &Stmts, - AllowedConstructsKind Allowed, + ParsedStmtContext StmtCtx, SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs); @@ -1978,7 +2024,8 @@ private: //===--------------------------------------------------------------------===// // Objective-C Statements - StmtResult ParseObjCAtStatement(SourceLocation atLoc); + StmtResult ParseObjCAtStatement(SourceLocation atLoc, + ParsedStmtContext StmtCtx); StmtResult ParseObjCTryStmt(SourceLocation atLoc); StmtResult ParseObjCThrowStmt(SourceLocation atLoc); StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc); @@ -2272,13 +2319,18 @@ private: /// Doesn't consume tokens. TPResult isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False, - bool *HasMissingTypename = nullptr); + bool *InvalidAsDeclSpec = nullptr); /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or /// \c TPResult::Ambiguous, determine whether the decl-specifier would be /// a type-specifier other than a cv-qualifier. bool isCXXDeclarationSpecifierAType(); + /// Determine whether the current token sequence might be + /// '<' template-argument-list '>' + /// rather than a less-than expression. + TPResult isTemplateArgumentList(unsigned TokensToSkip); + /// Determine whether an identifier has been tentatively declared as a /// non-type. Such tentative declarations should not be found to name a type /// during a tentative parse, but also should not be annotated as a non-type. @@ -2797,6 +2849,13 @@ private: /// initializer. void ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm); + /// Parses 'omp declare mapper' directive. + DeclGroupPtrTy ParseOpenMPDeclareMapperDirective(AccessSpecifier AS); + /// Parses variable declaration in 'omp declare mapper' directive. + TypeResult parseOpenMPDeclareMapperVarDecl(SourceRange &Range, + DeclarationName &Name, + AccessSpecifier AS = AS_none); + /// Parses simple list of variables. /// /// \param Kind Kind of the directive. @@ -2811,13 +2870,9 @@ private: bool AllowScopeSpecifier); /// Parses declarative or executable directive. /// - /// \param Allowed ACK_Any, if any directives are allowed, - /// ACK_StatementsOpenMPAnyExecutable - if any executable directives are - /// allowed, ACK_StatementsOpenMPNonStandalone - if only non-standalone - /// executable directives are allowed. - /// + /// \param StmtCtx The context in which we're parsing the directive. StmtResult - ParseOpenMPDeclarativeOrExecutableDirective(AllowedConstructsKind Allowed); + ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx); /// Parses clause of kind \a CKind for directive of a kind \a Kind. /// /// \param DKind Kind of current directive. @@ -2878,8 +2933,8 @@ public: Expr *TailExpr = nullptr; SourceLocation ColonLoc; SourceLocation RLoc; - CXXScopeSpec ReductionIdScopeSpec; - DeclarationNameInfo ReductionId; + CXXScopeSpec ReductionOrMapperIdScopeSpec; + DeclarationNameInfo ReductionOrMapperId; OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown; OpenMPLinearClauseKind LinKind = OMPC_LINEAR_val; SmallVector<OpenMPMapModifierKind, OMPMapClause::NumberOfModifiers> @@ -2902,6 +2957,12 @@ public: ParsedType ObjectType, SourceLocation *TemplateKWLoc, UnqualifiedId &Result); + /// Parses the mapper modifier in map, to, and from clauses. + bool parseMapperModifier(OpenMPVarListDataTy &Data); + /// Parses map-type-modifiers in map clause. + /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) + /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) + bool parseMapTypeModifiers(OpenMPVarListDataTy &Data); private: //===--------------------------------------------------------------------===// @@ -2954,7 +3015,6 @@ private: UnqualifiedId &TemplateName, bool AllowTypeAnnotation = true); void AnnotateTemplateIdTokenAsType(bool IsClassName = false); - bool IsTemplateArgumentList(unsigned Skip = 0); bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs); ParsedTemplateArgument ParseTemplateTemplateArgument(); ParsedTemplateArgument ParseTemplateArgument(); @@ -2964,10 +3024,14 @@ private: SourceLocation &DeclEnd, ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none); + // C++2a: Template, concept definition [temp] + Decl * + ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo, + SourceLocation &DeclEnd); //===--------------------------------------------------------------------===// // Modules - DeclGroupPtrTy ParseModuleDecl(); + DeclGroupPtrTy ParseModuleDecl(bool IsFirstDecl); Decl *ParseModuleImport(SourceLocation AtLoc); bool parseMisplacedModuleImport(); bool tryParseMisplacedModuleImport() { diff --git a/include/clang/Parse/RAIIObjectsForParser.h b/include/clang/Parse/RAIIObjectsForParser.h index ba5e5fe3c8fb..558106eb684d 100644 --- a/include/clang/Parse/RAIIObjectsForParser.h +++ b/include/clang/Parse/RAIIObjectsForParser.h @@ -1,9 +1,8 @@ //===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Rewrite/Core/DeltaTree.h b/include/clang/Rewrite/Core/DeltaTree.h index f798e9fc41eb..e566c92aaff9 100644 --- a/include/clang/Rewrite/Core/DeltaTree.h +++ b/include/clang/Rewrite/Core/DeltaTree.h @@ -1,9 +1,8 @@ //===- DeltaTree.h - B-Tree for Rewrite Delta tracking ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Rewrite/Core/HTMLRewrite.h b/include/clang/Rewrite/Core/HTMLRewrite.h index 0f1f490d8305..340411e55347 100644 --- a/include/clang/Rewrite/Core/HTMLRewrite.h +++ b/include/clang/Rewrite/Core/HTMLRewrite.h @@ -1,9 +1,8 @@ //==- HTMLRewrite.h - Translate source code into prettified HTML ---*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Rewrite/Core/RewriteBuffer.h b/include/clang/Rewrite/Core/RewriteBuffer.h index c618298f5e82..b8f34174b715 100644 --- a/include/clang/Rewrite/Core/RewriteBuffer.h +++ b/include/clang/Rewrite/Core/RewriteBuffer.h @@ -1,9 +1,8 @@ //===- RewriteBuffer.h - Buffer rewriting interface -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h index 2a0e0a4a639b..039927c48b08 100644 --- a/include/clang/Rewrite/Core/RewriteRope.h +++ b/include/clang/Rewrite/Core/RewriteRope.h @@ -1,9 +1,8 @@ //===- RewriteRope.h - Rope specialized for rewriter ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h index 107968a9fb43..84c5ac3d72ee 100644 --- a/include/clang/Rewrite/Core/Rewriter.h +++ b/include/clang/Rewrite/Core/Rewriter.h @@ -1,9 +1,8 @@ //===- Rewriter.h - Code rewriting interface --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -85,7 +84,16 @@ public: /// in different buffers, this returns an empty string. /// /// Note that this method is not particularly efficient. - std::string getRewrittenText(SourceRange Range) const; + std::string getRewrittenText(CharSourceRange Range) const; + + /// getRewrittenText - Return the rewritten form of the text in the specified + /// range. If the start or end of the range was unrewritable or if they are + /// in different buffers, this returns an empty string. + /// + /// Note that this method is not particularly efficient. + std::string getRewrittenText(SourceRange Range) const { + return getRewrittenText(CharSourceRange::getTokenRange(Range)); + } /// InsertText - Insert the specified string at the specified location in the /// original buffer. This method returns true (and does nothing) if the input @@ -142,6 +150,13 @@ public: /// ReplaceText - This method replaces a range of characters in the input /// buffer with a new string. This is effectively a combined "remove/insert" /// operation. + bool ReplaceText(CharSourceRange range, StringRef NewStr) { + return ReplaceText(range.getBegin(), getRangeSize(range), NewStr); + } + + /// ReplaceText - This method replaces a range of characters in the input + /// buffer with a new string. This is effectively a combined "remove/insert" + /// operation. bool ReplaceText(SourceRange range, StringRef NewStr) { return ReplaceText(range.getBegin(), getRangeSize(range), NewStr); } diff --git a/include/clang/Rewrite/Core/TokenRewriter.h b/include/clang/Rewrite/Core/TokenRewriter.h index ab2c2c8b0adb..13ca2ddec303 100644 --- a/include/clang/Rewrite/Core/TokenRewriter.h +++ b/include/clang/Rewrite/Core/TokenRewriter.h @@ -1,9 +1,8 @@ //===- TokenRewriter.h - Token-based Rewriter -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Rewrite/Frontend/ASTConsumers.h b/include/clang/Rewrite/Frontend/ASTConsumers.h index e054e75e9595..618b38050dc7 100644 --- a/include/clang/Rewrite/Frontend/ASTConsumers.h +++ b/include/clang/Rewrite/Frontend/ASTConsumers.h @@ -1,9 +1,8 @@ //===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h index 7456840bc5c1..f514f3628a55 100644 --- a/include/clang/Rewrite/Frontend/FixItRewriter.h +++ b/include/clang/Rewrite/Frontend/FixItRewriter.h @@ -1,9 +1,8 @@ //===- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h index 40d2f4c22afe..4e9d1941bce0 100644 --- a/include/clang/Rewrite/Frontend/FrontendActions.h +++ b/include/clang/Rewrite/Frontend/FrontendActions.h @@ -1,9 +1,8 @@ //===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Rewrite/Frontend/Rewriters.h b/include/clang/Rewrite/Frontend/Rewriters.h index 3ad76dff824f..3f9332219c3b 100644 --- a/include/clang/Rewrite/Frontend/Rewriters.h +++ b/include/clang/Rewrite/Frontend/Rewriters.h @@ -1,9 +1,8 @@ //===--- Rewriters.h - Rewriter implementations -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h index 6e8d83974e5b..e13fe955eaf4 100644 --- a/include/clang/Sema/AnalysisBasedWarnings.h +++ b/include/clang/Sema/AnalysisBasedWarnings.h @@ -1,9 +1,8 @@ //=- AnalysisBasedWarnings.h - Sema warnings based on libAnalysis -*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -91,7 +90,7 @@ public: AnalysisBasedWarnings(Sema &s); void IssueWarnings(Policy P, FunctionScopeInfo *fscope, - const Decl *D, const BlockExpr *blkExpr); + const Decl *D, QualType BlockType); Policy getDefaultPolicy() { return DefaultPolicy; } diff --git a/include/clang/Sema/CXXFieldCollector.h b/include/clang/Sema/CXXFieldCollector.h index 6685751d1e61..f6ecd9f46e5e 100644 --- a/include/clang/Sema/CXXFieldCollector.h +++ b/include/clang/Sema/CXXFieldCollector.h @@ -1,9 +1,8 @@ //===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/CleanupInfo.h b/include/clang/Sema/CleanupInfo.h index 751bfb63b442..ea9df49f77e1 100644 --- a/include/clang/Sema/CleanupInfo.h +++ b/include/clang/Sema/CleanupInfo.h @@ -1,9 +1,8 @@ //===--- CleanupInfo.cpp - Cleanup Control in Sema ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index 5e46a84128d5..f7d073f48bfb 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -1,9 +1,8 @@ //===- CodeCompleteConsumer.h - Code Completion Interface -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -381,6 +380,7 @@ public: /// if the expression is a variable initializer or a function argument, the /// type of the corresponding variable or function parameter. QualType getPreferredType() const { return PreferredType; } + void setPreferredType(QualType T) { PreferredType = T; } /// Retrieve the type of the base object in a member-access /// expression. @@ -656,14 +656,6 @@ public: } // namespace clang -namespace llvm { - -template <> struct isPodLike<clang::CodeCompletionString::Chunk> { - static const bool value = true; -}; - -} // namespace llvm - namespace clang { /// A builder class used to construct new code-completion strings. @@ -1000,10 +992,6 @@ class CodeCompleteConsumer { protected: const CodeCompleteOptions CodeCompleteOpts; - /// Whether the output format for the code-completion consumer is - /// binary. - bool OutputIsBinary; - public: class OverloadCandidate { public: @@ -1074,9 +1062,8 @@ public: bool IncludeBriefComments) const; }; - CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts, - bool OutputIsBinary) - : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary) {} + CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts) + : CodeCompleteOpts(CodeCompleteOpts) {} /// Whether the code-completion consumer wants to see macros. bool includeMacros() const { @@ -1114,9 +1101,6 @@ public: return CodeCompleteOpts.LoadExternal; } - /// Determine whether the output of this consumer is binary. - bool isOutputBinary() const { return OutputIsBinary; } - /// Deregisters and destroys this code-completion consumer. virtual ~CodeCompleteConsumer(); @@ -1189,7 +1173,7 @@ public: /// results to the given raw output stream. PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts, raw_ostream &OS) - : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS), + : CodeCompleteConsumer(CodeCompleteOpts), OS(OS), CCTUInfo(std::make_shared<GlobalCodeCompletionAllocator>()) {} /// Prints the finalized code-completion results. diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h index 26f7f9d19f8e..a3403b01dcde 100644 --- a/include/clang/Sema/CodeCompleteOptions.h +++ b/include/clang/Sema/CodeCompleteOptions.h @@ -1,9 +1,8 @@ //===---- CodeCompleteOptions.h - Code Completion Options -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 8d6f0bc9148b..b417f89c0e5b 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -1,9 +1,8 @@ //===--- DeclSpec.h - Parsed declaration specifiers -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -23,6 +22,7 @@ #ifndef LLVM_CLANG_SEMA_DECLSPEC_H #define LLVM_CLANG_SEMA_DECLSPEC_H +#include "clang/AST/DeclCXX.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/Lambda.h" @@ -357,14 +357,13 @@ private: unsigned FS_inline_specified : 1; unsigned FS_forceinline_specified: 1; unsigned FS_virtual_specified : 1; - unsigned FS_explicit_specified : 1; unsigned FS_noreturn_specified : 1; // friend-specifier unsigned Friend_specified : 1; // constexpr-specifier - unsigned Constexpr_specified : 1; + unsigned ConstexprSpecifier : 2; union { UnionParsedType TypeRep; @@ -372,6 +371,9 @@ private: Expr *ExprRep; }; + /// ExplicitSpecifier - Store information about explicit spicifer. + ExplicitSpecifier FS_explicit_specifier; + // attributes. ParsedAttributes Attrs; @@ -394,6 +396,7 @@ private: SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc, TQ_unalignedLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; + SourceLocation FS_explicitCloseParenLoc; SourceLocation FS_forceinlineLoc; SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc; SourceLocation TQ_pipeLoc; @@ -421,31 +424,18 @@ public: } DeclSpec(AttributeFactory &attrFactory) - : StorageClassSpec(SCS_unspecified), - ThreadStorageClassSpec(TSCS_unspecified), - SCS_extern_in_linkage_spec(false), - TypeSpecWidth(TSW_unspecified), - TypeSpecComplex(TSC_unspecified), - TypeSpecSign(TSS_unspecified), - TypeSpecType(TST_unspecified), - TypeAltiVecVector(false), - TypeAltiVecPixel(false), - TypeAltiVecBool(false), - TypeSpecOwned(false), - TypeSpecPipe(false), - TypeSpecSat(false), - TypeQualifiers(TQ_unspecified), - FS_inline_specified(false), - FS_forceinline_specified(false), - FS_virtual_specified(false), - FS_explicit_specified(false), - FS_noreturn_specified(false), - Friend_specified(false), - Constexpr_specified(false), - Attrs(attrFactory), - writtenBS(), - ObjCQualifiers(nullptr) { - } + : StorageClassSpec(SCS_unspecified), + ThreadStorageClassSpec(TSCS_unspecified), + SCS_extern_in_linkage_spec(false), TypeSpecWidth(TSW_unspecified), + TypeSpecComplex(TSC_unspecified), TypeSpecSign(TSS_unspecified), + TypeSpecType(TST_unspecified), TypeAltiVecVector(false), + TypeAltiVecPixel(false), TypeAltiVecBool(false), TypeSpecOwned(false), + TypeSpecPipe(false), TypeSpecSat(false), TypeQualifiers(TQ_unspecified), + FS_inline_specified(false), FS_forceinline_specified(false), + FS_virtual_specified(false), FS_noreturn_specified(false), + Friend_specified(false), ConstexprSpecifier(CSK_unspecified), + FS_explicit_specifier(), Attrs(attrFactory), writtenBS(), + ObjCQualifiers(nullptr) {} // storage-class-specifier SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } @@ -540,6 +530,7 @@ public: static const char *getSpecifierName(DeclSpec::TSW W); static const char *getSpecifierName(DeclSpec::SCS S); static const char *getSpecifierName(DeclSpec::TSCS S); + static const char *getSpecifierName(ConstexprSpecKind C); // type-qualifiers @@ -571,11 +562,22 @@ public: return FS_inline_specified ? FS_inlineLoc : FS_forceinlineLoc; } + ExplicitSpecifier getExplicitSpecifier() const { + return FS_explicit_specifier; + } + bool isVirtualSpecified() const { return FS_virtual_specified; } SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; } - bool isExplicitSpecified() const { return FS_explicit_specified; } + bool hasExplicitSpecifier() const { + return FS_explicit_specifier.isSpecified(); + } SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; } + SourceRange getExplicitSpecRange() const { + return FS_explicit_specifier.getExpr() + ? SourceRange(FS_explicitLoc, FS_explicitCloseParenLoc) + : SourceRange(FS_explicitLoc); + } bool isNoreturnSpecified() const { return FS_noreturn_specified; } SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; } @@ -587,8 +589,9 @@ public: FS_forceinlineLoc = SourceLocation(); FS_virtual_specified = false; FS_virtualLoc = SourceLocation(); - FS_explicit_specified = false; + FS_explicit_specifier = ExplicitSpecifier(); FS_explicitLoc = SourceLocation(); + FS_explicitCloseParenLoc = SourceLocation(); FS_noreturn_specified = false; FS_noreturnLoc = SourceLocation(); } @@ -707,7 +710,8 @@ public: bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); + unsigned &DiagID, ExplicitSpecifier ExplicitSpec, + SourceLocation CloseParenLoc); bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); @@ -715,8 +719,8 @@ public: unsigned &DiagID); bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); - bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); + bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID); bool isFriendSpecified() const { return Friend_specified; } SourceLocation getFriendSpecLoc() const { return FriendLoc; } @@ -724,11 +728,17 @@ public: bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); } SourceLocation getModulePrivateSpecLoc() const { return ModulePrivateLoc; } - bool isConstexprSpecified() const { return Constexpr_specified; } + ConstexprSpecKind getConstexprSpecifier() const { + return ConstexprSpecKind(ConstexprSpecifier); + } + SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; } + bool hasConstexprSpecifier() const { + return ConstexprSpecifier != CSK_unspecified; + } void ClearConstexprSpec() { - Constexpr_specified = false; + ConstexprSpecifier = CSK_unspecified; ConstexprLoc = SourceLocation(); } diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index a26b6ff070f6..929db5dfce23 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -1,9 +1,8 @@ //===- DelayedDiagnostic.h - Delayed declarator diagnostics -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/Designator.h b/include/clang/Sema/Designator.h index 55603fe2e2f9..05f661151263 100644 --- a/include/clang/Sema/Designator.h +++ b/include/clang/Sema/Designator.h @@ -1,9 +1,8 @@ //===--- Designator.h - Initialization Designator ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index 00f80e27415d..88fa6f53d8bf 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -1,9 +1,8 @@ //===--- ExternalSemaSource.h - External Sema Interface ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h index 1c46e1d0e3d2..7c8dc46307d4 100644 --- a/include/clang/Sema/IdentifierResolver.h +++ b/include/clang/Sema/IdentifierResolver.h @@ -1,9 +1,8 @@ //===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 3a2d6275650d..f726f3836307 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -1,9 +1,8 @@ //===- Initialization.h - Semantic Analysis for Initializers ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -387,6 +386,8 @@ public: } /// Create the initialization entity for a lambda capture. + /// + /// \p VarID The name of the entity being captured, or nullptr for 'this'. static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc) { @@ -510,7 +511,7 @@ public: /// For a lambda capture, return the capture's name. StringRef getCapturedVarName() const { assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); - return Capture.VarID->getName(); + return Capture.VarID ? Capture.VarID->getName() : "this"; } /// Determine the location of the capture when initializing @@ -820,9 +821,6 @@ public: /// Perform a conversion adding _Atomic to a type. SK_AtomicConversion, - /// Perform a load from a glvalue, producing an rvalue. - SK_LValueToRValue, - /// Perform an implicit conversion sequence. SK_ConversionSequence, @@ -1011,6 +1009,9 @@ public: /// Reference binding drops qualifiers. FK_ReferenceInitDropsQualifiers, + /// Reference with mismatching address space binding to temporary. + FK_ReferenceAddrspaceMismatchTemporary, + /// Reference binding failed. FK_ReferenceInitFailed, @@ -1266,12 +1267,6 @@ public: /// type. void AddAtomicConversionStep(QualType Ty); - /// Add a new step that performs a load of the given type. - /// - /// Although the term "LValueToRValue" is conventional, this applies to both - /// lvalues and xvalues. - void AddLValueToRValueStep(QualType Ty); - /// Add a new step that applies an implicit conversion sequence. void AddConversionSequenceStep(const ImplicitConversionSequence &ICS, QualType T, bool TopLevelOfInitList = false); diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 4f7da851e232..0466d06d753b 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -1,9 +1,8 @@ //===- Lookup.h - Classes for name lookup -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -173,7 +172,8 @@ public: : SemaPtr(Other.SemaPtr), NameInfo(Other.NameInfo), LookupKind(Other.LookupKind), IDNS(Other.IDNS), Redecl(Other.Redecl), ExternalRedecl(Other.ExternalRedecl), HideTags(Other.HideTags), - AllowHidden(Other.AllowHidden) {} + AllowHidden(Other.AllowHidden), + TemplateNameLookup(Other.TemplateNameLookup) {} // FIXME: Remove these deleted methods once the default build includes // -Wdeprecated. @@ -194,7 +194,8 @@ public: HideTags(std::move(Other.HideTags)), Diagnose(std::move(Other.Diagnose)), AllowHidden(std::move(Other.AllowHidden)), - Shadowed(std::move(Other.Shadowed)) { + Shadowed(std::move(Other.Shadowed)), + TemplateNameLookup(std::move(Other.TemplateNameLookup)) { Other.Paths = nullptr; Other.Diagnose = false; } @@ -217,6 +218,7 @@ public: Diagnose = std::move(Other.Diagnose); AllowHidden = std::move(Other.AllowHidden); Shadowed = std::move(Other.Shadowed); + TemplateNameLookup = std::move(Other.TemplateNameLookup); Other.Paths = nullptr; Other.Diagnose = false; return *this; @@ -287,6 +289,15 @@ public: HideTags = Hide; } + /// Sets whether this is a template-name lookup. For template-name lookups, + /// injected-class-names are treated as naming a template rather than a + /// template specialization. + void setTemplateNameLookup(bool TemplateName) { + TemplateNameLookup = TemplateName; + } + + bool isTemplateNameLookup() const { return TemplateNameLookup; } + bool isAmbiguous() const { return getResultKind() == Ambiguous; } @@ -740,6 +751,9 @@ private: /// declaration that we skipped. This only happens when \c LookupKind /// is \c LookupRedeclarationWithLinkage. bool Shadowed = false; + + /// True if we're looking up a template-name. + bool TemplateNameLookup = false; }; /// Consumes visible declarations found when searching for diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h index 86bddebcef69..8157e488d3b1 100644 --- a/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/include/clang/Sema/MultiplexExternalSemaSource.h @@ -1,9 +1,8 @@ //===--- MultiplexExternalSemaSource.h - External Sema Interface-*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h index d0af4d15fb9f..bd2ce2a9f016 100644 --- a/include/clang/Sema/ObjCMethodList.h +++ b/include/clang/Sema/ObjCMethodList.h @@ -1,9 +1,8 @@ //===--- ObjCMethodList.h - A singly linked list of methods -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 96fd5892daae..96aadeac2ba3 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -1,9 +1,8 @@ //===- Overload.h - C++ Overloading -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -706,6 +705,11 @@ class Sema; /// attribute disabled it. ovl_fail_enable_if, + /// This candidate constructor or conversion fonction + /// is used implicitly but the explicit(bool) specifier + /// was resolved to true + ovl_fail_explicit_resolved, + /// This candidate was not viable because its address could not be taken. ovl_fail_addr_not_available, @@ -719,6 +723,11 @@ class Sema; /// This candidate was not viable because it is a non-default multiversioned /// function. ovl_non_default_multiversion_function, + + /// This constructor/conversion candidate fail due to an address space + /// mismatch between the object being constructed and the overload + /// candidate. + ovl_fail_object_addrspace_mismatch }; /// A list of implicit conversion sequences for the arguments of an @@ -874,6 +883,9 @@ class Sema; unsigned NumInlineBytesUsed = 0; llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace; + // Address space of the object being constructed. + LangAS DestAS = LangAS::Default; + /// If we have space, allocates from inline storage. Otherwise, allocates /// from the slab allocator. /// FIXME: It would probably be nice to have a SmallBumpPtrAllocator @@ -962,13 +974,34 @@ class Sema; OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator& Best); - void NoteCandidates(Sema &S, - OverloadCandidateDisplayKind OCD, - ArrayRef<Expr *> Args, + SmallVector<OverloadCandidate *, 32> CompleteCandidates( + Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef<Expr *> Args, + SourceLocation OpLoc = SourceLocation(), + llvm::function_ref<bool(OverloadCandidate &)> Filter = + [](OverloadCandidate &) { return true; }); + + void NoteCandidates( + PartialDiagnosticAt PA, Sema &S, OverloadCandidateDisplayKind OCD, + ArrayRef<Expr *> Args, StringRef Opc = "", + SourceLocation Loc = SourceLocation(), + llvm::function_ref<bool(OverloadCandidate &)> Filter = + [](OverloadCandidate &) { return true; }); + + void NoteCandidates(Sema &S, ArrayRef<Expr *> Args, + ArrayRef<OverloadCandidate *> Cands, StringRef Opc = "", - SourceLocation Loc = SourceLocation(), - llvm::function_ref<bool(OverloadCandidate&)> Filter = - [](OverloadCandidate&) { return true; }); + SourceLocation OpLoc = SourceLocation()); + + LangAS getDestAS() { return DestAS; } + + void setDestAS(LangAS AS) { + assert((Kind == CSK_InitByConstructor || + Kind == CSK_InitByUserDefinedConversion) && + "can't set the destination address space when not constructing an " + "object"); + DestAS = AS; + } + }; bool isBetterOverloadCandidate(Sema &S, diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h index ae2f178df1ec..f395282c0c52 100644 --- a/include/clang/Sema/Ownership.h +++ b/include/clang/Sema/Ownership.h @@ -1,9 +1,8 @@ //===- Ownership.h - Parser ownership helpers -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -129,9 +128,6 @@ namespace llvm { } }; - template <class T> - struct isPodLike<clang::OpaquePtr<T>> { static const bool value = true; }; - } // namespace llvm namespace clang { diff --git a/include/clang/Sema/ParsedAttr.h b/include/clang/Sema/ParsedAttr.h index 11202cb137b5..d87d5da04acc 100644 --- a/include/clang/Sema/ParsedAttr.h +++ b/include/clang/Sema/ParsedAttr.h @@ -1,9 +1,8 @@ //======- ParsedAttr.h - Parsed attribute sets ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -168,6 +167,8 @@ public: private: IdentifierInfo *AttrName; IdentifierInfo *ScopeName; + IdentifierInfo *MacroII = nullptr; + SourceLocation MacroExpansionLoc; SourceRange AttrRange; SourceLocation ScopeLoc; SourceLocation EllipsisLoc; @@ -208,6 +209,9 @@ private: /// A cached value. mutable unsigned ProcessingCache : 8; + /// True if the attribute is specified using '#pragma clang attribute'. + mutable unsigned IsPragmaClangAttribute : 1; + /// The location of the 'unavailable' keyword in an /// availability attribute. SourceLocation UnavailableLoc; @@ -239,7 +243,8 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), - HasParsedType(false), HasProcessingCache(false) { + HasParsedType(false), HasProcessingCache(false), + IsPragmaClangAttribute(false) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -256,8 +261,8 @@ private: ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - HasProcessingCache(false), UnavailableLoc(unavailable), - MessageExpr(messageExpr) { + HasProcessingCache(false), IsPragmaClangAttribute(false), + UnavailableLoc(unavailable), MessageExpr(messageExpr) { ArgsUnion PVal(Parm); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); new (getAvailabilityData()) detail::AvailabilityData( @@ -274,7 +279,7 @@ private: ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - HasProcessingCache(false) { + HasProcessingCache(false), IsPragmaClangAttribute(false) { ArgsUnion *Args = getArgsBuffer(); Args[0] = Parm1; Args[1] = Parm2; @@ -291,7 +296,7 @@ private: ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), - HasProcessingCache(false) { + HasProcessingCache(false), IsPragmaClangAttribute(false) { ArgsUnion PVal(ArgKind); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); @@ -309,7 +314,7 @@ private: ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), - HasProcessingCache(false) { + HasProcessingCache(false), IsPragmaClangAttribute(false) { new (&getTypeBuffer()) ParsedType(typeArg); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -323,7 +328,7 @@ private: ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), - HasProcessingCache(false) { + HasProcessingCache(false), IsPragmaClangAttribute(false) { new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -435,7 +440,12 @@ public: } bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } - void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } + void setUsedAsTypeAttr(bool Used = true) { UsedAsTypeAttr = Used; } + + /// True if the attribute is specified using '#pragma clang attribute'. + bool isPragmaClangAttribute() const { return IsPragmaClangAttribute; } + + void setIsPragmaClangAttribute() { IsPragmaClangAttribute = true; } bool isPackExpansion() const { return EllipsisLoc.isValid(); } SourceLocation getEllipsisLoc() const { return EllipsisLoc; } @@ -539,6 +549,27 @@ public: return getPropertyDataBuffer().SetterId; } + /// Set the macro identifier info object that this parsed attribute was + /// declared in if it was declared in a macro. Also set the expansion location + /// of the macro. + void setMacroIdentifier(IdentifierInfo *MacroName, SourceLocation Loc) { + MacroII = MacroName; + MacroExpansionLoc = Loc; + } + + /// Returns true if this attribute was declared in a macro. + bool hasMacroIdentifier() const { return MacroII != nullptr; } + + /// Return the macro identifier if this attribute was declared in a macro. + /// nullptr is returned if it was not declared in a macro. + IdentifierInfo *getMacroIdentifier() const { return MacroII; } + + SourceLocation getMacroExpansionLoc() const { + assert(hasMacroIdentifier() && "Can only get the macro expansion location " + "if this attribute has a macro identifier."); + return MacroExpansionLoc; + } + /// Get an index into the attribute spelling list /// defined in Attr.td. This index is used by an attribute /// to pretty print itself. @@ -568,6 +599,25 @@ public: /// parsed attribute does not have a semantic equivalent, or would not have /// a Spelling enumeration, the value UINT_MAX is returned. unsigned getSemanticSpelling() const; + + /// If this is an OpenCL addr space attribute returns its representation + /// in LangAS, otherwise returns default addr space. + LangAS asOpenCLLangAS() const { + switch (getKind()) { + case ParsedAttr::AT_OpenCLConstantAddressSpace: + return LangAS::opencl_constant; + case ParsedAttr::AT_OpenCLGlobalAddressSpace: + return LangAS::opencl_global; + case ParsedAttr::AT_OpenCLLocalAddressSpace: + return LangAS::opencl_local; + case ParsedAttr::AT_OpenCLPrivateAddressSpace: + return LangAS::opencl_private; + case ParsedAttr::AT_OpenCLGenericAddressSpace: + return LangAS::opencl_generic; + default: + return LangAS::Default; + } + } }; class AttributePool; @@ -632,6 +682,7 @@ public: class AttributePool { friend class AttributeFactory; + friend class ParsedAttributes; AttributeFactory &Factory; llvm::TinyPtrVector<ParsedAttr *> Attrs; @@ -865,6 +916,13 @@ public: pool.takeAllFrom(attrs.pool); } + void takeOneFrom(ParsedAttributes &Attrs, ParsedAttr *PA) { + Attrs.getPool().remove(PA); + Attrs.remove(PA); + getPool().add(PA); + addAtEnd(PA); + } + void clear() { clearListOnly(); pool.clear(); diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h index 258b2291d260..2eed301e8aeb 100644 --- a/include/clang/Sema/ParsedTemplate.h +++ b/include/clang/Sema/ParsedTemplate.h @@ -1,9 +1,8 @@ //===--- ParsedTemplate.h - Template Parsing Data Types ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index 9d9ab0514fb5..7848df8f70d9 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -1,9 +1,8 @@ //===- Scope.h - Scope interface --------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -132,6 +131,9 @@ public: /// We are between inheritance colon and the real class/struct definition scope. ClassInheritanceScope = 0x800000, + + /// This is the scope of a C++ catch statement. + CatchScope = 0x1000000, }; private: diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index e09a68aba707..ea2595113d58 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -1,9 +1,8 @@ //===- ScopeInfo.h - Information about a semantic context -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -16,6 +15,7 @@ #define LLVM_CLANG_SEMA_SCOPEINFO_H #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/Type.h" #include "clang/Basic/CapturedStmt.h" #include "clang/Basic/LLVM.h" @@ -85,11 +85,11 @@ class PossiblyUnreachableDiag { public: PartialDiagnostic PD; SourceLocation Loc; - const Stmt *stmt; + llvm::TinyPtrVector<const Stmt*> Stmts; PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, - const Stmt *stmt) - : PD(PD), Loc(Loc), stmt(stmt) {} + ArrayRef<const Stmt *> Stmts) + : PD(PD), Loc(Loc), Stmts(Stmts) {} }; /// Retains information about a function, method, or block that is @@ -488,6 +488,8 @@ public: /// Clear out the information in this function scope, making it /// suitable for reuse. void Clear(); + + bool isPlainFunction() const { return Kind == SK_Function; } }; class Capture { @@ -507,20 +509,14 @@ class Capture { enum CaptureKind { Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA }; - enum { - IsNestedCapture = 0x1, - IsThisCaptured = 0x2 - }; - /// The variable being captured (if we are not capturing 'this') and whether - /// this is a nested capture, and whether we are capturing 'this' - llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis; + union { + /// If Kind == Cap_VLA, the captured type. + const VariableArrayType *CapturedVLA; - /// Expression to initialize a field of the given type, and the kind of - /// capture (if this is a capture and not an init-capture). The expression - /// is only required if we are capturing ByVal and the variable's type has - /// a non-trivial copy constructor. - llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind; + /// Otherwise, the captured variable (if any). + VarDecl *CapturedVar; + }; /// The source location at which the first capture occurred. SourceLocation Loc; @@ -528,71 +524,91 @@ class Capture { /// The location of the ellipsis that expands a parameter pack. SourceLocation EllipsisLoc; - /// The type as it was captured, which is in effect the type of the - /// non-static data member that would hold the capture. + /// The type as it was captured, which is the type of the non-static data + /// member that would hold the capture. QualType CaptureType; + /// The CaptureKind of this capture. + unsigned Kind : 2; + + /// Whether this is a nested capture (a capture of an enclosing capturing + /// scope's capture). + unsigned Nested : 1; + + /// Whether this is a capture of '*this'. + unsigned CapturesThis : 1; + /// Whether an explicit capture has been odr-used in the body of the /// lambda. - bool ODRUsed = false; + unsigned ODRUsed : 1; /// Whether an explicit capture has been non-odr-used in the body of /// the lambda. - bool NonODRUsed = false; + unsigned NonODRUsed : 1; + + /// Whether the capture is invalid (a capture was required but the entity is + /// non-capturable). + unsigned Invalid : 1; public: Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, - SourceLocation Loc, SourceLocation EllipsisLoc, - QualType CaptureType, Expr *Cpy) - : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0), - InitExprAndCaptureKind( - Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef - : Cap_ByCopy), - Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {} + SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, + bool Invalid) + : CapturedVar(Var), Loc(Loc), EllipsisLoc(EllipsisLoc), + CaptureType(CaptureType), + Kind(Block ? Cap_Block : ByRef ? Cap_ByRef : Cap_ByCopy), + Nested(IsNested), CapturesThis(false), ODRUsed(false), + NonODRUsed(false), Invalid(Invalid) {} enum IsThisCapture { ThisCapture }; Capture(IsThisCapture, bool IsNested, SourceLocation Loc, - QualType CaptureType, Expr *Cpy, const bool ByCopy) - : VarAndNestedAndThis( - nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))), - InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef), - Loc(Loc), CaptureType(CaptureType) {} - - bool isThisCapture() const { - return VarAndNestedAndThis.getInt() & IsThisCaptured; - } - + QualType CaptureType, const bool ByCopy, bool Invalid) + : Loc(Loc), CaptureType(CaptureType), + Kind(ByCopy ? Cap_ByCopy : Cap_ByRef), Nested(IsNested), + CapturesThis(true), ODRUsed(false), NonODRUsed(false), + Invalid(Invalid) {} + + enum IsVLACapture { VLACapture }; + Capture(IsVLACapture, const VariableArrayType *VLA, bool IsNested, + SourceLocation Loc, QualType CaptureType) + : CapturedVLA(VLA), Loc(Loc), CaptureType(CaptureType), Kind(Cap_VLA), + Nested(IsNested), CapturesThis(false), ODRUsed(false), + NonODRUsed(false), Invalid(false) {} + + bool isThisCapture() const { return CapturesThis; } bool isVariableCapture() const { return !isThisCapture() && !isVLATypeCapture(); } - bool isCopyCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByCopy; - } + bool isCopyCapture() const { return Kind == Cap_ByCopy; } + bool isReferenceCapture() const { return Kind == Cap_ByRef; } + bool isBlockCapture() const { return Kind == Cap_Block; } + bool isVLATypeCapture() const { return Kind == Cap_VLA; } - bool isReferenceCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByRef; - } + bool isNested() const { return Nested; } - bool isBlockCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_Block; - } - - bool isVLATypeCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_VLA; - } + bool isInvalid() const { return Invalid; } - bool isNested() const { - return VarAndNestedAndThis.getInt() & IsNestedCapture; - } + /// Determine whether this capture is an init-capture. + bool isInitCapture() const; bool isODRUsed() const { return ODRUsed; } bool isNonODRUsed() const { return NonODRUsed; } - void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; } + void markUsed(bool IsODRUse) { + if (IsODRUse) + ODRUsed = true; + else + NonODRUsed = true; + } VarDecl *getVariable() const { assert(isVariableCapture()); - return VarAndNestedAndThis.getPointer(); + return CapturedVar; + } + + const VariableArrayType *getCapturedVLAType() const { + assert(isVLATypeCapture()); + return CapturedVLA; } /// Retrieve the location at which this variable was captured. @@ -605,15 +621,7 @@ public: /// Retrieve the capture type for this capture, which is effectively /// the type of the non-static data member in the lambda/block structure /// that would store this capture. - QualType getCaptureType() const { - assert(!isThisCapture()); - return CaptureType; - } - - Expr *getInitExpr() const { - assert(!isVLATypeCapture() && "no init expression for type capture"); - return static_cast<Expr *>(InitExprAndCaptureKind.getPointer()); - } + QualType getCaptureType() const { return CaptureType; } }; class CapturingScopeInfo : public FunctionScopeInfo { @@ -651,24 +659,20 @@ public: void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, SourceLocation Loc, SourceLocation EllipsisLoc, - QualType CaptureType, Expr *Cpy) { + QualType CaptureType, bool Invalid) { Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, - EllipsisLoc, CaptureType, Cpy)); + EllipsisLoc, CaptureType, Invalid)); CaptureMap[Var] = Captures.size(); } - void addVLATypeCapture(SourceLocation Loc, QualType CaptureType) { - Captures.push_back(Capture(/*Var*/ nullptr, /*isBlock*/ false, - /*isByref*/ false, /*isNested*/ false, Loc, - /*EllipsisLoc*/ SourceLocation(), CaptureType, - /*Cpy*/ nullptr)); + void addVLATypeCapture(SourceLocation Loc, const VariableArrayType *VLAType, + QualType CaptureType) { + Captures.push_back(Capture(Capture::VLACapture, VLAType, + /*FIXME: IsNested*/ false, Loc, CaptureType)); } - // Note, we do not need to add the type of 'this' since that is always - // retrievable from Sema::getCurrentThisType - and is also encoded within the - // type of the corresponding FieldDecl. - void addThisCapture(bool isNested, SourceLocation Loc, - Expr *Cpy, bool ByCopy); + void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, + bool ByCopy); /// Determine whether the C++ 'this' is captured. bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } @@ -817,16 +821,24 @@ public: /// each 'auto' parameter, during initial AST construction. unsigned AutoTemplateParameterDepth = 0; - /// Store the list of the auto parameters for a generic lambda. - /// If this is a generic lambda, store the list of the auto - /// parameters converted into TemplateTypeParmDecls into a vector - /// that can be used to construct the generic lambda's template - /// parameter list, during initial AST construction. - SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams; + /// The number of parameters in the template parameter list that were + /// explicitly specified by the user, as opposed to being invented by use + /// of an auto parameter. + unsigned NumExplicitTemplateParams = 0; + + /// Source range covering the explicit template parameter list (if it exists). + SourceRange ExplicitTemplateParamsRange; + + /// Store the list of the template parameters for a generic lambda. + /// If this is a generic lambda, this holds the explicit template parameters + /// followed by the auto parameters converted into TemplateTypeParmDecls. + /// It can be used to construct the generic lambda's template parameter list + /// during initial AST construction. + SmallVector<NamedDecl*, 4> TemplateParams; /// If this is a generic lambda, and the template parameter - /// list has been created (from the AutoTemplateParams) then - /// store a reference to it (cache it to avoid reconstructing it). + /// list has been created (from the TemplateParams) then store + /// a reference to it (cache it to avoid reconstructing it). TemplateParameterList *GLTemplateParameterList = nullptr; /// Contains all variable-referring-expressions (i.e. DeclRefExprs @@ -879,9 +891,9 @@ public: } /// Is this scope known to be for a generic lambda? (This will be false until - /// we parse the first 'auto'-typed parameter. + /// we parse a template parameter list or the first 'auto'-typed parameter). bool isGenericLambda() const { - return !AutoTemplateParams.empty() || GLTemplateParameterList; + return !TemplateParams.empty() || GLTemplateParameterList; } /// Add a variable that might potentially be captured by the @@ -902,7 +914,8 @@ public: /// }; /// } void addPotentialCapture(Expr *VarExpr) { - assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr)); + assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr) || + isa<FunctionParmPackExpr>(VarExpr)); PotentiallyCapturingExprs.push_back(VarExpr); } @@ -954,13 +967,15 @@ public: /// building such a node. So we need a rule that anyone can implement and get /// exactly the same result". void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) { - assert(isa<DeclRefExpr>(CapturingVarExpr) - || isa<MemberExpr>(CapturingVarExpr)); + assert(isa<DeclRefExpr>(CapturingVarExpr) || + isa<MemberExpr>(CapturingVarExpr) || + isa<FunctionParmPackExpr>(CapturingVarExpr)); NonODRUsedCapturingExprs.insert(CapturingVarExpr); } bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const { - assert(isa<DeclRefExpr>(CapturingVarExpr) - || isa<MemberExpr>(CapturingVarExpr)); + assert(isa<DeclRefExpr>(CapturingVarExpr) || + isa<MemberExpr>(CapturingVarExpr) || + isa<FunctionParmPackExpr>(CapturingVarExpr)); return NonODRUsedCapturingExprs.count(CapturingVarExpr); } void removePotentialCapture(Expr *E) { @@ -982,9 +997,8 @@ public: PotentialThisCaptureLocation.isValid(); } - // When passed the index, returns the VarDecl and Expr associated - // with the index. - void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const; + void visitPotentialCaptures( + llvm::function_ref<void(VarDecl *, Expr *)> Callback) const; }; FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy() @@ -1004,12 +1018,12 @@ void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { Uses.push_back(WeakUseTy(E, IsRead)); } -inline void -CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, - Expr *Cpy, - const bool ByCopy) { - Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, QualType(), - Cpy, ByCopy)); +inline void CapturingScopeInfo::addThisCapture(bool isNested, + SourceLocation Loc, + QualType CaptureType, + bool ByCopy) { + Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, + ByCopy, /*Invalid*/ false)); CXXThisCaptureIndex = Captures.size(); } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index e5b7465820a9..af762f74d745 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1,9 +1,8 @@ //===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -157,6 +156,7 @@ namespace clang { class OMPDeclareReductionDecl; class OMPDeclareSimdDecl; class OMPClause; + struct OMPVarListLocTy; struct OverloadCandidate; class OverloadCandidateSet; class OverloadExpr; @@ -274,6 +274,56 @@ public: } }; +/// Keeps track of expected type during expression parsing. The type is tied to +/// a particular token, all functions that update or consume the type take a +/// start location of the token they are looking at as a parameter. This allows +/// to avoid updating the type on hot paths in the parser. +class PreferredTypeBuilder { +public: + PreferredTypeBuilder() = default; + explicit PreferredTypeBuilder(QualType Type) : Type(Type) {} + + void enterCondition(Sema &S, SourceLocation Tok); + void enterReturn(Sema &S, SourceLocation Tok); + void enterVariableInit(SourceLocation Tok, Decl *D); + /// Computing a type for the function argument may require running + /// overloading, so we postpone its computation until it is actually needed. + /// + /// Clients should be very careful when using this funciton, as it stores a + /// function_ref, clients should make sure all calls to get() with the same + /// location happen while function_ref is alive. + void enterFunctionArgument(SourceLocation Tok, + llvm::function_ref<QualType()> ComputeType); + + void enterParenExpr(SourceLocation Tok, SourceLocation LParLoc); + void enterUnary(Sema &S, SourceLocation Tok, tok::TokenKind OpKind, + SourceLocation OpLoc); + void enterBinary(Sema &S, SourceLocation Tok, Expr *LHS, tok::TokenKind Op); + void enterMemAccess(Sema &S, SourceLocation Tok, Expr *Base); + void enterSubscript(Sema &S, SourceLocation Tok, Expr *LHS); + /// Handles all type casts, including C-style cast, C++ casts, etc. + void enterTypeCast(SourceLocation Tok, QualType CastType); + + QualType get(SourceLocation Tok) const { + if (Tok != ExpectedLoc) + return QualType(); + if (!Type.isNull()) + return Type; + if (ComputeType) + return ComputeType(); + return QualType(); + } + +private: + /// Start position of a token for which we store expected type. + SourceLocation ExpectedLoc; + /// Expected type for a token starting at ExpectedLoc. + QualType Type; + /// A function to compute expected type at ExpectedLoc. It is only considered + /// if Type is null. + llvm::function_ref<QualType()> ComputeType; +}; + /// Sema - This implements semantic analysis and AST building for C. class Sema { Sema(const Sema &) = delete; @@ -537,15 +587,15 @@ public: /// element type here is ExprWithCleanups::Object. SmallVector<BlockDecl*, 8> ExprCleanupObjects; - /// Store a list of either DeclRefExprs or MemberExprs - /// that contain a reference to a variable (constant) that may or may not - /// be odr-used in this Expr, and we won't know until all lvalue-to-rvalue - /// and discarded value conversions have been applied to all subexpressions - /// of the enclosing full expression. This is cleared at the end of each - /// full expression. - llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs; + /// Store a set of either DeclRefExprs or MemberExprs that contain a reference + /// to a variable (constant) that may or may not be odr-used in this Expr, and + /// we won't know until all lvalue-to-rvalue and discarded value conversions + /// have been applied to all subexpressions of the enclosing full expression. + /// This is cleared at the end of each full expression. + using MaybeODRUseExprSet = llvm::SmallPtrSet<Expr *, 2>; + MaybeODRUseExprSet MaybeODRUseExprs; - std::unique_ptr<sema::FunctionScopeInfo> PreallocatedFunctionScope; + std::unique_ptr<sema::FunctionScopeInfo> CachedFunctionScope; /// Stack containing information about each of the nested /// function, block, and method scopes that are currently active. @@ -632,16 +682,6 @@ public: SmallVector<std::pair<FunctionDecl*, FunctionDecl*>, 2> DelayedEquivalentExceptionSpecChecks; - /// All the members seen during a class definition which were both - /// explicitly defaulted and had explicitly-specified exception - /// specifications, along with the function type containing their - /// user-specified exception specification. Those exception specifications - /// were overridden with the default specifications, but we still need to - /// check whether they are compatible with the default specification, and - /// we can't do that until the nesting set of class definitions is complete. - SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2> - DelayedDefaultedMemberExceptionSpecs; - typedef llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>> LateParsedTemplateMapT; @@ -757,6 +797,15 @@ public: } }; + /// Used to change context to isConstantEvaluated without pushing a heavy + /// ExpressionEvaluationContextRecord object. + bool isConstantEvaluatedOverride; + + bool isConstantEvaluated() { + return ExprEvalContexts.back().isConstantEvaluated() || + isConstantEvaluatedOverride; + } + /// RAII object to handle the state changes required to synthesize /// a function body. class SynthesizedFunctionScope { @@ -979,7 +1028,7 @@ public: /// context (i.e. the number of TypoExprs created). unsigned NumTypos; - llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs; + MaybeODRUseExprSet SavedMaybeODRUseExprs; /// The lambdas that are present within this context, if it /// is indeed an unevaluated context. @@ -1163,6 +1212,11 @@ public: /// of -Wselector. llvm::MapVector<Selector, SourceLocation> ReferencedSelectors; + /// List of SourceLocations where 'self' is implicitly retained inside a + /// block. + llvm::SmallVector<std::pair<SourceLocation, const BlockDecl *>, 1> + ImplicitlyRetainedSelfLocs; + /// Kinds of C++ special members. enum CXXSpecialMember { CXXDefaultConstructor, @@ -1331,8 +1385,21 @@ public: void emitAndClearUnusedLocalTypedefWarnings(); + enum TUFragmentKind { + /// The global module fragment, between 'module;' and a module-declaration. + Global, + /// A normal translation unit fragment. For a non-module unit, this is the + /// entire translation unit. Otherwise, it runs from the module-declaration + /// to the private-module-fragment (if any) or the end of the TU (if not). + Normal, + /// The private module fragment, between 'module :private;' and the end of + /// the translation unit. + Private + }; + void ActOnStartOfTranslationUnit(); void ActOnEndOfTranslationUnit(); + void ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind); void CheckDelegatingCtorCycles(); @@ -1350,10 +1417,24 @@ public: void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, RecordDecl *RD, CapturedRegionKind K); - void + + /// Custom deleter to allow FunctionScopeInfos to be kept alive for a short + /// time after they've been popped. + class PoppedFunctionScopeDeleter { + Sema *Self; + + public: + explicit PoppedFunctionScopeDeleter(Sema *Self) : Self(Self) {} + void operator()(sema::FunctionScopeInfo *Scope) const; + }; + + using PoppedFunctionScopePtr = + std::unique_ptr<sema::FunctionScopeInfo, PoppedFunctionScopeDeleter>; + + PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP = nullptr, const Decl *D = nullptr, - const BlockExpr *blkExpr = nullptr); + QualType BlockType = QualType()); sema::FunctionScopeInfo *getCurFunction() const { return FunctionScopes.empty() ? nullptr : FunctionScopes.back(); @@ -1369,7 +1450,6 @@ public: void PopCompoundScope(); sema::CompoundScopeInfo &getCurCompoundScope() const; - bool isCurCompoundStmtAStmtExpr() const; bool hasAnyUnrecoverableErrorsInThisFunction() const; @@ -1412,6 +1492,10 @@ public: QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc); QualType BuildExtVectorType(QualType T, Expr *ArraySize, SourceLocation AttrLoc); + QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace, + SourceLocation AttrLoc); + + /// Same as above, but constructs the AddressSpace index if not provided. QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace, SourceLocation AttrLoc); @@ -1489,6 +1573,7 @@ public: bool CheckExceptionSpecSubset(const PartialDiagnostic &DiagID, const PartialDiagnostic &NestedDiagID, const PartialDiagnostic &NoteID, + const PartialDiagnostic &NoThrowDiagID, const FunctionProtoType *Superset, SourceLocation SuperLoc, const FunctionProtoType *Subset, @@ -1571,13 +1656,18 @@ private: TypeDiagnoser *Diagnoser); struct ModuleScope { + SourceLocation BeginLoc; clang::Module *Module = nullptr; bool ModuleInterface = false; + bool ImplicitGlobalModuleFragment = false; VisibleModuleSet OuterVisibleModules; }; /// The modules we're currently parsing. llvm::SmallVector<ModuleScope, 16> ModuleScopes; + /// Namespace definitions that we will export when they finish. + llvm::SmallPtrSet<const NamespaceDecl*, 8> DeferredExportedNamespaces; + /// Get the module whose scope we are currently within. Module *getCurrentModule() const { return ModuleScopes.empty() ? nullptr : ModuleScopes.back().Module; @@ -1757,7 +1847,8 @@ public: NC_NestedNameSpecifier, NC_TypeTemplate, NC_VarTemplate, - NC_FunctionTemplate + NC_FunctionTemplate, + NC_UndeclaredTemplate, }; class NameClassification { @@ -1805,6 +1896,12 @@ public: return Result; } + static NameClassification UndeclaredTemplate(TemplateName Name) { + NameClassification Result(NC_UndeclaredTemplate); + Result.Template = Name; + return Result; + } + NameClassificationKind getKind() const { return Kind; } ParsedType getType() const { @@ -1819,7 +1916,7 @@ public: TemplateName getTemplateName() const { assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || - Kind == NC_VarTemplate); + Kind == NC_VarTemplate || Kind == NC_UndeclaredTemplate); return Template; } @@ -1831,6 +1928,8 @@ public: return TNK_Function_template; case NC_VarTemplate: return TNK_Var_template; + case NC_UndeclaredTemplate: + return TNK_Undeclared_template; default: llvm_unreachable("unsupported name classification."); } @@ -1861,11 +1960,11 @@ public: /// expression. /// /// \param CCC The correction callback, if typo correction is desired. - NameClassification - ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, - SourceLocation NameLoc, const Token &NextToken, - bool IsAddressOfOperand, - std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr); + NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, + IdentifierInfo *&Name, SourceLocation NameLoc, + const Token &NextToken, + bool IsAddressOfOperand, + CorrectionCandidateCallback *CCC = nullptr); /// Describes the detailed kind of a template name. Used in diagnostics. enum class TemplateNameKindForDiagnostics { @@ -1874,6 +1973,7 @@ public: VarTemplate, AliasTemplate, TemplateTemplateParam, + Concept, DependentTemplate }; TemplateNameKindForDiagnostics @@ -1964,7 +2064,7 @@ public: bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckVariableDeclarationType(VarDecl *NewVD); bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, - Expr *&Init); + Expr *Init); void CheckCompleteVariableDeclaration(VarDecl *VD); void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD); void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); @@ -1993,7 +2093,9 @@ public: QualType NewT, QualType OldT); void CheckMain(FunctionDecl *FD, const DeclSpec &D); void CheckMSVCRTEntryPoint(FunctionDecl *FD); - Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, bool IsDefinition); + Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, + bool IsDefinition); + void CheckFunctionOrTemplateParamDeclarator(Scope *S, Declarator &D); Decl *ActOnParamDeclarator(Scope *S, Declarator &D); ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, @@ -2012,6 +2114,48 @@ public: bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc); + // Contexts where using non-trivial C union types can be disallowed. This is + // passed to err_non_trivial_c_union_in_invalid_context. + enum NonTrivialCUnionContext { + // Function parameter. + NTCUC_FunctionParam, + // Function return. + NTCUC_FunctionReturn, + // Default-initialized object. + NTCUC_DefaultInitializedObject, + // Variable with automatic storage duration. + NTCUC_AutoVar, + // Initializer expression that might copy from another object. + NTCUC_CopyInit, + // Assignment. + NTCUC_Assignment, + // Compound literal. + NTCUC_CompoundLiteral, + // Block capture. + NTCUC_BlockCapture, + // lvalue-to-rvalue conversion of volatile type. + NTCUC_LValueToRValueVolatile, + }; + + /// Emit diagnostics if the initializer or any of its explicit or + /// implicitly-generated subexpressions require copying or + /// default-initializing a type that is or contains a C union type that is + /// non-trivial to copy or default-initialize. + void checkNonTrivialCUnionInInitializer(const Expr *Init, SourceLocation Loc); + + // These flags are passed to checkNonTrivialCUnion. + enum NonTrivialCUnionKind { + NTCUK_Init = 0x1, + NTCUK_Destruct = 0x2, + NTCUK_Copy = 0x4, + }; + + /// Emit diagnostics if a non-trivial C union type or a struct that contains + /// a non-trivial C union is used in an invalid context. + void checkNonTrivialCUnion(QualType QT, SourceLocation Loc, + NonTrivialCUnionContext UseContext, + unsigned NonTrivialKind); + void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit); void ActOnUninitializedDecl(Decl *dcl); void ActOnInitializerError(Decl *Dcl); @@ -2102,24 +2246,40 @@ public: enum class ModuleDeclKind { Interface, ///< 'export module X;' Implementation, ///< 'module X;' - Partition, ///< 'module partition X;' }; /// The parser has processed a module-declaration that begins the definition /// of a module interface or implementation. DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, - ModuleIdPath Path); + ModuleIdPath Path, bool IsFirstDecl); + + /// The parser has processed a global-module-fragment declaration that begins + /// the definition of the global module fragment of the current module unit. + /// \param ModuleLoc The location of the 'module' keyword. + DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc); + + /// The parser has processed a private-module-fragment declaration that begins + /// the definition of the private module fragment of the current module unit. + /// \param ModuleLoc The location of the 'module' keyword. + /// \param PrivateLoc The location of the 'private' keyword. + DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, + SourceLocation PrivateLoc); /// The parser has processed a module import declaration. /// - /// \param AtLoc The location of the '@' symbol, if any. - /// + /// \param StartLoc The location of the first token in the declaration. This + /// could be the location of an '@', 'export', or 'import'. + /// \param ExportLoc The location of the 'export' keyword, if any. /// \param ImportLoc The location of the 'import' keyword. - /// /// \param Path The module access path. - DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, - ModuleIdPath Path); + DeclResult ActOnModuleImport(SourceLocation StartLoc, + SourceLocation ExportLoc, + SourceLocation ImportLoc, ModuleIdPath Path); + DeclResult ActOnModuleImport(SourceLocation StartLoc, + SourceLocation ExportLoc, + SourceLocation ImportLoc, Module *M, + ModuleIdPath Path = {}); /// The parser has processed a module import translated from a /// #include or similar preprocessing directive. @@ -2413,14 +2573,6 @@ public: /// Add this decl to the scope shadowed decl chains. void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true); - /// Make the given externally-produced declaration visible at the - /// top level scope. - /// - /// \param D The externally-produced declaration to push. - /// - /// \param Name The name of the externally-produced declaration. - void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name); - /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns /// true if 'D' belongs to the given declaration context. @@ -2456,18 +2608,38 @@ public: AMK_ProtocolImplementation, }; + /// Describes the kind of priority given to an availability attribute. + /// + /// The sum of priorities deteremines the final priority of the attribute. + /// The final priority determines how the attribute will be merged. + /// An attribute with a lower priority will always remove higher priority + /// attributes for the specified platform when it is being applied. An + /// attribute with a higher priority will not be applied if the declaration + /// already has an availability attribute with a lower priority for the + /// specified platform. The final prirority values are not expected to match + /// the values in this enumeration, but instead should be treated as a plain + /// integer value. This enumeration just names the priority weights that are + /// used to calculate that final vaue. + enum AvailabilityPriority : int { + /// The availability attribute was specified explicitly next to the + /// declaration. + AP_Explicit = 0, + + /// The availability attribute was applied using '#pragma clang attribute'. + AP_PragmaClangAttribute = 1, + + /// The availability attribute for a specific platform was inferred from + /// an availability attribute for another platform. + AP_InferredFromOtherPlatform = 2 + }; + /// Attribute merging methods. Return true if a new attribute was added. - AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, - IdentifierInfo *Platform, - bool Implicit, - VersionTuple Introduced, - VersionTuple Deprecated, - VersionTuple Obsoleted, - bool IsUnavailable, - StringRef Message, - bool IsStrict, StringRef Replacement, - AvailabilityMergeKind AMK, - unsigned AttrSpellingListIndex); + AvailabilityAttr *mergeAvailabilityAttr( + NamedDecl *D, SourceRange Range, IdentifierInfo *Platform, bool Implicit, + VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, + bool IsUnavailable, StringRef Message, bool IsStrict, + StringRef Replacement, AvailabilityMergeKind AMK, int Priority, + unsigned AttrSpellingListIndex); TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range, TypeVisibilityAttr::VisibilityType Vis, unsigned AttrSpellingListIndex); @@ -2496,6 +2668,12 @@ public: unsigned AttrSpellingListIndex); MinSizeAttr *mergeMinSizeAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex); + NoSpeculativeLoadHardeningAttr * + mergeNoSpeculativeLoadHardeningAttr(Decl *D, + const NoSpeculativeLoadHardeningAttr &AL); + SpeculativeLoadHardeningAttr * + mergeSpeculativeLoadHardeningAttr(Decl *D, + const SpeculativeLoadHardeningAttr &AL); OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex); InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL); @@ -2555,13 +2733,6 @@ public: bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl, bool ConsiderCudaAttrs = true); - /// Checks availability of the function depending on the current - /// function context.Inside an unavailable function,unavailability is ignored. - /// - /// \returns true if \p FD is unavailable and current context is inside - /// an available function, false otherwise. - bool isFunctionConsideredUnavailable(FunctionDecl *FD); - ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, @@ -2641,7 +2812,8 @@ public: CCEK_Enumerator, ///< Enumerator value with fixed underlying type. CCEK_TemplateArg, ///< Value of a non-type template parameter. CCEK_NewExpr, ///< Constant expression in a noptr-new-declarator. - CCEK_ConstexprIf ///< Condition in a constexpr if statement. + CCEK_ConstexprIf, ///< Condition in a constexpr if statement. + CCEK_ExplicitBool ///< Condition in an explicit(bool) specifier. }; ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE); @@ -2763,7 +2935,8 @@ public: OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false, bool PartialOverloading = false, - bool AllowExplicit = false, + bool AllowExplicit = true, + bool AllowExplicitConversion = false, ADLCallKind IsADLCandidate = ADLCallKind::NotADL, ConversionSequenceList EarlyConversions = None); void AddFunctionCandidates(const UnresolvedSetImpl &Functions, @@ -2802,7 +2975,7 @@ public: FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false, - bool PartialOverloading = false, + bool PartialOverloading = false, bool AllowExplicit = true, ADLCallKind IsADLCandidate = ADLCallKind::NotADL); bool CheckNonDependentConversions(FunctionTemplateDecl *FunctionTemplate, ArrayRef<QualType> ParamTypes, @@ -2814,20 +2987,16 @@ public: QualType ObjectType = QualType(), Expr::Classification ObjectClassification = {}); - void AddConversionCandidate(CXXConversionDecl *Conversion, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, - Expr *From, QualType ToType, - OverloadCandidateSet& CandidateSet, - bool AllowObjCConversionOnExplicit, - bool AllowResultConversion = true); - void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, - Expr *From, QualType ToType, - OverloadCandidateSet &CandidateSet, - bool AllowObjCConversionOnExplicit, - bool AllowResultConversion = true); + void AddConversionCandidate( + CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, + CXXRecordDecl *ActingContext, Expr *From, QualType ToType, + OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, + bool AllowExplicit, bool AllowResultConversion = true); + void AddTemplateConversionCandidate( + FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, + CXXRecordDecl *ActingContext, Expr *From, QualType ToType, + OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, + bool AllowExplicit, bool AllowResultConversion = true); void AddSurrogateCandidate(CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, @@ -3091,6 +3260,8 @@ public: LookupObjCImplicitSelfParam, /// Look up the name of an OpenMP user-defined reduction operation. LookupOMPReductionName, + /// Look up the name of an OpenMP user-defined mapper. + LookupOMPMapperName, /// Look up any declaration with any name. LookupAnyName }; @@ -3192,7 +3363,7 @@ private: makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback &CCC, DeclContext *MemberContext, bool EnteringContext, const ObjCObjectPointerType *OPT, bool ErrorRecovery); @@ -3276,7 +3447,7 @@ public: TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext = nullptr, bool EnteringContext = false, @@ -3286,7 +3457,7 @@ public: TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback &CCC, TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode, DeclContext *MemberContext = nullptr, @@ -3411,7 +3582,7 @@ public: // Check if there is an explicit attribute, but only look through parens. // The intent is to look for an attribute on the current declarator, but not // one that came from a typedef. - bool hasExplicitCallingConv(QualType &T); + bool hasExplicitCallingConv(QualType T); /// Get the outermost AttributedType node that sets a calling convention. /// Valid types should not have multiple attributes with different CCs. @@ -3869,6 +4040,7 @@ public: unsigned NumInputs, IdentifierInfo **Names, MultiExprArg Constraints, MultiExprArg Exprs, Expr *AsmString, MultiExprArg Clobbers, + unsigned NumLabels, SourceLocation RParenLoc); void FillInlineAsmIdentifierInfo(Expr *Res, @@ -4021,7 +4193,6 @@ public: ObjCInterfaceDecl *ClassReciever = nullptr); void NoteDeletedFunction(FunctionDecl *FD); void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD); - std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD); bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc); @@ -4064,8 +4235,11 @@ public: void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var); void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base = nullptr); void MarkMemberReferenced(MemberExpr *E); + void MarkFunctionParmPackReferenced(FunctionParmPackExpr *E); + void MarkCaptureUsedInEnclosingContext(VarDecl *Capture, SourceLocation Loc, + unsigned CapturingScopeIndex); - void UpdateMarkingForLValueToRValue(Expr *E); + ExprResult CheckLValueToRValueConversionOperand(Expr *E); void CleanupVarDeclMarking(); enum TryCaptureKind { @@ -4150,6 +4324,10 @@ public: /// If it is unreachable, the diagnostic will not be emitted. bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD); + /// Similar, but diagnostic is only produced if all the specified statements + /// are reachable. + bool DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt*> Stmts, + const PartialDiagnostic &PD); // Primary Expressions. SourceRange getExprRange(Expr *E) const; @@ -4157,7 +4335,7 @@ public: ExprResult ActOnIdExpression( Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, - std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr, + CorrectionCandidateCallback *CCC = nullptr, bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr); void DecomposeUnqualifiedId(const UnqualifiedId &Id, @@ -4167,7 +4345,7 @@ public: bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - std::unique_ptr<CorrectionCandidateCallback> CCC, + CorrectionCandidateCallback &CCC, TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr); @@ -4181,16 +4359,28 @@ public: bool isAddressOfOperand, const TemplateArgumentListInfo *TemplateArgs); - ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, - ExprValueKind VK, - SourceLocation Loc, - const CXXScopeSpec *SS = nullptr); - ExprResult + /// If \p D cannot be odr-used in the current expression evaluation context, + /// return a reason explaining why. Otherwise, return NOUR_None. + NonOdrUseReason getNonOdrUseReasonInCurrentContext(ValueDecl *D); + + DeclRefExpr *BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, + SourceLocation Loc, + const CXXScopeSpec *SS = nullptr); + DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, const DeclarationNameInfo &NameInfo, const CXXScopeSpec *SS = nullptr, NamedDecl *FoundD = nullptr, + SourceLocation TemplateKWLoc = SourceLocation(), + const TemplateArgumentListInfo *TemplateArgs = nullptr); + DeclRefExpr * + BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, + const DeclarationNameInfo &NameInfo, + NestedNameSpecifierLoc NNS, + NamedDecl *FoundD = nullptr, + SourceLocation TemplateKWLoc = SourceLocation(), const TemplateArgumentListInfo *TemplateArgs = nullptr); + ExprResult BuildAnonymousStructUnionMemberReference( const CXXScopeSpec &SS, @@ -4378,6 +4568,23 @@ public: UnqualifiedId &Member, Decl *ObjCImpDecl); + MemberExpr * + BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, + const CXXScopeSpec *SS, SourceLocation TemplateKWLoc, + ValueDecl *Member, DeclAccessPair FoundDecl, + bool HadMultipleCandidates, + const DeclarationNameInfo &MemberNameInfo, QualType Ty, + ExprValueKind VK, ExprObjectKind OK, + const TemplateArgumentListInfo *TemplateArgs = nullptr); + MemberExpr * + BuildMemberExpr(Expr *Base, bool IsArrow, SourceLocation OpLoc, + NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, + ValueDecl *Member, DeclAccessPair FoundDecl, + bool HadMultipleCandidates, + const DeclarationNameInfo &MemberNameInfo, QualType Ty, + ExprValueKind VK, ExprObjectKind OK, + const TemplateArgumentListInfo *TemplateArgs = nullptr); + void ActOnDefaultCtorInitializers(Decl *CDtorDecl); bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, FunctionDecl *FDecl, @@ -4394,6 +4601,9 @@ public: /// locations. ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, + Expr *ExecConfig = nullptr); + ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, + MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig = nullptr, bool IsExecConfig = false); ExprResult @@ -4467,6 +4677,8 @@ public: void ActOnStartStmtExpr(); ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc); // "({..})" + // Handle the final expression in a statement expression. + ExprResult ActOnStmtExprResult(ExprResult E); void ActOnStmtExprError(); // __builtin_offsetof(type, identifier(.identifier|[expr])*) @@ -4502,6 +4714,17 @@ public: ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, TypeSourceInfo *TInfo, SourceLocation RPLoc); + // __builtin_LINE(), __builtin_FUNCTION(), __builtin_FILE(), + // __builtin_COLUMN() + ExprResult ActOnSourceLocExpr(SourceLocExpr::IdentKind Kind, + SourceLocation BuiltinLoc, + SourceLocation RPLoc); + + // Build a potentially resolved SourceLocExpr. + ExprResult BuildSourceLocExpr(SourceLocExpr::IdentKind Kind, + SourceLocation BuiltinLoc, SourceLocation RPLoc, + DeclContext *ParentContext); + // __null ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc); @@ -5056,6 +5279,13 @@ public: SourceRange AngleBrackets, SourceRange Parens); + ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, + ExprResult Operand, + SourceLocation RParenLoc); + + ExprResult BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, + Expr *Operand, SourceLocation RParenLoc); + ExprResult BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, @@ -5094,13 +5324,18 @@ public: ExprResult BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Operator, SourceLocation EllipsisLoc, Expr *RHS, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + Optional<unsigned> NumExpansions); ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, BinaryOperatorKind Operator); //// ActOnCXXThis - Parse 'this' pointer. ExprResult ActOnCXXThis(SourceLocation loc); + /// Build a CXXThisExpr and mark it referenced in the current context. + Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit); + void MarkThisReferenced(CXXThisExpr *This); + /// Try to retrieve the type of the 'this' pointer. /// /// \returns The type of 'this', if possible. Otherwise, returns a NULL type. @@ -5204,7 +5439,7 @@ public: SourceRange TypeIdParens, QualType AllocType, TypeSourceInfo *AllocTypeInfo, - Expr *ArraySize, + Optional<Expr *> ArraySize, SourceRange DirectInitRange, Expr *Initializer); @@ -5568,12 +5803,12 @@ public: LambdaCaptureDefault CaptureDefault); /// Start the definition of a lambda expression. - CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class, - SourceRange IntroducerRange, - TypeSourceInfo *MethodType, - SourceLocation EndLoc, - ArrayRef<ParmVarDecl *> Params, - bool IsConstexprSpecified); + CXXMethodDecl * + startLambdaDefinition(CXXRecordDecl *Class, SourceRange IntroducerRange, + TypeSourceInfo *MethodType, SourceLocation EndLoc, + ArrayRef<ParmVarDecl *> Params, + ConstexprSpecKind ConstexprKind, + Optional<std::pair<unsigned, Decl *>> Mangling = None); /// Endow the lambda scope info with the relevant properties. void buildLambdaScope(sema::LambdaScopeInfo *LSI, @@ -5589,14 +5824,16 @@ public: /// any implicit conversions such as an lvalue-to-rvalue conversion if /// not being used to initialize a reference. ParsedType actOnLambdaInitCaptureInitialization( - SourceLocation Loc, bool ByRef, IdentifierInfo *Id, - LambdaCaptureInitKind InitKind, Expr *&Init) { + SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, + IdentifierInfo *Id, LambdaCaptureInitKind InitKind, Expr *&Init) { return ParsedType::make(buildLambdaInitCaptureInitialization( - Loc, ByRef, Id, InitKind != LambdaCaptureInitKind::CopyInit, Init)); + Loc, ByRef, EllipsisLoc, None, Id, + InitKind != LambdaCaptureInitKind::CopyInit, Init)); } - QualType buildLambdaInitCaptureInitialization(SourceLocation Loc, bool ByRef, - IdentifierInfo *Id, - bool DirectInit, Expr *&Init); + QualType buildLambdaInitCaptureInitialization( + SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, + Optional<unsigned> NumExpansions, IdentifierInfo *Id, bool DirectInit, + Expr *&Init); /// Create a dummy variable within the declcontext of the lambda's /// call operator, for name lookup purposes for a lambda init capture. @@ -5605,16 +5842,23 @@ public: /// variables appropriately. VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, QualType InitCaptureType, + SourceLocation EllipsisLoc, IdentifierInfo *Id, unsigned InitStyle, Expr *Init); - /// Build the implicit field for an init-capture. - FieldDecl *buildInitCaptureField(sema::LambdaScopeInfo *LSI, VarDecl *Var); + /// Add an init-capture to a lambda scope. + void addInitCapture(sema::LambdaScopeInfo *LSI, VarDecl *Var); /// Note that we have finished the explicit captures for the /// given lambda. void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI); + /// \brief This is called after parsing the explicit template parameter list + /// on a lambda (if it exists) in C++2a. + void ActOnLambdaExplicitTemplateParameterList(SourceLocation LAngleLoc, + ArrayRef<NamedDecl *> TParams, + SourceLocation RAngleLoc); + /// Introduce the lambda parameters into scope. void addLambdaParameters( ArrayRef<LambdaIntroducer::LambdaCapture> Captures, @@ -5649,6 +5893,14 @@ public: bool DiagnoseUnusedLambdaCapture(SourceRange CaptureRange, const sema::Capture &From); + /// Build a FieldDecl suitable to hold the given capture. + FieldDecl *BuildCaptureField(RecordDecl *RD, const sema::Capture &Capture); + + /// Initialize the given capture with a suitable expression. + ExprResult BuildCaptureInit(const sema::Capture &Capture, + SourceLocation ImplicitCaptureLoc, + bool IsOpenMPMapping = false); + /// Complete a lambda-expression having processed and attached the /// lambda body. ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, @@ -5868,8 +6120,8 @@ public: /// MarkVirtualMembersReferenced - Will mark all members of the given /// CXXRecordDecl referenced. - void MarkVirtualMembersReferenced(SourceLocation Loc, - const CXXRecordDecl *RD); + void MarkVirtualMembersReferenced(SourceLocation Loc, const CXXRecordDecl *RD, + bool ConstexprOnly = false); /// Define all of the vtables that have been used in this /// translation unit and reference any virtual members used by those @@ -5956,8 +6208,6 @@ public: void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD); void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD); - void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD, - const FunctionProtoType *T); void CheckDelayedMemberExceptionSpecs(); //===--------------------------------------------------------------------===// @@ -6145,14 +6395,37 @@ public: // C++ Templates [C++ 14] // void FilterAcceptableTemplateNames(LookupResult &R, - bool AllowFunctionTemplates = true); + bool AllowFunctionTemplates = true, + bool AllowDependent = true); bool hasAnyAcceptableTemplateNames(LookupResult &R, - bool AllowFunctionTemplates = true); - + bool AllowFunctionTemplates = true, + bool AllowDependent = true, + bool AllowNonTemplateFunctions = false); + /// Try to interpret the lookup result D as a template-name. + /// + /// \param D A declaration found by name lookup. + /// \param AllowFunctionTemplates Whether function templates should be + /// considered valid results. + /// \param AllowDependent Whether unresolved using declarations (that might + /// name templates) should be considered valid results. + NamedDecl *getAsTemplateNameDecl(NamedDecl *D, + bool AllowFunctionTemplates = true, + bool AllowDependent = true); + + enum class AssumedTemplateKind { + /// This is not assumed to be a template name. + None, + /// This is assumed to be a template name because lookup found nothing. + FoundNothing, + /// This is assumed to be a template name because lookup found one or more + /// functions (but no function templates). + FoundFunctions, + }; bool LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType, bool EnteringContext, bool &MemberOfUnknownSpecialization, - SourceLocation TemplateKWLoc = SourceLocation()); + SourceLocation TemplateKWLoc = SourceLocation(), + AssumedTemplateKind *ATK = nullptr); TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, @@ -6163,6 +6436,20 @@ public: TemplateTy &Template, bool &MemberOfUnknownSpecialization); + /// Try to resolve an undeclared template name as a type template. + /// + /// Sets II to the identifier corresponding to the template name, and updates + /// Name to a corresponding (typo-corrected) type template name and TNK to + /// the corresponding kind, if possible. + void ActOnUndeclaredTypeTemplateName(Scope *S, TemplateTy &Name, + TemplateNameKind &TNK, + SourceLocation NameLoc, + IdentifierInfo *&II); + + bool resolveAssumedTemplateNameAsType(Scope *S, TemplateName &Name, + SourceLocation NameLoc, + bool Diagnose = true); + /// Determine whether a particular identifier might be the name in a C++1z /// deduction-guide declaration. bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, @@ -6272,14 +6559,11 @@ public: TemplateArgumentListInfo &TemplateArgs); TypeResult - ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, + ActOnTemplateIdType(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, TemplateTy Template, IdentifierInfo *TemplateII, - SourceLocation TemplateIILoc, - SourceLocation LAngleLoc, - ASTTemplateArgsPtr TemplateArgs, - SourceLocation RAngleLoc, - bool IsCtorOrDtorName = false, - bool IsClassName = false); + SourceLocation TemplateIILoc, SourceLocation LAngleLoc, + ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, + bool IsCtorOrDtorName = false, bool IsClassName = false); /// Parsed an elaborated-type-specifier that refers to a template-id, /// such as \c class T::template apply<U>. @@ -6310,6 +6594,13 @@ public: SourceLocation TemplateLoc, const TemplateArgumentListInfo *TemplateArgs); + ExprResult + CheckConceptTemplateId(const CXXScopeSpec &SS, + const DeclarationNameInfo &NameInfo, + ConceptDecl *Template, + SourceLocation TemplateLoc, + const TemplateArgumentListInfo *TemplateArgs); + void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc); ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, @@ -6577,6 +6868,11 @@ public: const TemplateArgument *Args, unsigned NumArgs); + // Concepts + Decl *ActOnConceptDefinition( + Scope *S, MultiTemplateParamsArg TemplateParameterLists, + IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr); + //===--------------------------------------------------------------------===// // C++ Variadic Templates (C++0x [temp.variadic]) //===--------------------------------------------------------------------===// @@ -7099,7 +7395,7 @@ public: QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, QualType Type, TypeSourceInfo *TSI, SourceRange Range, bool DirectInit, - Expr *&Init); + Expr *Init); TypeLoc getReturnTypeLoc(FunctionDecl *FD) const; @@ -7271,8 +7567,10 @@ public: SourceRange InstantiationRange; CodeSynthesisContext() - : Kind(TemplateInstantiation), Entity(nullptr), Template(nullptr), - TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {} + : Kind(TemplateInstantiation), + SavedInNonInstantiationSFINAEContext(false), Entity(nullptr), + Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0), + DeductionInfo(nullptr) {} /// Determines whether this template is an actual instantiation /// that should be counted toward the maximum instantiation depth. @@ -7925,7 +8223,8 @@ public: LateInstantiatedAttrVec *LateAttrs, DeclContext *Owner, LocalInstantiationScope *StartingScope, - bool InstantiatingVarTemplate = false); + bool InstantiatingVarTemplate = false, + VarTemplateSpecializationDecl *PrevVTSD = nullptr); void InstantiateVariableInitializer( VarDecl *Var, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -8018,17 +8317,19 @@ public: const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList); - Decl *ActOnStartClassImplementation( - SourceLocation AtClassImplLoc, - IdentifierInfo *ClassName, SourceLocation ClassLoc, - IdentifierInfo *SuperClassname, - SourceLocation SuperClassLoc); + Decl *ActOnStartClassImplementation(SourceLocation AtClassImplLoc, + IdentifierInfo *ClassName, + SourceLocation ClassLoc, + IdentifierInfo *SuperClassname, + SourceLocation SuperClassLoc, + const ParsedAttributesView &AttrList); Decl *ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *CatName, - SourceLocation CatLoc); + SourceLocation CatLoc, + const ParsedAttributesView &AttrList); DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef<Decl *> Decls); @@ -8579,6 +8880,16 @@ public: void AddXConsumedAttr(Decl *D, SourceRange SR, unsigned SpellingIndex, RetainOwnershipKind K, bool IsTemplateInstantiation); + /// addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size + /// attribute to a particular declaration. + void addAMDGPUFlatWorkGroupSizeAttr(SourceRange AttrRange, Decl *D, Expr *Min, + Expr *Max, unsigned SpellingListIndex); + + /// addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a + /// particular declaration. + void addAMDGPUWavesPerEUAttr(SourceRange AttrRange, Decl *D, Expr *Min, + Expr *Max, unsigned SpellingListIndex); + bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type); //===--------------------------------------------------------------------===// @@ -8697,6 +9008,13 @@ private: /// Pop OpenMP function region for non-capturing function. void popOpenMPFunctionRegion(const sema::FunctionScopeInfo *OldFSI); + /// Check whether we're allowed to call Callee from the current function. + void checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee); + + /// Check if the expression is allowed to be used in expressions for the + /// OpenMP devices. + void checkOpenMPDeviceExpr(const Expr *E); + /// Checks if a type or a declaration is disabled due to the owning extension /// being disabled, and emits diagnostic messages if it is disabled. /// \param D type or declaration to be checked. @@ -8713,6 +9031,10 @@ private: SourceRange SrcRange = SourceRange()); public: + /// Function tries to capture lambda's captured variables in the OpenMP region + /// before the original lambda is captured. + void tryCaptureOpenMPLambdas(ValueDecl *V); + /// Return true if the provided declaration \a VD should be captured by /// reference. /// \param Level Relative level of nested OpenMP construct for that the check @@ -8722,7 +9044,8 @@ public: /// Check if the specified variable is used in one of the private /// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP /// constructs. - VarDecl *isOpenMPCapturedDecl(ValueDecl *D); + VarDecl *isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo = false, + unsigned StopAt = 0); ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc); @@ -8767,9 +9090,9 @@ public: // OpenMP directives and clauses. /// Called on correct id-expression from the '#pragma omp /// threadprivate'. - ExprResult ActOnOpenMPIdExpression(Scope *CurScope, - CXXScopeSpec &ScopeSpec, - const DeclarationNameInfo &Id); + ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, + const DeclarationNameInfo &Id, + OpenMPDirectiveKind Kind); /// Called on well-formed '#pragma omp threadprivate'. DeclGroupPtrTy ActOnOpenMPThreadprivateDirective( SourceLocation Loc, @@ -8777,6 +9100,11 @@ public: /// Builds a new OpenMPThreadPrivateDecl and checks its correctness. OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList); + /// Called on well-formed '#pragma omp allocate'. + DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, + ArrayRef<Expr *> VarList, + ArrayRef<OMPClause *> Clauses, + DeclContext *Owner = nullptr); /// Called on well-formed '#pragma omp requires'. DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef<OMPClause *> ClauseList); @@ -8806,6 +9134,27 @@ public: DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd( Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid); + /// Check variable declaration in 'omp declare mapper' construct. + TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D); + /// Check if the specified type is allowed to be used in 'omp declare + /// mapper' construct. + QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, + TypeResult ParsedType); + /// Called on start of '#pragma omp declare mapper'. + OMPDeclareMapperDecl *ActOnOpenMPDeclareMapperDirectiveStart( + Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, + SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, + Decl *PrevDeclInScope = nullptr); + /// Build the mapper variable of '#pragma omp declare mapper'. + void ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, + Scope *S, QualType MapperType, + SourceLocation StartLoc, + DeclarationName VN); + /// Called at the end of '#pragma omp declare mapper'. + DeclGroupPtrTy + ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, + ArrayRef<OMPClause *> ClauseList); + /// Called on the start of target region i.e. '#pragma omp declare target'. bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc); /// Called at the end of target region i.e. '#pragme omp end declare target'. @@ -8825,12 +9174,6 @@ public: } /// Return true inside OpenMP target region. bool isInOpenMPTargetExecutionDirective() const; - /// Return true if (un)supported features for the current target should be - /// diagnosed if OpenMP (offloading) is enabled. - bool shouldDiagnoseTargetSupportFromOpenMP() const { - return !getLangOpts().OpenMPIsDevice || isInOpenMPDeclareTargetContext() || - isInOpenMPTargetExecutionDirective(); - } /// Return the number of captured regions created for an OpenMP directive. static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind); @@ -9110,6 +9453,11 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// Called on well-formed 'allocator' clause. + OMPClause *ActOnOpenMPAllocatorClause(Expr *Allocator, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// Called on well-formed 'if' clause. OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, @@ -9176,7 +9524,7 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); - + OMPClause *ActOnOpenMPSingleExprWithArgClause( OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -9231,7 +9579,7 @@ public: /// Called on well-formed 'unified_address' clause. OMPClause *ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc); - + /// Called on well-formed 'reverse_offload' clause. OMPClause *ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc); @@ -9247,15 +9595,18 @@ public: OMPClause *ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ColonLoc, SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, + const OMPVarListLocTy &Locs, SourceLocation ColonLoc, + CXXScopeSpec &ReductionOrMapperIdScopeSpec, + DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, - ArrayRef<SourceLocation> MapTypeModifiersLoc, - OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, - SourceLocation DepLinMapLoc); + ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, + bool IsMapTypeImplicit, SourceLocation DepLinMapLoc); + /// Called on well-formed 'allocate' clause. + OMPClause * + ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList, + SourceLocation StartLoc, SourceLocation ColonLoc, + SourceLocation LParenLoc, SourceLocation EndLoc); /// Called on well-formed 'private' clause. OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, @@ -9339,10 +9690,12 @@ public: OMPClause * ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, ArrayRef<SourceLocation> MapTypeModifiersLoc, + CXXScopeSpec &MapperIdScopeSpec, + DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, - ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc); + ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, + ArrayRef<Expr *> UnresolvedMappers = llvm::None); /// Called on well-formed 'num_teams' clause. OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -9367,25 +9720,22 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc); /// Called on well-formed 'to' clause. - OMPClause *ActOnOpenMPToClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); + OMPClause * + ActOnOpenMPToClause(ArrayRef<Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec, + DeclarationNameInfo &MapperId, + const OMPVarListLocTy &Locs, + ArrayRef<Expr *> UnresolvedMappers = llvm::None); /// Called on well-formed 'from' clause. - OMPClause *ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); + OMPClause *ActOnOpenMPFromClause( + ArrayRef<Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec, + DeclarationNameInfo &MapperId, const OMPVarListLocTy &Locs, + ArrayRef<Expr *> UnresolvedMappers = llvm::None); /// Called on well-formed 'use_device_ptr' clause. OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); + const OMPVarListLocTy &Locs); /// Called on well-formed 'is_device_ptr' clause. OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); + const OMPVarListLocTy &Locs); /// The kind of conversion being performed. enum CheckedConversionKind { @@ -9554,6 +9904,12 @@ public: /// like address spaces. IncompatiblePointerDiscardsQualifiers, + /// IncompatibleNestedPointerAddressSpaceMismatch - The assignment + /// changes address spaces in nested pointer types which is not allowed. + /// For instance, converting __private int ** to __generic int ** is + /// illegal even though __private could be converted to __generic. + IncompatibleNestedPointerAddressSpaceMismatch, + /// IncompatibleNestedPointerQualifiers - The assignment is between two /// nested pointer types, and the qualifiers other than the first two /// levels differ e.g. char ** -> const char **, but we accept them as an @@ -9949,6 +10305,14 @@ public: ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr = false); + /// ActOnExplicitBoolSpecifier - Build an ExplicitSpecifier from an expression + /// found in an explicit(bool) specifier. + ExplicitSpecifier ActOnExplicitBoolSpecifier(Expr *E); + + /// tryResolveExplicitSpecifier - Attempt to resolve the explict specifier. + /// Returns true if the explicit specifier is now resolved. + bool tryResolveExplicitSpecifier(ExplicitSpecifier &ExplicitSpec); + /// DiagnoseAssignmentAsCondition - Given that an expression is /// being used as a boolean condition, warn if it's an assignment. void DiagnoseAssignmentAsCondition(Expr *E); @@ -10024,7 +10388,7 @@ public: /// compilation, this is currently only enabled for CUDA compilations. llvm::DenseMap<CanonicalDeclPtr<FunctionDecl>, std::vector<PartialDiagnosticAt>> - CUDADeferredDiags; + DeviceDeferredDiags; /// A pair of a canonical FunctionDecl and a SourceLocation. When used as the /// key in a hashtable, both the FD and location are hashed. @@ -10045,21 +10409,22 @@ public: /// map. llvm::DenseMap</* Callee = */ CanonicalDeclPtr<FunctionDecl>, /* Caller = */ FunctionDeclAndLoc> - CUDAKnownEmittedFns; + DeviceKnownEmittedFns; - /// A partial call graph maintained during CUDA compilation to support - /// deferred diagnostics. + /// A partial call graph maintained during CUDA/OpenMP device code compilation + /// to support deferred diagnostics. /// /// Functions are only added here if, at the time they're considered, they are /// not known-emitted. As soon as we discover that a function is /// known-emitted, we remove it and everything it transitively calls from this - /// set and add those functions to CUDAKnownEmittedFns. + /// set and add those functions to DeviceKnownEmittedFns. llvm::DenseMap</* Caller = */ CanonicalDeclPtr<FunctionDecl>, /* Callees = */ llvm::MapVector<CanonicalDeclPtr<FunctionDecl>, SourceLocation>> - CUDACallGraph; + DeviceCallGraph; - /// Diagnostic builder for CUDA errors which may or may not be deferred. + /// Diagnostic builder for CUDA/OpenMP devices errors which may or may not be + /// deferred. /// /// In CUDA, there exist constructs (e.g. variable-length arrays, try/catch) /// which are not allowed to appear inside __device__ functions and are @@ -10073,7 +10438,7 @@ public: /// diagnostic, or no diagnostic at all, according to an argument you pass to /// its constructor, thus simplifying the process of creating these "maybe /// deferred" diagnostics. - class CUDADiagBuilder { + class DeviceDiagBuilder { public: enum Kind { /// Emit no diagnostics. @@ -10090,29 +10455,32 @@ public: K_Deferred }; - CUDADiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID, - FunctionDecl *Fn, Sema &S); - ~CUDADiagBuilder(); + DeviceDiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID, + FunctionDecl *Fn, Sema &S); + DeviceDiagBuilder(DeviceDiagBuilder &&D); + DeviceDiagBuilder(const DeviceDiagBuilder &) = default; + ~DeviceDiagBuilder(); /// Convertible to bool: True if we immediately emitted an error, false if /// we didn't emit an error or we created a deferred error. /// /// Example usage: /// - /// if (CUDADiagBuilder(...) << foo << bar) + /// if (DeviceDiagBuilder(...) << foo << bar) /// return ExprError(); /// /// But see CUDADiagIfDeviceCode() and CUDADiagIfHostCode() -- you probably - /// want to use these instead of creating a CUDADiagBuilder yourself. + /// want to use these instead of creating a DeviceDiagBuilder yourself. operator bool() const { return ImmediateDiag.hasValue(); } template <typename T> - friend const CUDADiagBuilder &operator<<(const CUDADiagBuilder &Diag, - const T &Value) { + friend const DeviceDiagBuilder &operator<<(const DeviceDiagBuilder &Diag, + const T &Value) { if (Diag.ImmediateDiag.hasValue()) *Diag.ImmediateDiag << Value; - else if (Diag.PartialDiag.hasValue()) - *Diag.PartialDiag << Value; + else if (Diag.PartialDiagId.hasValue()) + Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second + << Value; return Diag; } @@ -10126,10 +10494,18 @@ public: // Invariant: At most one of these Optionals has a value. // FIXME: Switch these to a Variant once that exists. llvm::Optional<SemaDiagnosticBuilder> ImmediateDiag; - llvm::Optional<PartialDiagnostic> PartialDiag; + llvm::Optional<unsigned> PartialDiagId; }; - /// Creates a CUDADiagBuilder that emits the diagnostic if the current context + /// Indicate that this function (and thus everything it transtively calls) + /// will be codegen'ed, and emit any deferred diagnostics on this function and + /// its (transitive) callees. + void markKnownEmitted( + Sema &S, FunctionDecl *OrigCaller, FunctionDecl *OrigCallee, + SourceLocation OrigLoc, + const llvm::function_ref<bool(Sema &, FunctionDecl *)> IsKnownEmitted); + + /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context /// is "used as device code". /// /// - If CurContext is a __host__ function, does not emit any diagnostics. @@ -10145,13 +10521,32 @@ public: /// if (CUDADiagIfDeviceCode(Loc, diag::err_cuda_vla) << CurrentCUDATarget()) /// return ExprError(); /// // Otherwise, continue parsing as normal. - CUDADiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); + DeviceDiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); - /// Creates a CUDADiagBuilder that emits the diagnostic if the current context + /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context /// is "used as host code". /// /// Same as CUDADiagIfDeviceCode, with "host" and "device" switched. - CUDADiagBuilder CUDADiagIfHostCode(SourceLocation Loc, unsigned DiagID); + DeviceDiagBuilder CUDADiagIfHostCode(SourceLocation Loc, unsigned DiagID); + + /// Creates a DeviceDiagBuilder that emits the diagnostic if the current + /// context is "used as device code". + /// + /// - If CurContext is a `declare target` function or it is known that the + /// function is emitted for the device, emits the diagnostics immediately. + /// - If CurContext is a non-`declare target` function and we are compiling + /// for the device, creates a diagnostic which is emitted if and when we + /// realize that the function will be codegen'ed. + /// + /// Example usage: + /// + /// // Variable-length arrays are not allowed in NVPTX device code. + /// if (diagIfOpenMPDeviceCode(Loc, diag::err_vla_unsupported)) + /// return ExprError(); + /// // Otherwise, continue parsing as normal. + DeviceDiagBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID); + + DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID); enum CUDAFunctionTarget { CFT_Device, @@ -10284,6 +10679,11 @@ public: /// Copies target attributes from the template TD to the function FD. void inheritCUDATargetAttrs(FunctionDecl *FD, const FunctionTemplateDecl &TD); + /// Returns the name of the launch configuration function. This is the name + /// of the function that will be called to configure kernel call, with the + /// parameters specified via <<<>>>. + std::string getCudaConfigureFuncName() const; + /// \name Code completion //@{ /// Describes the context in which code completion occurs. @@ -10342,11 +10742,14 @@ public: struct CodeCompleteExpressionData; void CodeCompleteExpression(Scope *S, const CodeCompleteExpressionData &Data); - void CodeCompleteExpression(Scope *S, QualType PreferredType); + void CodeCompleteExpression(Scope *S, QualType PreferredType, + bool IsParenthesized = false); void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase, SourceLocation OpLoc, bool IsArrow, - bool IsBaseExprStatement); - void CodeCompletePostfixExpression(Scope *S, ExprResult LHS); + bool IsBaseExprStatement, + QualType PreferredType); + void CodeCompletePostfixExpression(Scope *S, ExprResult LHS, + QualType PreferredType); void CodeCompleteTag(Scope *S, unsigned TagSpec); void CodeCompleteTypeQualifiers(DeclSpec &DS); void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, @@ -10368,12 +10771,10 @@ public: IdentifierInfo *II, SourceLocation OpenParLoc); void CodeCompleteInitializer(Scope *S, Decl *D); - void CodeCompleteReturn(Scope *S); void CodeCompleteAfterIf(Scope *S); - void CodeCompleteBinaryRHS(Scope *S, Expr *LHS, tok::TokenKind Op); - void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, - bool EnteringContext, QualType BaseType); + void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext, + QualType BaseType, QualType PreferredType); void CodeCompleteUsing(Scope *S); void CodeCompleteUsingDirective(Scope *S); void CodeCompleteNamespaceDecl(Scope *S); @@ -10498,6 +10899,7 @@ private: ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, CallExpr *TheCall); + void checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, CallExpr *TheCall); bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, unsigned MaxWidth); @@ -10551,6 +10953,7 @@ private: bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, unsigned ExpectedFieldNum, bool AllowName); + bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall); public: enum FormatStringType { FST_Scanf, @@ -10773,9 +11176,6 @@ private: "there shouldn't be any pending delayed exception spec checks"); assert(S.DelayedEquivalentExceptionSpecChecks.empty() && "there shouldn't be any pending delayed exception spec checks"); - assert(S.DelayedDefaultedMemberExceptionSpecs.empty() && - "there shouldn't be any pending delayed defaulted member " - "exception specs"); assert(S.DelayedDllExportClasses.empty() && "there shouldn't be any pending delayed DLL export classes"); swapSavedState(); @@ -10787,8 +11187,6 @@ private: SavedOverridingExceptionSpecChecks; decltype(DelayedEquivalentExceptionSpecChecks) SavedEquivalentExceptionSpecChecks; - decltype(DelayedDefaultedMemberExceptionSpecs) - SavedDefaultedMemberExceptionSpecs; decltype(DelayedDllExportClasses) SavedDllExportClasses; void swapSavedState() { @@ -10796,8 +11194,6 @@ private: S.DelayedOverridingExceptionSpecChecks); SavedEquivalentExceptionSpecChecks.swap( S.DelayedEquivalentExceptionSpecChecks); - SavedDefaultedMemberExceptionSpecs.swap( - S.DelayedDefaultedMemberExceptionSpecs); SavedDllExportClasses.swap(S.DelayedDllExportClasses); } }; @@ -10847,6 +11243,15 @@ public: Expr *E, llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action); + + /// Describes the reason a calling convention specification was ignored, used + /// for diagnostics. + enum class CallingConventionIgnoredReason { + ForThisTarget = 0, + VariadicFunction, + ConstructorDestructor, + BuiltinFunction + }; }; /// RAII object that enters a new expression evaluation context. diff --git a/include/clang/Sema/SemaConsumer.h b/include/clang/Sema/SemaConsumer.h index a2caf86c3653..1c5962e9f055 100644 --- a/include/clang/Sema/SemaConsumer.h +++ b/include/clang/Sema/SemaConsumer.h @@ -1,9 +1,8 @@ //===--- SemaConsumer.h - Abstract interface for AST semantics --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h index 30a2497a3e87..ae027eca1998 100644 --- a/include/clang/Sema/SemaDiagnostic.h +++ b/include/clang/Sema/SemaDiagnostic.h @@ -1,9 +1,8 @@ //===--- DiagnosticSema.h - Diagnostics for libsema -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Sema/SemaFixItUtils.h b/include/clang/Sema/SemaFixItUtils.h index 84dc58754b7b..df9bc4297694 100644 --- a/include/clang/Sema/SemaFixItUtils.h +++ b/include/clang/Sema/SemaFixItUtils.h @@ -1,9 +1,8 @@ //===--- SemaFixItUtils.h - Sema FixIts -------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h index c55e16a27cd3..dfb34daa14d3 100644 --- a/include/clang/Sema/SemaInternal.h +++ b/include/clang/Sema/SemaInternal.h @@ -1,9 +1,8 @@ //===--- SemaInternal.h - Internal Sema Interfaces --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -39,15 +38,6 @@ FTIHasNonVoidParameters(const DeclaratorChunk::FunctionTypeInfo &FTI) { return FTI.NumParams && !FTIHasSingleVoidParameter(FTI); } -// This requires the variable to be non-dependent and the initializer -// to not be value dependent. -inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) { - const VarDecl *DefVD = nullptr; - return !isa<ParmVarDecl>(Var) && - Var->isUsableInConstantExpressions(Context) && - Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE(); -} - // Helper function to check whether D's attributes match current CUDA mode. // Decls with mismatched attributes and related diagnostics may have to be // ignored during this CUDA compilation pass. @@ -60,36 +50,6 @@ inline bool DeclAttrsMatchCUDAMode(const LangOptions &LangOpts, Decl *D) { return isDeviceSideDecl == LangOpts.CUDAIsDevice; } -// Directly mark a variable odr-used. Given a choice, prefer to use -// MarkVariableReferenced since it does additional checks and then -// calls MarkVarDeclODRUsed. -// If the variable must be captured: -// - if FunctionScopeIndexToStopAt is null, capture it in the CurContext -// - else capture it in the DeclContext that maps to the -// *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack. -inline void MarkVarDeclODRUsed(VarDecl *Var, - SourceLocation Loc, Sema &SemaRef, - const unsigned *const FunctionScopeIndexToStopAt) { - // Keep track of used but undefined variables. - // FIXME: We shouldn't suppress this warning for static data members. - if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly && - (!Var->isExternallyVisible() || Var->isInline() || - SemaRef.isExternalWithNoLinkageType(Var)) && - !(Var->isStaticDataMember() && Var->hasInit())) { - SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()]; - if (old.isInvalid()) - old = Loc; - } - QualType CaptureType, DeclRefType; - SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit, - /*EllipsisLoc*/ SourceLocation(), - /*BuildAndDiagnose*/ true, - CaptureType, DeclRefType, - FunctionScopeIndexToStopAt); - - Var->markUsed(SemaRef.Context); -} - /// Return a DLL attribute from the declaration. inline InheritableAttr *getDLLAttr(Decl *D) { assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) && diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h index 8edb9b5c613d..e8eaa46b88a2 100644 --- a/include/clang/Sema/SemaLambda.h +++ b/include/clang/Sema/SemaLambda.h @@ -1,9 +1,8 @@ //===--- SemaLambda.h - Lambda Helper Functions --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index 39b08e934be4..68c8c83c3631 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -1,9 +1,8 @@ //===- SemaTemplate.h - C++ Templates ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception //===----------------------------------------------------------------------===// // // This file provides types used in the semantic analysis of C++ templates. @@ -228,7 +227,7 @@ class VarDecl; class LocalInstantiationScope { public: /// A set of declarations. - using DeclArgumentPack = SmallVector<ParmVarDecl *, 4>; + using DeclArgumentPack = SmallVector<VarDecl *, 4>; private: /// Reference to the semantic analysis that is performing @@ -379,7 +378,7 @@ class VarDecl; findInstantiationOf(const Decl *D); void InstantiatedLocal(const Decl *D, Decl *Inst); - void InstantiatedLocalPackArg(const Decl *D, ParmVarDecl *Inst); + void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst); void MakeInstantiatedLocalArgPack(const Decl *D); /// Note that the given parameter pack has been partially substituted @@ -476,7 +475,8 @@ class VarDecl; // A few supplemental visitor functions. Decl *VisitCXXMethodDecl(CXXMethodDecl *D, TemplateParameterList *TemplateParams, - bool IsClassScopeSpecialization = false); + Optional<const ASTTemplateArgumentListInfo *> + ClassScopeSpecializationArgs = llvm::None); Decl *VisitFunctionDecl(FunctionDecl *D, TemplateParameterList *TemplateParams); Decl *VisitDecl(Decl *D); @@ -545,7 +545,8 @@ class VarDecl; Decl *VisitVarTemplateSpecializationDecl( VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos, const TemplateArgumentListInfo &TemplateArgsInfo, - ArrayRef<TemplateArgument> Converted); + ArrayRef<TemplateArgument> Converted, + VarTemplateSpecializationDecl *PrevDecl = nullptr); Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); ClassTemplatePartialSpecializationDecl * diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index 93395b4945d5..662c4072c978 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -1,9 +1,8 @@ //===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Sema/TemplateInstCallback.h b/include/clang/Sema/TemplateInstCallback.h index dc729d52243c..3ab0e8c6be9f 100644 --- a/include/clang/Sema/TemplateInstCallback.h +++ b/include/clang/Sema/TemplateInstCallback.h @@ -1,9 +1,8 @@ //===- TemplateInstCallback.h - Template Instantiation Callback - C++ --===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===---------------------------------------------------------------------===// // diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h index d8fe82799845..b49a96c0b93f 100644 --- a/include/clang/Sema/TypoCorrection.h +++ b/include/clang/Sema/TypoCorrection.h @@ -1,9 +1,8 @@ //===- TypoCorrection.h - Class for typo correction results -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -313,6 +312,13 @@ public: : InvalidDistance; } + /// Clone this CorrectionCandidateCallback. CorrectionCandidateCallbacks are + /// initially stack-allocated. However in case where delayed typo-correction + /// is done we need to move the callback to storage with a longer lifetime. + /// Every class deriving from CorrectionCandidateCallback must implement + /// this method. + virtual std::unique_ptr<CorrectionCandidateCallback> clone() = 0; + void setTypoName(IdentifierInfo *II) { Typo = II; } void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; } @@ -343,14 +349,28 @@ protected: NestedNameSpecifier *TypoNNS; }; +class DefaultFilterCCC final : public CorrectionCandidateCallback { +public: + explicit DefaultFilterCCC(IdentifierInfo *Typo = nullptr, + NestedNameSpecifier *TypoNNS = nullptr) + : CorrectionCandidateCallback(Typo, TypoNNS) {} + + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<DefaultFilterCCC>(*this); + } +}; + /// Simple template class for restricting typo correction candidates /// to ones having a single Decl* of the given type. template <class C> -class DeclFilterCCC : public CorrectionCandidateCallback { +class DeclFilterCCC final : public CorrectionCandidateCallback { public: bool ValidateCandidate(const TypoCorrection &candidate) override { return candidate.getCorrectionDeclAs<C>(); } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<DeclFilterCCC>(*this); + } }; // Callback class to limit the allowed keywords and to only accept typo @@ -363,6 +383,9 @@ public: MemberExpr *ME = nullptr); bool ValidateCandidate(const TypoCorrection &candidate) override; + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<FunctionCallFilterCCC>(*this); + } private: unsigned NumArgs; @@ -372,7 +395,7 @@ private: }; // Callback class that effectively disabled typo correction -class NoTypoCorrectionCCC : public CorrectionCandidateCallback { +class NoTypoCorrectionCCC final : public CorrectionCandidateCallback { public: NoTypoCorrectionCCC() { WantTypeSpecifiers = false; @@ -385,6 +408,9 @@ public: bool ValidateCandidate(const TypoCorrection &candidate) override { return false; } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<NoTypoCorrectionCCC>(*this); + } }; } // namespace clang diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h index 115e97bcd2ce..434393677d42 100644 --- a/include/clang/Sema/Weak.h +++ b/include/clang/Sema/Weak.h @@ -1,9 +1,8 @@ //===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index ec752fb7c796..0e1b9e0af9e6 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -1,9 +1,8 @@ //===- ASTBitCodes.h - Enum values for the PCH bitcode format ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -24,7 +23,7 @@ #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/DenseMapInfo.h" -#include "llvm/Bitcode/BitCodes.h" +#include "llvm/Bitstream/BitCodes.h" #include <cassert> #include <cstdint> @@ -1174,7 +1173,10 @@ namespace serialization { TYPE_DEPENDENT_ADDRESS_SPACE = 47, /// A dependentSizedVectorType record. - TYPE_DEPENDENT_SIZED_VECTOR = 48 + TYPE_DEPENDENT_SIZED_VECTOR = 48, + + /// A type defined in a macro. + TYPE_MACRO_QUALIFIED = 49 }; /// The type IDs for special types constructed by semantic @@ -1439,9 +1441,6 @@ namespace serialization { /// A CXXConstructorDecl record. DECL_CXX_CONSTRUCTOR, - /// A CXXConstructorDecl record for an inherited constructor. - DECL_CXX_INHERITED_CONSTRUCTOR, - /// A CXXDestructorDecl record. DECL_CXX_DESTRUCTOR, @@ -1490,7 +1489,10 @@ namespace serialization { /// A TypeAliasTemplateDecl record. DECL_TYPE_ALIAS_TEMPLATE, - /// A StaticAssertDecl record. + /// \brief A ConceptDecl record. + DECL_CONCEPT, + + /// \brief A StaticAssertDecl record. DECL_STATIC_ASSERT, /// A record containing CXXBaseSpecifiers. @@ -1522,7 +1524,10 @@ namespace serialization { /// An OMPRequiresDecl record. DECL_OMP_REQUIRES, - + + /// An OMPAllocateDcl record. + DECL_OMP_ALLOCATE, + /// An EmptyDecl record. DECL_EMPTY, @@ -1538,6 +1543,9 @@ namespace serialization { /// A PragmaDetectMismatchDecl record. DECL_PRAGMA_DETECT_MISMATCH, + /// An OMPDeclareMapperDecl record. + DECL_OMP_DECLARE_MAPPER, + /// An OMPDeclareReductionDecl record. DECL_OMP_DECLARE_REDUCTION, @@ -1727,6 +1735,9 @@ namespace serialization { /// A GNUNullExpr record. EXPR_GNU_NULL, + /// A SourceLocExpr record. + EXPR_SOURCE_LOC, + /// A ShuffleVectorExpr record. EXPR_SHUFFLE_VECTOR, diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h index c462a90dde54..f3a01a4b9731 100644 --- a/include/clang/Serialization/ASTDeserializationListener.h +++ b/include/clang/Serialization/ASTDeserializationListener.h @@ -1,9 +1,8 @@ //===- ASTDeserializationListener.h - Decl/Type PCH Read Events -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index f97f545852f4..37bea48d8846 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1,9 +1,8 @@ //===- ASTReader.h - AST File Reader ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -57,7 +56,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" -#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Endian.h" #include "llvm/Support/MemoryBuffer.h" @@ -98,7 +97,7 @@ class HeaderSearchOptions; class LangOptions; class LazyASTUnresolvedSet; class MacroInfo; -class MemoryBufferCache; +class InMemoryModuleCache; class NamedDecl; class NamespaceDecl; class ObjCCategoryDecl; @@ -441,9 +440,6 @@ private: /// The module manager which manages modules and their dependencies ModuleManager ModuleMgr; - /// The cache that manages memory buffers for PCM files. - MemoryBufferCache &PCMCache; - /// A dummy identifier resolver used to merge TU-scope declarations in /// C, for the cases where we don't have a Sema object to provide a real /// identifier resolver. @@ -1441,6 +1437,7 @@ private: void Error(StringRef Msg) const; void Error(unsigned DiagID, StringRef Arg1 = StringRef(), StringRef Arg2 = StringRef()) const; + void Error(llvm::Error &&Err) const; public: /// Load the AST file and validate its contents against the given @@ -1482,8 +1479,8 @@ public: /// /// \param ReadTimer If non-null, a timer used to track the time spent /// deserializing. - ASTReader(Preprocessor &PP, ASTContext *Context, - const PCHContainerReader &PCHContainerRdr, + ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache, + ASTContext *Context, const PCHContainerReader &PCHContainerRdr, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, StringRef isysroot = "", bool DisableValidation = false, bool AllowASTWithCompilerErrors = false, @@ -2224,6 +2221,9 @@ public: llvm::APFloat ReadAPFloat(const RecordData &Record, const llvm::fltSemantics &Sem, unsigned &Idx); + /// Read an APValue + APValue ReadAPValue(const RecordData &Record, unsigned &Idx); + // Read a string static std::string ReadString(const RecordData &Record, unsigned &Idx); @@ -2235,6 +2235,10 @@ public: // Read a path std::string ReadPath(ModuleFile &F, const RecordData &Record, unsigned &Idx); + // Read a path + std::string ReadPath(StringRef BaseDirectory, const RecordData &Record, + unsigned &Idx); + // Skip a path static void SkipPath(const RecordData &Record, unsigned &Idx) { SkipString(Record, Idx); @@ -2376,7 +2380,8 @@ public: /// Reads a record with id AbbrevID from Cursor, resetting the /// internal state. - unsigned readRecord(llvm::BitstreamCursor &Cursor, unsigned AbbrevID); + Expected<unsigned> readRecord(llvm::BitstreamCursor &Cursor, + unsigned AbbrevID); /// Is this a module file for a module (rather than a PCH or similar). bool isModule() const { return F->isModule(); } @@ -2430,6 +2435,14 @@ public: ID); } + ExplicitSpecifier readExplicitSpec() { + uint64_t Kind = readInt(); + bool HasExpr = Kind & 0x1; + Kind = Kind >> 1; + return ExplicitSpecifier(HasExpr ? readExpr() : nullptr, + static_cast<ExplicitSpecKind>(Kind)); + } + void readExceptionSpec(SmallVectorImpl<QualType> &ExceptionStorage, FunctionProtoType::ExceptionSpecInfo &ESI) { return Reader->readExceptionSpec(*F, ExceptionStorage, ESI, Record, Idx); @@ -2604,6 +2617,8 @@ public: return Reader->ReadSourceRange(*F, Record, Idx); } + APValue readAPValue() { return Reader->ReadAPValue(Record, Idx); } + /// Read an integral value, advancing Idx. llvm::APInt readAPInt() { return Reader->ReadAPInt(Record, Idx); @@ -2666,7 +2681,10 @@ struct SavedStreamPosition { : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {} ~SavedStreamPosition() { - Cursor.JumpToBit(Offset); + if (llvm::Error Err = Cursor.JumpToBit(Offset)) + llvm::report_fatal_error( + "Cursor should always be able to go back, failed: " + + toString(std::move(Err))); } private: diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 11af30ac8373..76bd874fb012 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -1,9 +1,8 @@ //===- ASTWriter.h - AST File Writer ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -37,7 +36,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitstream/BitstreamWriter.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -75,8 +74,8 @@ class IdentifierResolver; class LangOptions; class MacroDefinitionRecord; class MacroInfo; -class MemoryBufferCache; class Module; +class InMemoryModuleCache; class ModuleFileExtension; class ModuleFileExtensionWriter; class NamedDecl; @@ -133,7 +132,7 @@ private: const SmallVectorImpl<char> &Buffer; /// The PCM manager which manages memory buffers for pcm files. - MemoryBufferCache &PCMCache; + InMemoryModuleCache &ModuleCache; /// The ASTContext we're writing. ASTContext *Context = nullptr; @@ -543,7 +542,7 @@ public: /// Create a new precompiled header writer that outputs to /// the given bitstream. ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer, - MemoryBufferCache &PCMCache, + InMemoryModuleCache &ModuleCache, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, bool IncludeTimestamps = true); ~ASTWriter() override; @@ -571,7 +570,8 @@ public: /// the module but currently is merely a random 32-bit number. ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile, Module *WritingModule, StringRef isysroot, - bool hasErrors = false); + bool hasErrors = false, + bool ShouldCacheASTInMemory = false); /// Emit a token. void AddToken(const Token &Tok, RecordDataImpl &Record); @@ -738,6 +738,7 @@ private: void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, const Attr *Attr) override; + void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) override; void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; void AddedAttributeToRecord(const Attr *Attr, const RecordDecl *Record) override; @@ -862,6 +863,9 @@ public: /// Emit a floating-point value. void AddAPFloat(const llvm::APFloat &Value); + /// Emit an APvalue. + void AddAPValue(const APValue &Value); + /// Emit a reference to an identifier. void AddIdentifierRef(const IdentifierInfo *II) { return Writer->AddIdentifierRef(II, *Record); @@ -974,6 +978,7 @@ class PCHGenerator : public SemaConsumer { llvm::BitstreamWriter Stream; ASTWriter Writer; bool AllowASTWithErrors; + bool ShouldCacheASTInMemory; protected: ASTWriter &getWriter() { return Writer; } @@ -981,10 +986,12 @@ protected: SmallVectorImpl<char> &getPCH() const { return Buffer->Data; } public: - PCHGenerator(const Preprocessor &PP, StringRef OutputFile, StringRef isysroot, + PCHGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache, + StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, - bool AllowASTWithErrors = false, bool IncludeTimestamps = true); + bool AllowASTWithErrors = false, bool IncludeTimestamps = true, + bool ShouldCacheASTInMemory = false); ~PCHGenerator() override; void InitializeSema(Sema &S) override { SemaPtr = &S; } diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h index ad827e37db2d..0c05537dd108 100644 --- a/include/clang/Serialization/ContinuousRangeMap.h +++ b/include/clang/Serialization/ContinuousRangeMap.h @@ -1,9 +1,8 @@ //===- ContinuousRangeMap.h - Map with int range as key ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -74,7 +73,7 @@ public: } void insertOrReplace(const value_type &Val) { - iterator I = std::lower_bound(Rep.begin(), Rep.end(), Val, Compare()); + iterator I = llvm::lower_bound(Rep, Val, Compare()); if (I != Rep.end() && I->first == Val.first) { I->second = Val.second; return; @@ -92,7 +91,7 @@ public: const_iterator end() const { return Rep.end(); } iterator find(Int K) { - iterator I = std::upper_bound(Rep.begin(), Rep.end(), K, Compare()); + iterator I = llvm::upper_bound(Rep, K, Compare()); // I points to the first entry with a key > K, which is the range that // follows the one containing K. if (I == Rep.begin()) diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h index 5791fc024a32..5f4812626224 100644 --- a/include/clang/Serialization/GlobalModuleIndex.h +++ b/include/clang/Serialization/GlobalModuleIndex.h @@ -1,9 +1,8 @@ //===--- GlobalModuleIndex.h - Global Module Index --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -21,6 +20,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" #include <memory> #include <utility> @@ -123,27 +123,14 @@ class GlobalModuleIndex { public: ~GlobalModuleIndex(); - /// An error code returned when trying to read an index. - enum ErrorCode { - /// No error occurred. - EC_None, - /// No index was found. - EC_NotFound, - /// Some other process is currently building the index; it is not - /// available yet. - EC_Building, - /// There was an unspecified I/O error reading or writing the index. - EC_IOError - }; - /// Read a global index file for the given directory. /// /// \param Path The path to the specific module cache where the module files /// for the intended configuration reside. /// /// \returns A pair containing the global module index (if it exists) and - /// the error code. - static std::pair<GlobalModuleIndex *, ErrorCode> + /// the error. + static std::pair<GlobalModuleIndex *, llvm::Error> readIndex(llvm::StringRef Path); /// Returns an iterator for identifiers stored in the index table. @@ -195,9 +182,9 @@ public: /// creating modules. /// \param Path The path to the directory containing module files, into /// which the global index will be written. - static ErrorCode writeIndex(FileManager &FileMgr, - const PCHContainerReader &PCHContainerRdr, - llvm::StringRef Path); + static llvm::Error writeIndex(FileManager &FileMgr, + const PCHContainerReader &PCHContainerRdr, + llvm::StringRef Path); }; } diff --git a/include/clang/Serialization/InMemoryModuleCache.h b/include/clang/Serialization/InMemoryModuleCache.h new file mode 100644 index 000000000000..7b5b5c1cf1be --- /dev/null +++ b/include/clang/Serialization/InMemoryModuleCache.h @@ -0,0 +1,107 @@ +//===- InMemoryModuleCache.h - In-memory cache for modules ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H +#define LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H + +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/MemoryBuffer.h" +#include <memory> + +namespace clang { + +/// In-memory cache for modules. +/// +/// This is a cache for modules for use across a compilation, sharing state +/// between the CompilerInstances in an implicit modules build. It must be +/// shared by each CompilerInstance, ASTReader, ASTWriter, and ModuleManager +/// that are coordinating. +/// +/// Critically, it ensures that a single process has a consistent view of each +/// PCM. This is used by \a CompilerInstance when building PCMs to ensure that +/// each \a ModuleManager sees the same files. +class InMemoryModuleCache : public llvm::RefCountedBase<InMemoryModuleCache> { + struct PCM { + std::unique_ptr<llvm::MemoryBuffer> Buffer; + + /// Track whether this PCM is known to be good (either built or + /// successfully imported by a CompilerInstance/ASTReader using this + /// cache). + bool IsFinal = false; + + PCM() = default; + PCM(std::unique_ptr<llvm::MemoryBuffer> Buffer) + : Buffer(std::move(Buffer)) {} + }; + + /// Cache of buffers. + llvm::StringMap<PCM> PCMs; + +public: + /// There are four states for a PCM. It must monotonically increase. + /// + /// 1. Unknown: the PCM has neither been read from disk nor built. + /// 2. Tentative: the PCM has been read from disk but not yet imported or + /// built. It might work. + /// 3. ToBuild: the PCM read from disk did not work but a new one has not + /// been built yet. + /// 4. Final: indicating that the current PCM was either built in this + /// process or has been successfully imported. + enum State { Unknown, Tentative, ToBuild, Final }; + + /// Get the state of the PCM. + State getPCMState(llvm::StringRef Filename) const; + + /// Store the PCM under the Filename. + /// + /// \pre state is Unknown + /// \post state is Tentative + /// \return a reference to the buffer as a convenience. + llvm::MemoryBuffer &addPCM(llvm::StringRef Filename, + std::unique_ptr<llvm::MemoryBuffer> Buffer); + + /// Store a just-built PCM under the Filename. + /// + /// \pre state is Unknown or ToBuild. + /// \pre state is not Tentative. + /// \return a reference to the buffer as a convenience. + llvm::MemoryBuffer &addBuiltPCM(llvm::StringRef Filename, + std::unique_ptr<llvm::MemoryBuffer> Buffer); + + /// Try to remove a buffer from the cache. No effect if state is Final. + /// + /// \pre state is Tentative/Final. + /// \post Tentative => ToBuild or Final => Final. + /// \return false on success, i.e. if Tentative => ToBuild. + bool tryToDropPCM(llvm::StringRef Filename); + + /// Mark a PCM as final. + /// + /// \pre state is Tentative or Final. + /// \post state is Final. + void finalizePCM(llvm::StringRef Filename); + + /// Get a pointer to the pCM if it exists; else nullptr. + llvm::MemoryBuffer *lookupPCM(llvm::StringRef Filename) const; + + /// Check whether the PCM is final and has been shown to work. + /// + /// \return true iff state is Final. + bool isPCMFinal(llvm::StringRef Filename) const; + + /// Check whether the PCM is waiting to be built. + /// + /// \return true iff state is ToBuild. + bool shouldBuildPCM(llvm::StringRef Filename) const; +}; + +} // end namespace clang + +#endif // LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h index d6e78e693109..1979c53a7133 100644 --- a/include/clang/Serialization/Module.h +++ b/include/clang/Serialization/Module.h @@ -1,9 +1,8 @@ //===- Module.h - Module description ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -25,7 +24,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Support/Endian.h" #include <cassert> #include <cstdint> @@ -175,7 +174,7 @@ public: unsigned Generation; /// The memory buffer that stores the data associated with - /// this AST file, owned by the PCMCache in the ModuleManager. + /// this AST file, owned by the InMemoryModuleCache. llvm::MemoryBuffer *Buffer; /// The size of this file, in bits. diff --git a/include/clang/Serialization/ModuleFileExtension.h b/include/clang/Serialization/ModuleFileExtension.h index f70218e329af..63562c0d6bd2 100644 --- a/include/clang/Serialization/ModuleFileExtension.h +++ b/include/clang/Serialization/ModuleFileExtension.h @@ -1,9 +1,8 @@ //===-- ModuleFileExtension.h - Module File Extensions ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h index cfc9a2ef112c..5b3b22be759c 100644 --- a/include/clang/Serialization/ModuleManager.h +++ b/include/clang/Serialization/ModuleManager.h @@ -1,9 +1,8 @@ //===- ModuleManager.cpp - Module Manager -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -39,7 +38,7 @@ class FileEntry; class FileManager; class GlobalModuleIndex; class HeaderSearch; -class MemoryBufferCache; +class InMemoryModuleCache; class ModuleMap; class PCHContainerReader; @@ -68,7 +67,7 @@ class ModuleManager { FileManager &FileMgr; /// Cache of PCM files. - IntrusiveRefCntPtr<MemoryBufferCache> PCMCache; + IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache; /// Knows how to unwrap module containers. const PCHContainerReader &PCHContainerRdr; @@ -140,7 +139,7 @@ public: SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>; using ModuleOffset = std::pair<uint32_t, StringRef>; - explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache, + explicit ModuleManager(FileManager &FileMgr, InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, const HeaderSearch &HeaderSearchInfo); ~ModuleManager(); @@ -318,7 +317,7 @@ public: /// View the graphviz representation of the module graph. void viewGraph(); - MemoryBufferCache &getPCMCache() const { return *PCMCache; } + InMemoryModuleCache &getModuleCache() const { return *ModuleCache; } }; } // namespace serialization diff --git a/include/clang/Serialization/PCHContainerOperations.h b/include/clang/Serialization/PCHContainerOperations.h index 2a91d9830af3..33fc4a0a24e0 100644 --- a/include/clang/Serialization/PCHContainerOperations.h +++ b/include/clang/Serialization/PCHContainerOperations.h @@ -1,9 +1,8 @@ //===--- Serialization/PCHContainerOperations.h - PCH Containers --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Serialization/SerializationDiagnostic.h b/include/clang/Serialization/SerializationDiagnostic.h index 2decd1c2f67b..7fc93c11932f 100644 --- a/include/clang/Serialization/SerializationDiagnostic.h +++ b/include/clang/Serialization/SerializationDiagnostic.h @@ -1,9 +1,8 @@ //===--- SerializationDiagnostic.h - Serialization Diagnostics -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h index 192ac1261c76..c7732333d9ba 100644 --- a/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h +++ b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h @@ -1,9 +1,8 @@ //===--- ClangSACheckers.h - Registration functions for Checkers *- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,13 +18,17 @@ namespace clang { +class LangOptions; + namespace ento { + class CheckerManager; class CheckerRegistry; #define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ - void register##CLASS(CheckerManager &mgr); +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \ + void register##CLASS(CheckerManager &mgr); \ + bool shouldRegister##CLASS(const LangOptions &LO); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER #undef GET_CHECKERS diff --git a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td index 453e189fccb0..6625d79559f5 100644 --- a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td +++ b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td @@ -1,9 +1,8 @@ //===--- CheckerBase.td - Checker TableGen classes ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -11,14 +10,68 @@ // //===----------------------------------------------------------------------===// +/// Describes a checker or package option type. This is important for validating +/// user supplied inputs. +/// New option types can be added by modifying this enum. Note that this +/// requires changes in the TableGen emitter file ClangSACheckersEmitter.cpp. +class CmdLineOptionTypeEnum<bits<2> val> { + bits<2> Type = val; +} +def Integer : CmdLineOptionTypeEnum<0>; +def String : CmdLineOptionTypeEnum<1>; +def Boolean : CmdLineOptionTypeEnum<2>; + +/// Describes the state of the entry. We wouldn't like to display, for example, +/// developer only entries for a list meant for end users. +class DevelopmentStageEnum<bits<1> val> { + bits<1> Val = val; +} + +/// Alpha entries are under development, might be incomplet, inkorrekt and +/// unstable. +def InAlpha : DevelopmentStageEnum<0>; + +/// Released entries are stable, produce minimal, if any false positives, +/// and emits reports that explain the occurance of the bug understandably and +/// thoroughly. +def Released : DevelopmentStageEnum<1>; + +/// Marks the entry hidden. Hidden entries won't be displayed in +/// -analyzer-checker-option-help. +class HiddenEnum<bit val> { + bit Val = val; +} +def DontHide : HiddenEnum<0>; +def Hide : HiddenEnum<1>; + +/// Describes an option for a checker or a package. +class CmdLineOption<CmdLineOptionTypeEnum type, string cmdFlag, string desc, + string defaultVal, DevelopmentStageEnum stage, + HiddenEnum isHidden = DontHide> { + bits<2> Type = type.Type; + string CmdFlag = cmdFlag; + string Desc = desc; + string DefaultVal = defaultVal; + bits<1> DevelopmentStage = stage.Val; + bit Hidden = isHidden.Val; +} + +/// Describes a list of package options. +class PackageOptions<list<CmdLineOption> opts> { + list<CmdLineOption> PackageOptions = opts; +} + /// Describes a package. Every checker is a part of a package, for example, /// 'NullDereference' is part of the 'core' package, hence it's full name is /// 'core.NullDereference'. /// Example: /// def Core : Package<"core">; class Package<string name> { - string PackageName = name; - Package ParentPackage; + string PackageName = name; + // This field is optional. + list<CmdLineOption> PackageOptions; + Package ParentPackage; + bit Hidden = 0; } /// Describes a 'super' package that holds another package inside it. This is @@ -49,9 +102,37 @@ class Documentation<DocumentationEnum val> { /// Note that a checker has a name (e.g.: 'NullDereference'), and a fullname, /// that is autogenerated with the help of the ParentPackage field, that also /// includes package names (e.g.: 'core.NullDereference'). +/// Example: +/// def DereferenceChecker : Checker<"NullDereference">, +/// HelpText<"Check for dereferences of null pointers">; class Checker<string name = ""> { - string CheckerName = name; - string HelpText; - bits<2> Documentation; - Package ParentPackage; + string CheckerName = name; + string HelpText; + // This field is optional. + list<CmdLineOption> CheckerOptions; + // This field is optional. + list<Checker> Dependencies; + bits<2> Documentation; + Package ParentPackage; + bit Hidden = 0; +} + +/// Describes a list of checker options. +class CheckerOptions<list<CmdLineOption> opts> { + list<CmdLineOption> CheckerOptions = opts; } + +/// Describes dependencies in between checkers. For example, InnerPointerChecker +/// relies on information MallocBase gathers. +/// Example: +/// def InnerPointerChecker : Checker<"InnerPointer">, +/// HelpText<"Check for inner pointers of C++ containers used after " +/// "re/deallocation">, +/// Dependencies<[MallocBase]>; +class Dependencies<list<Checker> Deps = []> { + list<Checker> Dependencies = Deps; +} + +/// Marks a checker or a package hidden. Hidden entries are meant for developers +/// only, and aren't exposed to end users. +class Hidden { bit Hidden = 1; } diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td index 1bb3da7a2458..2b29efba66a4 100644 --- a/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1,9 +1,8 @@ //===--- Checkers.td - Static Analyzer Checkers -===-----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -21,7 +20,7 @@ include "CheckerBase.td" def Alpha : Package<"alpha">; def Core : Package<"core">; -def CoreBuiltin : Package<"builtin">, ParentPackage<Core>; +def CoreBuiltin : Package<"builtin">, ParentPackage<Core>, Hidden; def CoreUninitialized : Package<"uninitialized">, ParentPackage<Core>; def CoreAlpha : Package<"core">, ParentPackage<Alpha>; @@ -43,7 +42,18 @@ def OptIn : Package<"optin">; // development, but unwanted for developers who target only a single platform. def PortabilityOptIn : Package<"portability">, ParentPackage<OptIn>; -def Nullability : Package<"nullability">; +def Nullability : Package<"nullability">, + PackageOptions<[ + CmdLineOption<Boolean, + "NoDiagnoseCallsToSystemHeaders", + "Suppresses warnings for violating nullability annotations " + "of system header functions. This is useful if you are " + "concerned with your custom nullability annotations more " + "than with following nullability specifications of system " + "header functions.", + "false", + Released> + ]>; def Cplusplus : Package<"cplusplus">; def CplusplusAlpha : Package<"cplusplus">, ParentPackage<Alpha>; @@ -88,13 +98,16 @@ def LLVMAlpha : Package<"llvm">, ParentPackage<Alpha>; // The APIModeling package is for checkers that model APIs and don't perform // any diagnostics. These checkers are always turned on; this package is // intended for API modeling that is not controlled by the target triple. -def APIModeling : Package<"apiModeling">; -def GoogleAPIModeling : Package<"google">, ParentPackage<APIModeling>; +def APIModeling : Package<"apiModeling">, Hidden; +def GoogleAPIModeling : Package<"google">, ParentPackage<APIModeling>, Hidden; +def LLVMAPIModeling : Package<"llvm">, ParentPackage<APIModeling>, Hidden; -def Debug : Package<"debug">; +def Debug : Package<"debug">, Hidden; def CloneDetectionAlpha : Package<"clone">, ParentPackage<Alpha>; +def NonDeterminismAlpha : Package<"nondeterminism">, ParentPackage<Alpha>; + //===----------------------------------------------------------------------===// // Core Checkers. //===----------------------------------------------------------------------===// @@ -128,8 +141,14 @@ def UndefResultChecker : Checker<"UndefinedBinaryOperatorResult">, HelpText<"Check for undefined results of binary operators">, Documentation<HasDocumentation>; +def StackAddrEscapeBase : Checker<"StackAddrEscapeBase">, + HelpText<"Generate information about stack address escapes.">, + Documentation<NotDocumented>, + Hidden; + def StackAddrEscapeChecker : Checker<"StackAddressEscape">, HelpText<"Check that addresses to stack memory do not escape the function">, + Dependencies<[StackAddrEscapeBase]>, Documentation<HasDocumentation>; def DynamicTypePropagation : Checker<"DynamicTypePropagation">, @@ -138,7 +157,8 @@ def DynamicTypePropagation : Checker<"DynamicTypePropagation">, def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">, HelpText<"Assume that const string-like globals are non-null">, - Documentation<NotDocumented>; + Documentation<NotDocumented>, + Hidden; } // end "core" @@ -187,6 +207,7 @@ def CallAndMessageUnInitRefArg : Checker<"CallAndMessageUnInitRefArg">, HelpText<"Check for logical errors for function calls and Objective-C " "message expressions (e.g., uninitialized arguments, null function " "pointers, and pointer to undefined variables)">, + Dependencies<[CallAndMessageChecker]>, Documentation<HasAlphaDocumentation>; def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">, @@ -201,38 +222,57 @@ def DynamicTypeChecker : Checker<"DynamicTypeChecker">, def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">, HelpText<"Check that addresses to stack memory do not escape the function">, + Dependencies<[StackAddrEscapeBase]>, Documentation<HasAlphaDocumentation>; } // end "alpha.core" +//===----------------------------------------------------------------------===// +// Nullability checkers. +//===----------------------------------------------------------------------===// + let ParentPackage = Nullability in { +def NullabilityBase : Checker<"NullabilityBase">, + HelpText<"Stores information during the analysis about nullability.">, + Documentation<NotDocumented>, + Hidden; + def NullPassedToNonnullChecker : Checker<"NullPassedToNonnull">, HelpText<"Warns when a null pointer is passed to a pointer which has a " "_Nonnull type.">, + Dependencies<[NullabilityBase]>, Documentation<HasDocumentation>; def NullReturnedFromNonnullChecker : Checker<"NullReturnedFromNonnull">, HelpText<"Warns when a null pointer is returned from a function that has " "_Nonnull return type.">, + Dependencies<[NullabilityBase]>, Documentation<HasDocumentation>; def NullableDereferencedChecker : Checker<"NullableDereferenced">, HelpText<"Warns when a nullable pointer is dereferenced.">, + Dependencies<[NullabilityBase]>, Documentation<HasDocumentation>; def NullablePassedToNonnullChecker : Checker<"NullablePassedToNonnull">, HelpText<"Warns when a nullable pointer is passed to a pointer which has a " "_Nonnull type.">, + Dependencies<[NullabilityBase]>, Documentation<HasDocumentation>; def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">, HelpText<"Warns when a nullable pointer is returned from a function that has " "_Nonnull return type.">, + Dependencies<[NullabilityBase]>, Documentation<NotDocumented>; } // end "nullability" +//===----------------------------------------------------------------------===// +// APIModeling. +//===----------------------------------------------------------------------===// + let ParentPackage = APIModeling in { def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">, @@ -292,6 +332,120 @@ def ReturnUndefChecker : Checker<"UndefReturn">, } // end "core.uninitialized" //===----------------------------------------------------------------------===// +// Unix API checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = CString in { + +def CStringModeling : Checker<"CStringModeling">, + HelpText<"The base of several CString related checkers. On it's own it emits " + "no reports, but adds valuable information to the analysis when " + "enabled.">, + Documentation<NotDocumented>, + Hidden; + +def CStringNullArg : Checker<"NullArg">, + HelpText<"Check for null pointers being passed as arguments to C string " + "functions">, + Dependencies<[CStringModeling]>, + Documentation<HasDocumentation>; + +def CStringSyntaxChecker : Checker<"BadSizeArg">, + HelpText<"Check the size argument passed into C string functions for common " + "erroneous patterns">, + Dependencies<[CStringModeling]>, + Documentation<HasDocumentation>; + +} // end "unix.cstring" + +let ParentPackage = CStringAlpha in { + +def CStringOutOfBounds : Checker<"OutOfBounds">, + HelpText<"Check for out-of-bounds access in string functions">, + Dependencies<[CStringModeling]>, + Documentation<HasAlphaDocumentation>; + +def CStringBufferOverlap : Checker<"BufferOverlap">, + HelpText<"Checks for overlap in two buffer arguments">, + Dependencies<[CStringModeling]>, + Documentation<HasAlphaDocumentation>; + +def CStringNotNullTerm : Checker<"NotNullTerminated">, + HelpText<"Check for arguments which are not null-terminating strings">, + Dependencies<[CStringModeling]>, + Documentation<HasAlphaDocumentation>; + +} // end "alpha.unix.cstring" + +let ParentPackage = Unix in { + +def UnixAPIMisuseChecker : Checker<"API">, + HelpText<"Check calls to various UNIX/Posix functions">, + Documentation<HasDocumentation>; + +def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">, + HelpText<"The base of several malloc() related checkers. On it's own it " + "emits no reports, but adds valuable information to the analysis " + "when enabled.">, + CheckerOptions<[ + CmdLineOption<Boolean, + "Optimistic", + "If set to true, the checker assumes that all the " + "allocating and deallocating functions are annotated with " + "ownership_holds, ownership_takes and ownership_returns.", + "false", + InAlpha> + ]>, + Dependencies<[CStringModeling]>, + Documentation<NotDocumented>, + Hidden; + +def MallocChecker: Checker<"Malloc">, + HelpText<"Check for memory leaks, double free, and use-after-free problems. " + "Traces memory managed by malloc()/free().">, + Dependencies<[DynamicMemoryModeling]>, + Documentation<HasDocumentation>; + +def MallocSizeofChecker : Checker<"MallocSizeof">, + HelpText<"Check for dubious malloc arguments involving sizeof">, + Documentation<HasDocumentation>; + +def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">, + HelpText<"Check for mismatched deallocators.">, + Dependencies<[DynamicMemoryModeling]>, + Documentation<HasDocumentation>; + +def VforkChecker : Checker<"Vfork">, + HelpText<"Check for proper usage of vfork">, + Documentation<HasDocumentation>; + +} // end "unix" + +let ParentPackage = UnixAlpha in { + +def ChrootChecker : Checker<"Chroot">, + HelpText<"Check improper use of chroot">, + Documentation<HasAlphaDocumentation>; + +def PthreadLockChecker : Checker<"PthreadLock">, + HelpText<"Simple lock -> unlock checker">, + Documentation<HasAlphaDocumentation>; + +def StreamChecker : Checker<"Stream">, + HelpText<"Check stream handling functions">, + Documentation<HasAlphaDocumentation>; + +def SimpleStreamChecker : Checker<"SimpleStream">, + HelpText<"Check for misuses of stream APIs">, + Documentation<HasAlphaDocumentation>; + +def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, + HelpText<"Check for calls to blocking functions inside a critical section">, + Documentation<HasAlphaDocumentation>; + +} // end "alpha.unix" + +//===----------------------------------------------------------------------===// // C++ checkers. //===----------------------------------------------------------------------===// @@ -300,31 +454,112 @@ let ParentPackage = Cplusplus in { def InnerPointerChecker : Checker<"InnerPointer">, HelpText<"Check for inner pointers of C++ containers used after " "re/deallocation">, + Dependencies<[DynamicMemoryModeling]>, Documentation<NotDocumented>; def NewDeleteChecker : Checker<"NewDelete">, HelpText<"Check for double-free and use-after-free problems. Traces memory " "managed by new/delete.">, + Dependencies<[DynamicMemoryModeling]>, Documentation<HasDocumentation>; def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">, HelpText<"Check for memory leaks. Traces memory managed by new/delete.">, + Dependencies<[NewDeleteChecker]>, Documentation<HasDocumentation>; def CXXSelfAssignmentChecker : Checker<"SelfAssignment">, HelpText<"Checks C++ copy and move assignment operators for self assignment">, - Documentation<NotDocumented>; + Documentation<NotDocumented>, + Hidden; + +def SmartPtrModeling: Checker<"SmartPtr">, + HelpText<"Model behavior of C++ smart pointers">, + Documentation<NotDocumented>, + Hidden; def MoveChecker: Checker<"Move">, - HelpText<"Find use-after-move bugs in C++">, + HelpText<"Find use-after-move bugs in C++">, + CheckerOptions<[ + CmdLineOption<String, + "WarnOn", + "In non-aggressive mode, only warn on use-after-move of " + "local variables (or local rvalue references) and of STL " + "objects. The former is possible because local variables (or " + "local rvalue references) are not tempting their user to " + "re-use the storage. The latter is possible because STL " + "objects are known to end up in a valid but unspecified " + "state after the move and their state-reset methods are also " + "known, which allows us to predict precisely when " + "use-after-move is invalid. Some STL objects are known to " + "conform to additional contracts after move, so they are not " + "tracked. However, smart pointers specifically are tracked " + "because we can perform extra checking over them. In " + "aggressive mode, warn on any use-after-move because the " + "user has intentionally asked us to completely eliminate " + "use-after-move in his code. Values: \"KnownsOnly\", " + "\"KnownsAndLocals\", \"All\".", + "KnownsAndLocals", + Released> + ]>, Documentation<HasDocumentation>; } // end: "cplusplus" let ParentPackage = CplusplusOptIn in { +def UninitializedObjectChecker: Checker<"UninitializedObject">, + HelpText<"Reports uninitialized fields after object construction">, + CheckerOptions<[ + CmdLineOption<Boolean, + "Pedantic", + "If set to false, the checker won't emit warnings " + "for objects that don't have at least one initialized " + "field.", + "false", + Released>, + CmdLineOption<Boolean, + "NotesAsWarnings", + "If set to true, the checker will emit a warning " + "for each uninitalized field, as opposed to emitting one " + "warning per constructor call, and listing the uninitialized " + "fields that belongs to it in notes.", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "CheckPointeeInitialization", + "If set to false, the checker will not analyze " + "the pointee of pointer/reference fields, and will only " + "check whether the object itself is initialized.", + "false", + InAlpha>, + CmdLineOption<String, + "IgnoreRecordsWithField", + "If supplied, the checker will not analyze " + "structures that have a field with a name or type name that " + "matches the given pattern.", + "\"\"", + Released>, + CmdLineOption<Boolean, + "IgnoreGuardedFields", + "If set to true, the checker will analyze _syntactically_ " + "whether the found uninitialized object is used without a " + "preceding assert call. Defaults to false.", + "false", + InAlpha> + ]>, + Documentation<HasAlphaDocumentation>; + def VirtualCallChecker : Checker<"VirtualCall">, HelpText<"Check virtual function calls during construction or destruction">, + CheckerOptions<[ + CmdLineOption<Boolean, + "PureOnly", + "Whether to only report calls to pure virtual methods.", + "false", + Released> + ]>, Documentation<HasDocumentation>; } // end: "optin.cplusplus" @@ -340,21 +575,25 @@ def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">, HelpText<"Check integer to enumeration casts for out of range values">, Documentation<HasAlphaDocumentation>; +def IteratorModeling : Checker<"IteratorModeling">, + HelpText<"Models iterators of C++ containers">, + Documentation<NotDocumented>, + Hidden; + def InvalidatedIteratorChecker : Checker<"InvalidatedIterator">, HelpText<"Check for use of invalidated iterators">, + Dependencies<[IteratorModeling]>, Documentation<HasAlphaDocumentation>; def IteratorRangeChecker : Checker<"IteratorRange">, HelpText<"Check for iterators used outside their valid ranges">, + Dependencies<[IteratorModeling]>, Documentation<HasAlphaDocumentation>; def MismatchedIteratorChecker : Checker<"MismatchedIterator">, HelpText<"Check for use of iterators of different containers where iterators " "of the same container are expected">, - Documentation<HasAlphaDocumentation>; - -def UninitializedObjectChecker: Checker<"UninitializedObject">, - HelpText<"Reports uninitialized fields after object construction">, + Dependencies<[IteratorModeling]>, Documentation<HasAlphaDocumentation>; } // end: "alpha.cplusplus" @@ -366,16 +605,24 @@ def UninitializedObjectChecker: Checker<"UninitializedObject">, let ParentPackage = Valist in { +def ValistBase : Checker<"ValistBase">, + HelpText<"Gathers information about va_lists.">, + Documentation<NotDocumented>, + Hidden; + def UninitializedChecker : Checker<"Uninitialized">, HelpText<"Check for usages of uninitialized (or already released) va_lists.">, + Dependencies<[ValistBase]>, Documentation<NotDocumented>; def UnterminatedChecker : Checker<"Unterminated">, HelpText<"Check for va_lists which are not released by a va_end call.">, + Dependencies<[ValistBase]>, Documentation<NotDocumented>; def CopyToSelfChecker : Checker<"CopyToSelf">, HelpText<"Check for va_lists which are copied onto itself.">, + Dependencies<[ValistBase]>, Documentation<NotDocumented>; } // end : "valist" @@ -409,6 +656,14 @@ let ParentPackage = Performance in { def PaddingChecker : Checker<"Padding">, HelpText<"Check for excessively padded structs.">, + CheckerOptions<[ + CmdLineOption<Integer, + "AllowedPad", + "Reports are only generated if the excessive padding exceeds " + "'AllowedPad' in bytes.", + "24", + Released> + ]>, Documentation<NotDocumented>; } // end: "padding" @@ -419,40 +674,73 @@ def PaddingChecker : Checker<"Padding">, let ParentPackage = InsecureAPI in { +def SecuritySyntaxChecker : Checker<"SecuritySyntaxChecker">, + HelpText<"Base of various security function related checkers">, + Documentation<NotDocumented>, + Hidden; + def bcmp : Checker<"bcmp">, HelpText<"Warn on uses of the 'bcmp' function">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def bcopy : Checker<"bcopy">, HelpText<"Warn on uses of the 'bcopy' function">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def bzero : Checker<"bzero">, HelpText<"Warn on uses of the 'bzero' function">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def gets : Checker<"gets">, HelpText<"Warn on uses of the 'gets' function">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def getpw : Checker<"getpw">, HelpText<"Warn on uses of the 'getpw' function">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def mktemp : Checker<"mktemp">, HelpText<"Warn on uses of the 'mktemp' function">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def mkstemp : Checker<"mkstemp">, HelpText<"Warn when 'mkstemp' is passed fewer than 6 X's in the format " "string">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def rand : Checker<"rand">, HelpText<"Warn on uses of the 'rand', 'random', and related functions">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def strcpy : Checker<"strcpy">, HelpText<"Warn on uses of the 'strcpy' and 'strcat' functions">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def vfork : Checker<"vfork">, HelpText<"Warn on uses of the 'vfork' function">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; + def UncheckedReturn : Checker<"UncheckedReturn">, HelpText<"Warn on uses of functions whose return values must be always " "checked">, + Dependencies<[SecuritySyntaxChecker]>, + Documentation<HasDocumentation>; + +def DeprecatedOrUnsafeBufferHandling : + Checker<"DeprecatedOrUnsafeBufferHandling">, + HelpText<"Warn on uses of unsecure or deprecated buffer manipulating " + "functions">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; } // end "security.insecureAPI" @@ -462,6 +750,7 @@ let ParentPackage = Security in { def FloatLoopCounter : Checker<"FloatLoopCounter">, HelpText<"Warn on using a floating point value as a loop counter (CERT: " "FLP30-C, FLP30-CPP)">, + Dependencies<[SecuritySyntaxChecker]>, Documentation<HasDocumentation>; } // end "security" @@ -484,11 +773,20 @@ def MallocOverflowSecurityChecker : Checker<"MallocOverflow">, HelpText<"Check for overflows in the arguments to malloc()">, Documentation<HasAlphaDocumentation>; -// Operating systems specific PROT_READ/PROT_WRITE values is not implemented, -// the defaults are correct for several common operating systems though, -// but may need to be overridden via the related analyzer-config flags. def MmapWriteExecChecker : Checker<"MmapWriteExec">, HelpText<"Warn on mmap() calls that are both writable and executable">, + CheckerOptions<[ + CmdLineOption<Integer, + "MmapProtExec", + "Specifies the value of PROT_EXEC", + "0x04", + Released>, + CmdLineOption<Integer, + "MmapProtRead", + "Specifies the value of PROT_READ", + "0x01", + Released> + ]>, Documentation<HasAlphaDocumentation>; } // end "alpha.security" @@ -506,97 +804,37 @@ def GenericTaintChecker : Checker<"TaintPropagation">, } // end "alpha.security.taint" //===----------------------------------------------------------------------===// -// Unix API checkers. +// Mac OS X, Cocoa, and Core Foundation checkers. //===----------------------------------------------------------------------===// -let ParentPackage = Unix in { - -def UnixAPIMisuseChecker : Checker<"API">, - HelpText<"Check calls to various UNIX/Posix functions">, - Documentation<HasDocumentation>; - -def MallocChecker: Checker<"Malloc">, - HelpText<"Check for memory leaks, double free, and use-after-free problems. " - "Traces memory managed by malloc()/free().">, - Documentation<HasDocumentation>; - -def MallocSizeofChecker : Checker<"MallocSizeof">, - HelpText<"Check for dubious malloc arguments involving sizeof">, - Documentation<HasDocumentation>; - -def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">, - HelpText<"Check for mismatched deallocators.">, - Documentation<HasDocumentation>; - -def VforkChecker : Checker<"Vfork">, - HelpText<"Check for proper usage of vfork">, - Documentation<HasDocumentation>; - -} // end "unix" - -let ParentPackage = UnixAlpha in { - -def ChrootChecker : Checker<"Chroot">, - HelpText<"Check improper use of chroot">, - Documentation<HasAlphaDocumentation>; - -def PthreadLockChecker : Checker<"PthreadLock">, - HelpText<"Simple lock -> unlock checker">, - Documentation<HasAlphaDocumentation>; - -def StreamChecker : Checker<"Stream">, - HelpText<"Check stream handling functions">, - Documentation<HasAlphaDocumentation>; - -def SimpleStreamChecker : Checker<"SimpleStream">, - HelpText<"Check for misuses of stream APIs">, - Documentation<HasAlphaDocumentation>; - -def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, - HelpText<"Check for calls to blocking functions inside a critical section">, - Documentation<HasAlphaDocumentation>; - -} // end "alpha.unix" - -let ParentPackage = CString in { - -def CStringNullArg : Checker<"NullArg">, - HelpText<"Check for null pointers being passed as arguments to C string " - "functions">, - Documentation<HasDocumentation>; - -def CStringSyntaxChecker : Checker<"BadSizeArg">, - HelpText<"Check the size argument passed into C string functions for common " - "erroneous patterns">, - Documentation<HasDocumentation>; - -} // end "unix.cstring" - -let ParentPackage = CStringAlpha in { - -def CStringOutOfBounds : Checker<"OutOfBounds">, - HelpText<"Check for out-of-bounds access in string functions">, - Documentation<HasAlphaDocumentation>; - -def CStringBufferOverlap : Checker<"BufferOverlap">, - HelpText<"Checks for overlap in two buffer arguments">, - Documentation<HasAlphaDocumentation>; - -def CStringNotNullTerm : Checker<"NotNullTerminated">, - HelpText<"Check for arguments which are not null-terminating strings">, - Documentation<HasAlphaDocumentation>; +let ParentPackage = Cocoa in { -} // end "alpha.unix.cstring" +def RetainCountBase : Checker<"RetainCountBase">, + HelpText<"Common base of various retain count related checkers">, + Documentation<NotDocumented>, + Hidden; -//===----------------------------------------------------------------------===// -// Mac OS X, Cocoa, and Core Foundation checkers. -//===----------------------------------------------------------------------===// +} // end "osx.cocoa" let ParentPackage = OSX in { +def NSOrCFErrorDerefChecker : Checker<"NSOrCFErrorDerefChecker">, + HelpText<"Implementation checker for NSErrorChecker and CFErrorChecker">, + Documentation<NotDocumented>, + Hidden; + def NumberObjectConversionChecker : Checker<"NumberObjectConversion">, HelpText<"Check for erroneous conversions of objects representing numbers " "into numbers">, + CheckerOptions<[ + CmdLineOption<Boolean, + "Pedantic", + "Enables detection of more conversion patterns (which are " + "most likely more harmless, and therefore are more likely to " + "produce false positives).", + "false", + Released> + ]>, Documentation<NotDocumented>; def MacOSXAPIChecker : Checker<"API">, @@ -607,12 +845,19 @@ def MacOSKeychainAPIChecker : Checker<"SecKeychainAPI">, HelpText<"Check for proper uses of Secure Keychain APIs">, Documentation<HasDocumentation>; +def MIGChecker : Checker<"MIG">, + HelpText<"Find violations of the Mach Interface Generator " + "calling convention">, + Documentation<NotDocumented>; + def ObjCPropertyChecker : Checker<"ObjCProperty">, HelpText<"Check for proper uses of Objective-C properties">, Documentation<NotDocumented>; def OSObjectRetainCountChecker : Checker<"OSObjectRetainCount">, - HelpText<"Check for leaks and improper reference count management for OSObject">, + HelpText<"Check for leaks and improper reference count management for " + "OSObject">, + Dependencies<[RetainCountBase]>, Documentation<NotDocumented>; } // end "osx" @@ -676,14 +921,37 @@ def ObjCSuperCallChecker : Checker<"MissingSuperCall">, def NSErrorChecker : Checker<"NSError">, HelpText<"Check usage of NSError** parameters">, + Dependencies<[NSOrCFErrorDerefChecker]>, Documentation<HasDocumentation>; def RetainCountChecker : Checker<"RetainCount">, HelpText<"Check for leaks and improper reference count management">, + CheckerOptions<[ + CmdLineOption<Boolean, + "CheckOSObject", + "Find violations of retain-release rules applied to XNU " + "OSObject instances. By default, the checker only checks " + "retain-release rules for Objective-C NSObject instances " + "and CoreFoundation objects.", + "true", + InAlpha, + Hide>, + CmdLineOption<Boolean, + "TrackNSCFStartParam", + "Check not only that the code follows retain-release rules " + "with respect to objects it allocates or borrows from " + "elsewhere, but also that it fulfills its own retain count " + "specification with respect to objects that it receives as " + "arguments.", + "false", + Released> + ]>, + Dependencies<[RetainCountBase]>, Documentation<HasDocumentation>; def ObjCGenericsChecker : Checker<"ObjCGenerics">, HelpText<"Check for type errors when using Objective-C generics">, + Dependencies<[DynamicTypePropagation]>, Documentation<HasDocumentation>; def ObjCDeallocChecker : Checker<"Dealloc">, @@ -710,16 +978,33 @@ def GCDAntipattern : Checker<"GCDAntipattern">, Documentation<NotDocumented>; } // end "optin.performance" +let ParentPackage = OSXOptIn in { + +def OSObjectCStyleCast : Checker<"OSObjectCStyleCast">, + HelpText<"Checker for C-style casts of OSObjects">, + Documentation<NotDocumented>; + +} // end "optin.osx" + let ParentPackage = CocoaAlpha in { +def IvarInvalidationModeling : Checker<"IvarInvalidationModeling">, + HelpText<"Gathers information for annotation driven invalidation checking " + "for classes that contains a method annotated with " + "'objc_instance_variable_invalidator'">, + Documentation<NotDocumented>, + Hidden; + def InstanceVariableInvalidation : Checker<"InstanceVariableInvalidation">, HelpText<"Check that the invalidatable instance variables are invalidated in " "the methods annotated with objc_instance_variable_invalidator">, + Dependencies<[IvarInvalidationModeling]>, Documentation<HasAlphaDocumentation>; def MissingInvalidationMethod : Checker<"MissingInvalidationMethod">, HelpText<"Check that the invalidation methods are present in classes that " "contain invalidatable instance variables">, + Dependencies<[IvarInvalidationModeling]>, Documentation<HasAlphaDocumentation>; def DirectIvarAssignment : Checker<"DirectIvarAssignment">, @@ -730,6 +1015,7 @@ def DirectIvarAssignmentForAnnotatedFunctions : Checker<"DirectIvarAssignmentForAnnotatedFunctions">, HelpText<"Check for direct assignments to instance variables in the methods " "annotated with objc_no_direct_instance_variable_assignment">, + Dependencies<[DirectIvarAssignment]>, Documentation<HasAlphaDocumentation>; } // end "alpha.osx.cocoa" @@ -746,6 +1032,7 @@ def CFRetainReleaseChecker : Checker<"CFRetainRelease">, def CFErrorChecker : Checker<"CFError">, HelpText<"Check usage of CFErrorRef* parameters">, + Dependencies<[NSOrCFErrorDerefChecker]>, Documentation<HasDocumentation>; } // end "osx.coreFoundation" @@ -768,6 +1055,19 @@ let ParentPackage = LocalizabilityOptIn in { def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">, HelpText<"Warns about uses of non-localized NSStrings passed to UI methods " "expecting localized NSStrings">, + CheckerOptions<[ + CmdLineOption<Boolean, + "AggressiveReport", + "Marks a string being returned by any call as localized if " + "it is in LocStringFunctions (LSF) or the function is " + "annotated. Otherwise, we mark it as NonLocalized " + "(Aggressive) or NonLocalized only if it is not backed by a " + "SymRegion (Non-Aggressive), basically leaving only string " + "literals as NonLocalized.", + "false", + InAlpha, + Hide> + ]>, Documentation<HasDocumentation>; def EmptyLocalizationContextChecker : @@ -806,6 +1106,18 @@ def LLVMConventionsChecker : Checker<"Conventions">, } // end "llvm" +let ParentPackage = LLVMAPIModeling in { + +def CastValueChecker : Checker<"CastValue">, + HelpText<"Model implementation of custom RTTIs">, + Documentation<NotDocumented>; + +def ReturnValueChecker : Checker<"ReturnValue">, + HelpText<"Model the guaranteed boolean return value of function calls">, + Documentation<NotDocumented>; + +} // end "apiModeling.llvm" + //===----------------------------------------------------------------------===// // Checkers modeling Google APIs. //===----------------------------------------------------------------------===// @@ -826,12 +1138,118 @@ let ParentPackage = Debug in { def AnalysisOrderChecker : Checker<"AnalysisOrder">, HelpText<"Print callbacks that are called during analysis in order">, + CheckerOptions<[ + CmdLineOption<Boolean, + "PreStmtCastExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PostStmtCastExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PreStmtArraySubscriptExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PostStmtArraySubscriptExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PreStmtCXXNewExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PostStmtCXXNewExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PreStmtOffsetOfExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PostStmtOffsetOfExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PreCall", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PostCall", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "EndFunction", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "NewAllocator", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "Bind", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "LiveSymbols", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "RegionChanges", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "*", + "Enables all callbacks.", + "false", + Released, + Hide> + ]>, Documentation<NotDocumented>; def DominatorsTreeDumper : Checker<"DumpDominators">, HelpText<"Print the dominance tree for a given CFG">, Documentation<NotDocumented>; +def PostDominatorsTreeDumper : Checker<"DumpPostDominators">, + HelpText<"Print the post dominance tree for a given CFG">, + Documentation<NotDocumented>; + +def ControlDependencyTreeDumper : Checker<"DumpControlDependencies">, + HelpText<"Print the post control dependency tree for a given CFG">, + Documentation<NotDocumented>; + def LiveVariablesDumper : Checker<"DumpLiveVars">, HelpText<"Print results of live variable analysis">, Documentation<NotDocumented>; @@ -884,6 +1302,10 @@ def ExplodedGraphViewer : Checker<"ViewExplodedGraph">, HelpText<"View Exploded Graphs using GraphViz">, Documentation<NotDocumented>; +def ReportStmts : Checker<"ReportStmts">, + HelpText<"Emits a warning for every statement.">, + Documentation<NotDocumented>; + } // end "debug" @@ -895,6 +1317,28 @@ let ParentPackage = CloneDetectionAlpha in { def CloneChecker : Checker<"CloneChecker">, HelpText<"Reports similar pieces of code.">, + CheckerOptions<[ + CmdLineOption<Integer, + "MinimumCloneComplexity", + "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.", + "50", + Released>, + CmdLineOption<Boolean, + "ReportNormalClones", + "Report all clones, even less suspicious ones.", + "true", + Released>, + CmdLineOption<String, + "IgnoredFilesPattern", + "If supplied, the checker wont analyze files with a filename " + "that matches the given pattern.", + "\"\"", + Released> + ]>, Documentation<HasAlphaDocumentation>; } // end "clone" @@ -910,3 +1354,19 @@ def UnixAPIPortabilityChecker : Checker<"UnixAPI">, Documentation<NotDocumented>; } // end optin.portability + +//===----------------------------------------------------------------------===// +// NonDeterminism checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = NonDeterminismAlpha in { + +def PointerIterationChecker : Checker<"PointerIteration">, + HelpText<"Checks for non-determinism caused by iteration of unordered containers of pointers">, + Documentation<HasDocumentation>; + +def PointerSortingChecker : Checker<"PointerSorting">, + HelpText<"Check for non-determinism caused by sorting of pointers">, + Documentation<HasDocumentation>; + +} // end alpha.nondeterminism diff --git a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h index 463f04a65ac3..8f7148fde19a 100644 --- a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h +++ b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h @@ -1,9 +1,8 @@ //==- LocalCheckers.h - Intra-Procedural+Flow-Sensitive Checkers -*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h b/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h index 65e908912c54..bbc5111ccacc 100644 --- a/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h +++ b/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h @@ -1,9 +1,8 @@ //===-- MPIFunctionClassifier.h - classifies MPI functions ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/StaticAnalyzer/Checkers/SValExplainer.h b/include/clang/StaticAnalyzer/Checkers/SValExplainer.h index 62bb0f666d44..10c890246521 100644 --- a/include/clang/StaticAnalyzer/Checkers/SValExplainer.h +++ b/include/clang/StaticAnalyzer/Checkers/SValExplainer.h @@ -1,9 +1,8 @@ //== SValExplainer.h - Symbolic value explainer -----------------*- C++ -*--==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def index 99e26c75e1c2..377451576148 100644 --- a/include/clang/StaticAnalyzer/Core/Analyses.def +++ b/include/clang/StaticAnalyzer/Core/Analyses.def @@ -1,9 +1,8 @@ //===-- Analyses.def - Metadata about Static Analyses -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def index 3cd54df7b179..70bd476b6c43 100644 --- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -1,9 +1,8 @@ //===-- AnalyzerOptions.def - Metadata about Static Analyses ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -205,6 +204,10 @@ ANALYZER_OPTION(bool, ShouldPrunePaths, "prune-paths", "be pruned out of the final output.", true) +ANALYZER_OPTION(bool, ShouldAddPopUpNotes, "add-pop-up-notes", + "Whether pop-up notes should be added to the final output.", + true) + ANALYZER_OPTION( bool, ShouldConditionalizeStaticInitializers, "cfg-conditional-static-initializers", @@ -288,6 +291,23 @@ ANALYZER_OPTION(bool, DisplayCTUProgress, "display-ctu-progress", "the analyzer's progress related to ctu.", false) +ANALYZER_OPTION(bool, ShouldTrackConditions, "track-conditions", + "Whether to track conditions that are a control dependency of " + "an already tracked variable.", + false) + +ANALYZER_OPTION(bool, ShouldTrackConditionsDebug, "track-conditions-debug", + "Whether to place an event at each tracked condition.", + false) + +ANALYZER_OPTION(unsigned, CTUImportThreshold, "ctu-import-threshold", + "The maximal amount of translation units that is considered " + "for import when inlining functions during CTU analysis. " + "Lowering this threshold can alleviate the memory burder of " + "analysis with many interdependent definitions located in " + "various translation units.", + 100u) + //===----------------------------------------------------------------------===// // Unsinged analyzer options. //===----------------------------------------------------------------------===// diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index 7745e459e19b..9630a229bd3b 100644 --- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -1,9 +1,8 @@ //===- AnalyzerOptions.h - Analysis Engine Options --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -167,6 +166,29 @@ public: static std::vector<StringRef> getRegisteredCheckers(bool IncludeExperimental = false); + /// Convenience function for printing options or checkers and their + /// description in a formatted manner. If \p MinLineWidth is set to 0, no line + /// breaks are introduced for the description. + /// + /// Format, depending whether the option name's length is less then + /// \p OptionWidth: + /// + /// <padding>EntryName<padding>Description + /// <---------padding--------->Description + /// <---------padding--------->Description + /// + /// <padding>VeryVeryLongOptionName + /// <---------padding--------->Description + /// <---------padding--------->Description + /// ^~~~~~~~ InitialPad + /// ^~~~~~~~~~~~~~~~~~~~~~~~~~ EntryWidth + /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~MinLineWidth + static void printFormattedEntry( + llvm::raw_ostream &Out, + std::pair<StringRef, StringRef> EntryDescPair, + size_t EntryWidth, size_t InitialPad, size_t MinLineWidth = 0); + + /// Pair of checker name and enable/disable. std::vector<std::pair<std::string, bool>> CheckersControlList; @@ -198,6 +220,13 @@ public: unsigned DisableAllChecks : 1; unsigned ShowCheckerHelp : 1; + unsigned ShowCheckerHelpAlpha : 1; + unsigned ShowCheckerHelpDeveloper : 1; + + unsigned ShowCheckerOptionList : 1; + unsigned ShowCheckerOptionAlphaList : 1; + unsigned ShowCheckerOptionDeveloperList : 1; + unsigned ShowEnabledCheckerList : 1; unsigned ShowConfigOptionsList : 1; unsigned ShouldEmitErrorsOnInvalidConfigValue : 1; @@ -216,6 +245,9 @@ public: /// strategy. We get better code coverage when retry is enabled. unsigned NoRetryExhausted : 1; + /// Emit analyzer warnings as errors. + unsigned AnalyzerWerror : 1; + /// The inlining stack depth limit. // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls). unsigned InlineMaxStackDepth = 5; @@ -261,11 +293,14 @@ public: AnalyzerOptions() : DisableAllChecks(false), ShowCheckerHelp(false), - ShowEnabledCheckerList(false), ShowConfigOptionsList(false), - AnalyzeAll(false), AnalyzerDisplayProgress(false), - AnalyzeNestedBlocks(false), eagerlyAssumeBinOpBifurcation(false), - TrimGraph(false), visualizeExplodedGraphWithGraphViz(false), - UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false) { + ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false), + ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false), + ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false), + ShowConfigOptionsList(false), AnalyzeAll(false), + AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false), + eagerlyAssumeBinOpBifurcation(false), TrimGraph(false), + visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false), + PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) { llvm::sort(AnalyzerConfigCmdFlags); } @@ -273,54 +308,63 @@ public: /// interpreted as true and the "false" string is interpreted as false. /// /// If an option value is not provided, returns the given \p DefaultVal. - /// @param [in] Name Name for option to retrieve. - /// @param [in] DefaultVal Default value returned if no such option was - /// specified. - /// @param [in] C The checker object the option belongs to. Checker options - /// are retrieved in the following format: - /// `-analyzer-config <package and checker name>:OptionName=Value. + /// @param [in] CheckerName The *full name* of the checker. One may retrieve + /// this from the checker object's field \c Name, or through \c + /// CheckerManager::getCurrentCheckName within the checker's registry + /// function. + /// Checker options are retrieved in the following format: + /// `-analyzer-config CheckerName:OptionName=Value. + /// @param [in] OptionName Name for option to retrieve. /// @param [in] SearchInParents If set to true and the searched option was not /// specified for the given checker the options for the parent packages will /// be searched as well. The inner packages take precedence over the outer /// ones. - bool getCheckerBooleanOption(StringRef Name, bool DefaultVal, - const ento::CheckerBase *C, - bool SearchInParents = false) const; + bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName, + bool SearchInParents = false) const; + bool getCheckerBooleanOption(const ento::CheckerBase *C, StringRef OptionName, + bool SearchInParents = false) const; /// Interprets an option's string value as an integer value. /// /// If an option value is not provided, returns the given \p DefaultVal. - /// @param [in] Name Name for option to retrieve. - /// @param [in] DefaultVal Default value returned if no such option was - /// specified. - /// @param [in] C The checker object the option belongs to. Checker options - /// are retrieved in the following format: - /// `-analyzer-config <package and checker name>:OptionName=Value. + /// @param [in] CheckerName The *full name* of the checker. One may retrieve + /// this from the checker object's field \c Name, or through \c + /// CheckerManager::getCurrentCheckName within the checker's registry + /// function. + /// Checker options are retrieved in the following format: + /// `-analyzer-config CheckerName:OptionName=Value. + /// @param [in] OptionName Name for option to retrieve. /// @param [in] SearchInParents If set to true and the searched option was not /// specified for the given checker the options for the parent packages will /// be searched as well. The inner packages take precedence over the outer /// ones. - int getCheckerIntegerOption(StringRef Name, int DefaultVal, - const ento::CheckerBase *C, - bool SearchInParents = false) const; + int getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName, + bool SearchInParents = false) const; + + int getCheckerIntegerOption(const ento::CheckerBase *C, StringRef OptionName, + bool SearchInParents = false) const; /// Query an option's string value. /// /// If an option value is not provided, returns the given \p DefaultVal. - /// @param [in] Name Name for option to retrieve. - /// @param [in] DefaultVal Default value returned if no such option was - /// specified. - /// @param [in] C The checker object the option belongs to. Checker options - /// are retrieved in the following format: - /// `-analyzer-config <package and checker name>:OptionName=Value. + /// @param [in] CheckerName The *full name* of the checker. One may retrieve + /// this from the checker object's field \c Name, or through \c + /// CheckerManager::getCurrentCheckName within the checker's registry + /// function. + /// Checker options are retrieved in the following format: + /// `-analyzer-config CheckerName:OptionName=Value. + /// @param [in] OptionName Name for option to retrieve. /// @param [in] SearchInParents If set to true and the searched option was not /// specified for the given checker the options for the parent packages will /// be searched as well. The inner packages take precedence over the outer /// ones. - StringRef getCheckerStringOption(StringRef Name, StringRef DefaultVal, - const ento::CheckerBase *C, - bool SearchInParents = false) const; + StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName, + bool SearchInParents = false) const; + + StringRef getCheckerStringOption(const ento::CheckerBase *C, + StringRef OptionName, + bool SearchInParents = false) const; /// Retrieves and sets the UserMode. This is a high-level option, /// which is used to set other low-level options. It is not accessible diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 9041f4c1afbd..d30ad19b20f8 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -1,9 +1,8 @@ //===- BugReporter.h - Generate PathDiagnostics -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -95,7 +94,7 @@ protected: friend class BugReportEquivClass; friend class BugReporter; - BugType& BT; + const BugType& BT; const Decl *DeclWithIssue = nullptr; std::string ShortDescription; std::string Description; @@ -154,6 +153,9 @@ protected: /// \sa removeInvalidation llvm::SmallSet<InvalidationRecord, 4> Invalidations; + /// Conditions we're already tracking. + llvm::SmallSet<const ExplodedNode *, 4> TrackedConditions; + private: // Used internally by BugReporter. Symbols &getInterestingSymbols(); @@ -164,15 +166,15 @@ private: void popInterestingSymbolsAndRegions(); public: - BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode) + BugReport(const BugType& bt, StringRef desc, const ExplodedNode *errornode) : BT(bt), Description(desc), ErrorNode(errornode) {} - BugReport(BugType& bt, StringRef shortDesc, StringRef desc, + BugReport(const BugType& bt, StringRef shortDesc, StringRef desc, const ExplodedNode *errornode) : BT(bt), ShortDescription(shortDesc), Description(desc), ErrorNode(errornode) {} - BugReport(BugType &bt, StringRef desc, PathDiagnosticLocation l) + BugReport(const BugType &bt, StringRef desc, PathDiagnosticLocation l) : BT(bt), Description(desc), Location(l) {} /// Create a BugReport with a custom uniqueing location. @@ -190,7 +192,7 @@ public: virtual ~BugReport(); const BugType& getBugType() const { return BT; } - BugType& getBugType() { return BT; } + //BugType& getBugType() { return BT; } /// True when the report has an execution path associated with it. /// @@ -350,6 +352,13 @@ public: visitor_iterator visitor_begin() { return Callbacks.begin(); } visitor_iterator visitor_end() { return Callbacks.end(); } + /// Notes that the condition of the CFGBlock associated with \p Cond is + /// being tracked. + /// \returns false if the condition is already being tracked. + bool addTrackedCondition(const ExplodedNode *Cond) { + return TrackedConditions.insert(Cond).second; + } + /// Profile to identify equivalent bug reports for error report coalescing. /// Reports are uniqued to ensure that we do not emit multiple diagnostics /// for each bug. @@ -481,7 +490,7 @@ public: return {}; } - void Register(BugType *BT); + void Register(const BugType *BT); /// Add the given report to the set of reports tracked by BugReporter. /// @@ -593,6 +602,63 @@ public: NodeMapClosure& getNodeResolver() { return NMC; } }; + +/// The tag upon which the TagVisitor reacts. Add these in order to display +/// additional PathDiagnosticEventPieces along the path. +class NoteTag : public ProgramPointTag { +public: + using Callback = + std::function<std::string(BugReporterContext &, BugReport &)>; + +private: + static int Kind; + + const Callback Cb; + const bool IsPrunable; + + NoteTag(Callback &&Cb, bool IsPrunable) + : ProgramPointTag(&Kind), Cb(std::move(Cb)), IsPrunable(IsPrunable) {} + +public: + static bool classof(const ProgramPointTag *T) { + return T->getTagKind() == &Kind; + } + + Optional<std::string> generateMessage(BugReporterContext &BRC, + BugReport &R) const { + std::string Msg = Cb(BRC, R); + if (Msg.empty()) + return None; + + return std::move(Msg); + } + + StringRef getTagDescription() const override { + // TODO: Remember a few examples of generated messages + // and display them in the ExplodedGraph dump by + // returning them from this function. + return "Note Tag"; + } + + bool isPrunable() const { return IsPrunable; } + + // Manage memory for NoteTag objects. + class Factory { + std::vector<std::unique_ptr<NoteTag>> Tags; + + public: + const NoteTag *makeNoteTag(Callback &&Cb, bool IsPrunable = false) { + // We cannot use make_unique because we cannot access the private + // constructor from inside it. + std::unique_ptr<NoteTag> T(new NoteTag(std::move(Cb), IsPrunable)); + Tags.push_back(std::move(T)); + return Tags.back().get(); + } + }; + + friend class TagVisitor; +}; + } // namespace ento } // namespace clang diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h index c023ed5641a3..ef5d327d39da 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h @@ -1,9 +1,8 @@ //===- BugReporterVisitors.h - Generate PathDiagnostics ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -15,6 +14,7 @@ #ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H #define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H +#include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" @@ -189,22 +189,40 @@ public: BugReporterContext &BRC); std::shared_ptr<PathDiagnosticPiece> - VisitTrueTest(const Expr *Cond, bool tookTrue, BugReporterContext &BRC, - BugReport &R, const ExplodedNode *N); + VisitTrueTest(const Expr *Cond, BugReporterContext &BRC, BugReport &R, + const ExplodedNode *N, bool TookTrue); std::shared_ptr<PathDiagnosticPiece> - VisitTrueTest(const Expr *Cond, const DeclRefExpr *DR, const bool tookTrue, - BugReporterContext &BRC, BugReport &R, const ExplodedNode *N); + VisitTrueTest(const Expr *Cond, const DeclRefExpr *DR, + BugReporterContext &BRC, BugReport &R, const ExplodedNode *N, + bool TookTrue, bool IsAssuming); std::shared_ptr<PathDiagnosticPiece> VisitTrueTest(const Expr *Cond, const BinaryOperator *BExpr, - const bool tookTrue, BugReporterContext &BRC, BugReport &R, - const ExplodedNode *N); + BugReporterContext &BRC, BugReport &R, const ExplodedNode *N, + bool TookTrue, bool IsAssuming); + + std::shared_ptr<PathDiagnosticPiece> + VisitTrueTest(const Expr *Cond, const MemberExpr *ME, BugReporterContext &BRC, + BugReport &R, const ExplodedNode *N, bool TookTrue, + bool IsAssuming); std::shared_ptr<PathDiagnosticPiece> VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr, - const bool tookTrue, BugReporterContext &BRC, - BugReport &R, const ExplodedNode *N); + BugReporterContext &BRC, BugReport &R, + const ExplodedNode *N, bool TookTrue); + + /// Tries to print the value of the given expression. + /// + /// \param CondVarExpr The expression to print its value. + /// \param Out The stream to print. + /// \param N The node where we encountered the condition. + /// \param TookTrue Whether we took the \c true branch of the condition. + /// + /// \return Whether the print was successful. (The printing is successful if + /// we model the value and we could obtain it.) + bool printValue(const Expr *CondVarExpr, raw_ostream &Out, + const ExplodedNode *N, bool TookTrue, bool IsAssuming); bool patternMatch(const Expr *Ex, const Expr *ParentEx, @@ -212,7 +230,8 @@ public: BugReporterContext &BRC, BugReport &R, const ExplodedNode *N, - Optional<bool> &prunable); + Optional<bool> &prunable, + bool IsSameFieldName); static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece); }; @@ -294,34 +313,6 @@ public: BugReport &BR) override; }; -class CXXSelfAssignmentBRVisitor final : public BugReporterVisitor { - bool Satisfied = false; - -public: - CXXSelfAssignmentBRVisitor() = default; - - void Profile(llvm::FoldingSetNodeID &ID) const override {} - - std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ, - BugReporterContext &BRC, - BugReport &BR) override; -}; - -/// The bug visitor prints a diagnostic message at the location where a given -/// variable was tainted. -class TaintBugVisitor final : public BugReporterVisitor { -private: - const SVal V; - -public: - TaintBugVisitor(const SVal V) : V(V) {} - void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); } - - std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N, - BugReporterContext &BRC, - BugReport &BR) override; -}; - /// The bug visitor will walk all the nodes in a path and collect all the /// constraints. When it reaches the root node, will create a refutation /// manager and check if the constraints are satisfiable @@ -343,6 +334,17 @@ public: BugReport &BR) override; }; + +/// The visitor detects NoteTags and displays the event notes they contain. +class TagVisitor : public BugReporterVisitor { +public: + void Profile(llvm::FoldingSetNodeID &ID) const override; + + std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N, + BugReporterContext &BRC, + BugReport &R) override; +}; + namespace bugreporter { /// Attempts to add visitors to track expression value back to its point of diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h index 727ec7c66a89..324b5312e790 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h @@ -1,9 +1,8 @@ //===--- BugType.h - Bug Information Description ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -38,12 +37,14 @@ private: virtual void anchor(); public: - BugType(CheckName Check, StringRef Name, StringRef Cat) + BugType(CheckName Check, StringRef Name, StringRef Cat, + bool SuppressOnSink=false) : Check(Check), Name(Name), Category(Cat), Checker(nullptr), - SuppressOnSink(false) {} - BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat) + SuppressOnSink(SuppressOnSink) {} + BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat, + bool SuppressOnSink=false) : Check(Checker->getCheckName()), Name(Name), Category(Cat), - Checker(Checker), SuppressOnSink(false) {} + Checker(Checker), SuppressOnSink(SuppressOnSink) {} virtual ~BugType() = default; StringRef getName() const { return Name; } @@ -64,7 +65,6 @@ public: /// type should be suppressed if the end node of the report is post-dominated /// by a sink node. bool isSuppressOnSink() const { return SuppressOnSink; } - void setSuppressOnSink(bool x) { SuppressOnSink = x; } }; class BuiltinBug : public BugType { diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h index d07525661a6c..85526eb49f0c 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h @@ -1,9 +1,8 @@ //=--- CommonBugCategories.h - Provides common issue categories -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index e9c682d7986c..5230742a4aa4 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -1,9 +1,8 @@ //===- PathDiagnostic.h - Path-Specific Diagnostic Handling -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -314,6 +313,8 @@ public: bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; } + bool hasValidLocation() const { return asLocation().isValid(); } + void invalidate() { *this = PathDiagnosticLocation(); } @@ -366,7 +367,7 @@ public: class PathDiagnosticPiece: public llvm::FoldingSetNode { public: - enum Kind { ControlFlow, Event, Macro, Call, Note }; + enum Kind { ControlFlow, Event, Macro, Call, Note, PopUp }; enum DisplayHint { Above, Below }; private: @@ -469,7 +470,7 @@ public: PathDiagnosticPiece::Kind k, bool addPosRange = true) : PathDiagnosticPiece(s, k), Pos(pos) { - assert(Pos.isValid() && Pos.asLocation().isValid() && + assert(Pos.isValid() && Pos.hasValidLocation() && "PathDiagnosticSpotPiece's must have a valid location."); if (addPosRange && Pos.hasRange()) addRange(Pos.asRange()); } @@ -481,7 +482,7 @@ public: static bool classof(const PathDiagnosticPiece *P) { return P->getKind() == Event || P->getKind() == Macro || - P->getKind() == Note; + P->getKind() == Note || P->getKind() == PopUp; } }; @@ -745,7 +746,7 @@ public: class PathDiagnosticNotePiece: public PathDiagnosticSpotPiece { public: PathDiagnosticNotePiece(const PathDiagnosticLocation &Pos, StringRef S, - bool AddPosRange = true) + bool AddPosRange = true) : PathDiagnosticSpotPiece(Pos, S, Note, AddPosRange) {} ~PathDiagnosticNotePiece() override; @@ -758,6 +759,22 @@ public: void Profile(llvm::FoldingSetNodeID &ID) const override; }; +class PathDiagnosticPopUpPiece: public PathDiagnosticSpotPiece { +public: + PathDiagnosticPopUpPiece(const PathDiagnosticLocation &Pos, StringRef S, + bool AddPosRange = true) + : PathDiagnosticSpotPiece(Pos, S, PopUp, AddPosRange) {} + ~PathDiagnosticPopUpPiece() override; + + static bool classof(const PathDiagnosticPiece *P) { + return P->getKind() == PopUp; + } + + void dump() const override; + + void Profile(llvm::FoldingSetNodeID &ID) const override; +}; + /// File IDs mapped to sets of line numbers. using FilesToLineNumsMap = std::map<FileID, std::set<unsigned>>; diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h index 786465cee855..d0fe15f8b896 100644 --- a/include/clang/StaticAnalyzer/Core/Checker.h +++ b/include/clang/StaticAnalyzer/Core/Checker.h @@ -1,9 +1,8 @@ //== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -15,6 +14,7 @@ #define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H #include "clang/Analysis/ProgramPoint.h" +#include "clang/Basic/LangOptions.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "llvm/Support/Casting.h" @@ -474,8 +474,9 @@ public: class Call { template <typename CHECKER> - static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) { - return ((const CHECKER *)checker)->evalCall(CE, C); + static bool _evalCall(void *checker, const CallEvent &Call, + CheckerContext &C) { + return ((const CHECKER *)checker)->evalCall(Call, C); } public: diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 538ed19f7eef..6cc4baa1687f 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -1,9 +1,8 @@ //===- CheckerManager.h - Static Analyzer Checker Manager -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -137,12 +136,18 @@ public: AnalyzerOptions &getAnalyzerOptions() { return AOptions; } ASTContext &getASTContext() { return Context; } + /// Emits an error through a DiagnosticsEngine about an invalid user supplied + /// checker option value. + void reportInvalidCheckerOptionValue(const CheckerBase *C, + StringRef OptionName, + StringRef ExpectedValueDesc); + using CheckerRef = CheckerBase *; using CheckerTag = const void *; using CheckerDtor = CheckerFn<void ()>; //===----------------------------------------------------------------------===// -// registerChecker +// Checker registration. //===----------------------------------------------------------------------===// /// Used to register checkers. @@ -154,8 +159,7 @@ public: CHECKER *registerChecker(AT &&... Args) { CheckerTag tag = getTag<CHECKER>(); CheckerRef &ref = CheckerTags[tag]; - if (ref) - return static_cast<CHECKER *>(ref); // already registered. + assert(!ref && "Checker already registered, use getChecker!"); CHECKER *checker = new CHECKER(std::forward<AT>(Args)...); checker->Name = CurrentCheckName; @@ -165,8 +169,17 @@ public: return checker; } + template <typename CHECKER> + CHECKER *getChecker() { + CheckerTag tag = getTag<CHECKER>(); + assert(CheckerTags.count(tag) != 0 && + "Requested checker is not registered! Maybe you should add it as a " + "dependency in Checkers.td?"); + return static_cast<CHECKER *>(CheckerTags[tag]); + } + //===----------------------------------------------------------------------===// -// Functions for running checkers for AST traversing.. +// Functions for running checkers for AST traversing. //===----------------------------------------------------------------------===// /// Run checkers handling Decls. @@ -393,16 +406,20 @@ public: /// /// Unlike most other callbacks, any checker can simply implement the virtual /// method CheckerBase::printState if it has custom data to print. - /// \param Out The output stream + /// + /// \param Out The output stream /// \param State The state being printed - /// \param NL The preferred representation of a newline. - /// \param Sep The preferred separator between different kinds of data. - void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep); - -//===----------------------------------------------------------------------===// -// Internal registration functions for AST traversing. -//===----------------------------------------------------------------------===// + /// \param NL The preferred representation of a newline. + /// \param Space The preferred space between the left side and the message. + /// \param IsDot Whether the message will be printed in 'dot' format. + void runCheckersForPrintStateJson(raw_ostream &Out, ProgramStateRef State, + const char *NL = "\n", + unsigned int Space = 0, + bool IsDot = false) const; + + //===----------------------------------------------------------------------===// + // Internal registration functions for AST traversing. + //===----------------------------------------------------------------------===// // Functions used by the registration mechanism, checkers should not touch // these directly. @@ -473,7 +490,7 @@ public: CheckerFn<ProgramStateRef (ProgramStateRef, const SVal &cond, bool assumption)>; - using EvalCallFunc = CheckerFn<bool (const CallExpr *, CheckerContext &)>; + using EvalCallFunc = CheckerFn<bool (const CallEvent &, CheckerContext &)>; using CheckEndOfTranslationUnit = CheckerFn<void (const TranslationUnitDecl *, AnalysisManager &, diff --git a/include/clang/StaticAnalyzer/Core/IssueHash.h b/include/clang/StaticAnalyzer/Core/IssueHash.h index 03997aae79ae..38d5f847fc29 100644 --- a/include/clang/StaticAnalyzer/Core/IssueHash.h +++ b/include/clang/StaticAnalyzer/Core/IssueHash.h @@ -1,9 +1,8 @@ //===---------- IssueHash.h - Generate identification hashes ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_STATICANALYZER_CORE_ISSUE_HASH_H diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h index 2e81aa38c8de..ef6e7e0f45d5 100644 --- a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h +++ b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h @@ -1,9 +1,8 @@ //===--- PathDiagnosticConsumers.h - Path Diagnostic Clients ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h index 243795e720f6..4b7d6054cd87 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h @@ -1,9 +1,8 @@ //== APSIntType.h - Simple record of the type of APSInts --------*- C++ -*--==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index 50b9b566edc3..b0dda78a00a9 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -1,9 +1,8 @@ //== AnalysisManager.h - Path sensitive analysis data manager ------*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index 1c5d4eb2de32..ac218bc070e9 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -1,9 +1,8 @@ //==- BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h index 5e831095abc7..46ff69e0c396 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h @@ -1,9 +1,8 @@ //==- BlockCounter.h - ADT for counting block visits ---------------*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index 81dd83fc1071..db84102983af 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -1,9 +1,8 @@ //===- CallEvent.h - Wrapper for all function and method calls --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -72,39 +71,7 @@ enum CallEventKind { }; class CallEvent; - -/// This class represents a description of a function call using the number of -/// arguments and the name of the function. -class CallDescription { - friend CallEvent; - - mutable IdentifierInfo *II = nullptr; - mutable bool IsLookupDone = false; - // The list of the qualified names used to identify the specified CallEvent, - // e.g. "{a, b}" represent the qualified names, like "a::b". - std::vector<const char *> QualifiedName; - unsigned RequiredArgs; - -public: - const static unsigned NoArgRequirement = std::numeric_limits<unsigned>::max(); - - /// Constructs a CallDescription object. - /// - /// @param QualifiedName The list of the name qualifiers of the function that - /// will be matched. The user is allowed to skip any of the qualifiers. - /// For example, {"std", "basic_string", "c_str"} would match both - /// std::basic_string<...>::c_str() and std::__1::basic_string<...>::c_str(). - /// - /// @param RequiredArgs The number of arguments that is expected to match a - /// call. Omit this parameter to match every occurrence of call with a given - /// name regardless the number of arguments. - CallDescription(ArrayRef<const char *> QualifiedName, - unsigned RequiredArgs = NoArgRequirement) - : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs) {} - - /// Get the name of the function that this object matches. - StringRef getFunctionName() const { return QualifiedName.back(); } -}; +class CallDescription; template<typename T = CallEvent> class CallEventRef : public IntrusiveRefCntPtr<const T> { @@ -1077,6 +1044,85 @@ public: } }; +enum CallDescriptionFlags : int { + /// Describes a C standard function that is sometimes implemented as a macro + /// that expands to a compiler builtin with some __builtin prefix. + /// The builtin may as well have a few extra arguments on top of the requested + /// number of arguments. + CDF_MaybeBuiltin = 1 << 0, +}; + +/// This class represents a description of a function call using the number of +/// arguments and the name of the function. +class CallDescription { + friend CallEvent; + + mutable IdentifierInfo *II = nullptr; + mutable bool IsLookupDone = false; + // The list of the qualified names used to identify the specified CallEvent, + // e.g. "{a, b}" represent the qualified names, like "a::b". + std::vector<const char *> QualifiedName; + Optional<unsigned> RequiredArgs; + int Flags; + +public: + /// Constructs a CallDescription object. + /// + /// @param QualifiedName The list of the name qualifiers of the function that + /// will be matched. The user is allowed to skip any of the qualifiers. + /// For example, {"std", "basic_string", "c_str"} would match both + /// std::basic_string<...>::c_str() and std::__1::basic_string<...>::c_str(). + /// + /// @param RequiredArgs The number of arguments that is expected to match a + /// call. Omit this parameter to match every occurrence of call with a given + /// name regardless the number of arguments. + CallDescription(int Flags, ArrayRef<const char *> QualifiedName, + Optional<unsigned> RequiredArgs = None) + : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs), + Flags(Flags) {} + + /// Construct a CallDescription with default flags. + CallDescription(ArrayRef<const char *> QualifiedName, + Optional<unsigned> RequiredArgs = None) + : CallDescription(0, QualifiedName, RequiredArgs) {} + + /// Get the name of the function that this object matches. + StringRef getFunctionName() const { return QualifiedName.back(); } +}; + +/// An immutable map from CallDescriptions to arbitrary data. Provides a unified +/// way for checkers to react on function calls. +template <typename T> class CallDescriptionMap { + // Some call descriptions aren't easily hashable (eg., the ones with qualified + // names in which some sections are omitted), so let's put them + // in a simple vector and use linear lookup. + // TODO: Implement an actual map for fast lookup for "hashable" call + // descriptions (eg., the ones for C functions that just match the name). + std::vector<std::pair<CallDescription, T>> LinearMap; + +public: + CallDescriptionMap( + std::initializer_list<std::pair<CallDescription, T>> &&List) + : LinearMap(List) {} + + ~CallDescriptionMap() = default; + + // These maps are usually stored once per checker, so let's make sure + // we don't do redundant copies. + CallDescriptionMap(const CallDescriptionMap &) = delete; + CallDescriptionMap &operator=(const CallDescription &) = delete; + + const T *lookup(const CallEvent &Call) const { + // Slow path: linear lookup. + // TODO: Implement some sort of fast path. + for (const std::pair<CallDescription, T> &I : LinearMap) + if (Call.isCalled(I.first)) + return &I.second; + + return nullptr; + } +}; + /// Manages the lifetime of CallEvent objects. /// /// CallEventManager provides a way to create arbitrary CallEvents "on the diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index 6ee75b738465..981133e66977 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -1,9 +1,8 @@ //== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -220,6 +219,45 @@ public: Eng.getBugReporter().emitReport(std::move(R)); } + /// Produce a program point tag that displays an additional path note + /// to the user. This is a lightweight alternative to the + /// BugReporterVisitor mechanism: instead of visiting the bug report + /// node-by-node to restore the sequence of events that led to discovering + /// a bug, you can add notes as you add your transitions. + /// + /// @param Cb Callback with 'BugReporterContext &, BugReport &' parameters. + /// @param IsPrunable Whether the note is prunable. It allows BugReporter + /// to omit the note from the report if it would make the displayed + /// bug path significantly shorter. + const NoteTag *getNoteTag(NoteTag::Callback &&Cb, bool IsPrunable = false) { + return Eng.getNoteTags().makeNoteTag(std::move(Cb), IsPrunable); + } + + /// A shorthand version of getNoteTag that doesn't require you to accept + /// the BugReporterContext arguments when you don't need it. + /// + /// @param Cb Callback only with 'BugReport &' parameter. + /// @param IsPrunable Whether the note is prunable. It allows BugReporter + /// to omit the note from the report if it would make the displayed + /// bug path significantly shorter. + const NoteTag *getNoteTag(std::function<std::string(BugReport &)> &&Cb, + bool IsPrunable = false) { + return getNoteTag( + [Cb](BugReporterContext &, BugReport &BR) { return Cb(BR); }, + IsPrunable); + } + + /// A shorthand version of getNoteTag that accepts a plain note. + /// + /// @param Note The note. + /// @param IsPrunable Whether the note is prunable. It allows BugReporter + /// to omit the note from the report if it would make the displayed + /// bug path significantly shorter. + const NoteTag *getNoteTag(StringRef Note, bool IsPrunable = false) { + return getNoteTag( + [Note](BugReporterContext &, BugReport &) { return Note; }, IsPrunable); + } + /// Returns the word that should be used to refer to the declaration /// in the report. StringRef getDeclDescription(const Decl *D); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h index 7f34a7a5b19d..b53c042a1ca1 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h @@ -1,9 +1,8 @@ //== CheckerHelpers.h - Helper functions for checkers ------------*- C++ -*--=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h index d4f8fbaa43df..f85c37379158 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h @@ -1,9 +1,8 @@ //===- ConstraintManager.h - Constraints on symbolic values. ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -80,6 +79,9 @@ public: ConstraintManager() = default; virtual ~ConstraintManager(); + virtual bool haveEqualConstraints(ProgramStateRef S1, + ProgramStateRef S2) const = 0; + virtual ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond, bool Assumption) = 0; @@ -160,12 +162,9 @@ public: virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper& SymReaper) = 0; - virtual void print(ProgramStateRef state, - raw_ostream &Out, - const char* nl, - const char *sep) = 0; - - virtual void EndPath(ProgramStateRef state) {} + virtual void printJson(raw_ostream &Out, ProgramStateRef State, + const char *NL, unsigned int Space, + bool IsDot) const = 0; /// Convenience method to query the state to see if a symbol is null or /// not null, or if neither assumption can be made. diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 17369a85bfa3..278193ef99ed 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -1,9 +1,8 @@ //===- CoreEngine.h - Path-Sensitive Dataflow Engine ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -20,6 +19,7 @@ #include "clang/Analysis/CFG.h" #include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/LLVM.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" @@ -96,6 +96,10 @@ private: /// (This data is owned by AnalysisConsumer.) FunctionSummariesTy *FunctionSummaries; + /// Add path note tags along the path when we see that something interesting + /// is happening. This field is the allocator for such tags. + NoteTag::Factory NoteTags; + void generateNode(const ProgramPoint &Loc, ProgramStateRef State, ExplodedNode *Pred); @@ -117,6 +121,8 @@ private: void HandleStaticInit(const DeclStmt *DS, const CFGBlock *B, ExplodedNode *Pred); + void HandleVirtualBaseBranch(const CFGBlock *B, ExplodedNode *Pred); + private: ExplodedNode *generateCallExitBeginNode(ExplodedNode *N, const ReturnStmt *RS); @@ -193,9 +199,11 @@ public: /// Enqueue a single node created as a result of statement processing. void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx); + + NoteTag::Factory &getNoteTags() { return NoteTags; } }; -// TODO: Turn into a calss. +// TODO: Turn into a class. struct NodeBuilderContext { const CoreEngine &Eng; const CFGBlock *Block; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h index 092e23ce73c8..9bb1e2137566 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h @@ -1,9 +1,8 @@ //== DynamicTypeInfo.h - Runtime type information ----------------*- C++ -*--=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEINFO_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h index b0d514dc2863..a84b24872061 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h @@ -1,9 +1,8 @@ //===- DynamicTypeMap.h - Dynamic type map ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -30,12 +29,11 @@ class MemRegion; /// symbol to its most likely type. struct DynamicTypeMap {}; -using DynamicTypeMapImpl = - llvm::ImmutableMap<const MemRegion *, DynamicTypeInfo>; +using DynamicTypeMapTy = llvm::ImmutableMap<const MemRegion *, DynamicTypeInfo>; template <> struct ProgramStateTrait<DynamicTypeMap> - : public ProgramStatePartialTrait<DynamicTypeMapImpl> { + : public ProgramStatePartialTrait<DynamicTypeMapTy> { static void *GDMIndex(); }; @@ -55,8 +53,9 @@ inline ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, DynamicTypeInfo(NewTy, CanBeSubClassed)); } -void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out, - const char *NL, const char *Sep); +void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, + const char *NL = "\n", unsigned int Space = 0, + bool IsDot = false); } // namespace ento } // namespace clang diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h index 6d498031bea0..498e36e1431f 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h @@ -1,9 +1,8 @@ //===- Environment.h - Map from Stmt* to Locations/Values -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -92,9 +91,9 @@ public: return ExprBindings == RHS.ExprBindings; } - void print(raw_ostream &Out, const char *NL, const char *Sep, - const ASTContext &Context, - const LocationContext *WithLC = nullptr) const; + void printJson(raw_ostream &Out, const ASTContext &Ctx, + const LocationContext *LCtx = nullptr, const char *NL = "\n", + unsigned int Space = 0, bool IsDot = false) const; }; class EnvironmentManager { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index bf460df278aa..727d04cba278 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -1,9 +1,8 @@ //===- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 86b776afb822..2629d7121de4 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -1,9 +1,8 @@ //===- ExprEngine.h - Path-Sensitive Expression-Level Dataflow --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -23,6 +22,7 @@ #include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h" @@ -131,6 +131,9 @@ private: /// SymMgr - Object that manages the symbol information. SymbolManager &SymMgr; + /// MRMgr - MemRegionManager object that creates memory regions. + MemRegionManager &MRMgr; + /// svalBuilder - SValBuilder object that creates SVals from expressions. SValBuilder &svalBuilder; @@ -158,7 +161,7 @@ public: SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn); - ~ExprEngine() override; + ~ExprEngine() override = default; /// Returns true if there is still simulation state on the worklist. bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { @@ -180,6 +183,10 @@ public: AnalysisManager &getAnalysisManager() override { return AMgr; } + AnalysisDeclContextManager &getAnalysisDeclContextManager() { + return AMgr.getAnalysisDeclContextManager(); + } + CheckerManager &getCheckerManager() const { return *AMgr.getCheckerManager(); } @@ -369,10 +376,10 @@ public: const LocationContext *LCtx, const CallEvent *Call) override; - /// printState - Called by ProgramStateManager to print checker-specific data. - void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, - const char *Sep, - const LocationContext *LCtx = nullptr) override; + /// printJson - Called by ProgramStateManager to print checker-specific data. + void printJson(raw_ostream &Out, ProgramStateRef State, + const LocationContext *LCtx, const char *NL, + unsigned int Space, bool IsDot) const override; ProgramStateManager &getStateManager() override { return StateMgr; } @@ -387,9 +394,11 @@ public: return StateMgr.getBasicVals(); } - // FIXME: Remove when we migrate over to just using ValueManager. SymbolManager &getSymbolManager() { return SymMgr; } - const SymbolManager &getSymbolManager() const { return SymMgr; } + MemRegionManager &getRegionManager() { return MRMgr; } + + NoteTag::Factory &getNoteTags() { return Engine.getNoteTags(); } + // Functions for external checking of whether we have unfinished work bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); } @@ -707,6 +716,25 @@ private: AnalyzerOptions &Opts, const EvalCallOptions &CallOpts); + /// See if the given AnalysisDeclContext is built for a function that we + /// should always inline simply because it's small enough. + /// Apart from "small" functions, we also have "large" functions + /// (cf. isLarge()), some of which are huge (cf. isHuge()), and we classify + /// the remaining functions as "medium". + bool isSmall(AnalysisDeclContext *ADC) const; + + /// See if the given AnalysisDeclContext is built for a function that we + /// should inline carefully because it looks pretty large. + bool isLarge(AnalysisDeclContext *ADC) const; + + /// See if the given AnalysisDeclContext is built for a function that we + /// should never inline because it's legit gigantic. + bool isHuge(AnalysisDeclContext *ADC) const; + + /// See if the given AnalysisDeclContext is built for a function that we + /// should inline, just by looking at the declaration of the function. + bool mayInlineDecl(AnalysisDeclContext *ADC) const; + /// Checks our policies and decides weither the given call should be inlined. bool shouldInlineCall(const CallEvent &Call, const Decl *D, const ExplodedNode *Pred, diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h index b70faa10f0b2..53b4bf605871 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h @@ -1,9 +1,8 @@ //===- FunctionSummary.h - Stores summaries of functions. -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h index a4c505ce5f23..d25d26435454 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h @@ -1,9 +1,8 @@ //===--- LoopUnrolling.h - Unroll loops -------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h index f494c5d6dab8..7484a51b1eda 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h @@ -1,9 +1,8 @@ //===--- LoopWidening.h - Widen loops ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 3d0ff4efa1d7..071e35085a5f 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -1,9 +1,8 @@ //==- MemRegion.h - Abstract memory regions for static analysis -*- C++ -*--==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -774,9 +773,6 @@ class SymbolicRegion : public SubRegion { assert(s->getType()->isAnyPointerType() || s->getType()->isReferenceType() || s->getType()->isBlockPointerType()); - - // populateWorklistFromSymbol() relies on this assertion, and needs to be - // updated if more cases are introduced. assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg)); } @@ -912,7 +908,7 @@ protected: DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k), D(d) { assert(classof(this)); - assert(d); + assert(d && d->isCanonicalDecl()); } static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index c3a7028d8755..d38058f9af56 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -1,9 +1,8 @@ //== ProgramState.h - Path-sensitive "State" for tracking values -*- C++ -*--=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -21,7 +20,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ImmutableMap.h" #include "llvm/Support/Allocator.h" @@ -44,7 +42,6 @@ typedef std::unique_ptr<ConstraintManager>(*ConstraintManagerCreator)( ProgramStateManager &, SubEngine *); typedef std::unique_ptr<StoreManager>(*StoreManagerCreator)( ProgramStateManager &); -typedef llvm::ImmutableMap<const SubRegion*, TaintTagType> TaintedSubRegions; //===----------------------------------------------------------------------===// // ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState. @@ -368,38 +365,6 @@ public: template <typename CB> CB scanReachableSymbols(llvm::iterator_range<region_iterator> Reachable) const; - /// Create a new state in which the statement is marked as tainted. - LLVM_NODISCARD ProgramStateRef - addTaint(const Stmt *S, const LocationContext *LCtx, - TaintTagType Kind = TaintTagGeneric) const; - - /// Create a new state in which the value is marked as tainted. - LLVM_NODISCARD ProgramStateRef - addTaint(SVal V, TaintTagType Kind = TaintTagGeneric) const; - - /// Create a new state in which the symbol is marked as tainted. - LLVM_NODISCARD ProgramStateRef addTaint(SymbolRef S, - TaintTagType Kind = TaintTagGeneric) const; - - /// Create a new state in which the region symbol is marked as tainted. - LLVM_NODISCARD ProgramStateRef - addTaint(const MemRegion *R, TaintTagType Kind = TaintTagGeneric) const; - - /// Create a new state in a which a sub-region of a given symbol is tainted. - /// This might be necessary when referring to regions that can not have an - /// individual symbol, e.g. if they are represented by the default binding of - /// a LazyCompoundVal. - LLVM_NODISCARD ProgramStateRef - addPartialTaint(SymbolRef ParentSym, const SubRegion *SubRegion, - TaintTagType Kind = TaintTagGeneric) const; - - /// Check if the statement is tainted in the current state. - bool isTainted(const Stmt *S, const LocationContext *LCtx, - TaintTagType Kind = TaintTagGeneric) const; - bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const; - bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const; - bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const; - //==---------------------------------------------------------------------==// // Accessing the Generic Data Map (GDM). //==---------------------------------------------------------------------==// @@ -459,14 +424,14 @@ public: } // Pretty-printing. - void print(raw_ostream &Out, const char *nl = "\n", const char *sep = "", - const LocationContext *CurrentLC = nullptr) const; - void printDOT(raw_ostream &Out, - const LocationContext *CurrentLC = nullptr) const; - void printTaint(raw_ostream &Out, const char *nl = "\n") const; + void printJson(raw_ostream &Out, const LocationContext *LCtx = nullptr, + const char *NL = "\n", unsigned int Space = 0, + bool IsDot = false) const; + + void printDOT(raw_ostream &Out, const LocationContext *LCtx = nullptr, + unsigned int Space = 0) const; void dump() const; - void dumpTaint() const; private: friend void ProgramStateRetain(const ProgramState *state); @@ -500,7 +465,6 @@ private: std::unique_ptr<ConstraintManager> ConstraintMgr; ProgramState::GenericDataMap::Factory GDMFactory; - TaintedSubRegions::Factory TSRFactory; typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy; GDMContextsTy GDMContexts; @@ -589,11 +553,15 @@ public: ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState); - bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) { + bool haveEqualConstraints(ProgramStateRef S1, ProgramStateRef S2) const { + return ConstraintMgr->haveEqualConstraints(S1, S2); + } + + bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) const { return S1->Env == S2->Env; } - bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) { + bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) const { return S1->store == S2->store; } @@ -666,10 +634,6 @@ public: return ProgramStateTrait<T>::MakeContext(p); } - - void EndPath(ProgramStateRef St) { - ConstraintMgr->EndPath(St); - } }; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h index 64de736c7e9f..da82a55e3625 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h @@ -1,9 +1,8 @@ //ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- C++ -*- // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h index 415bb7713d4b..0ea26bf2e509 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h @@ -1,9 +1,8 @@ //== ProgramState_Fwd.h - Incomplete declarations of ProgramState -*- C++ -*--=/ // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h index 1b12a4edc205..a9ca3451d8f3 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h @@ -1,9 +1,8 @@ //== RangedConstraintManager.h ----------------------------------*- C++ -*--==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -114,7 +113,8 @@ private: public: RangeSet Intersect(BasicValueFactory &BV, Factory &F, llvm::APSInt Lower, llvm::APSInt Upper) const; - + RangeSet Intersect(BasicValueFactory &BV, Factory &F, + const RangeSet &Other) const; RangeSet Negate(BasicValueFactory &BV, Factory &F) const; void print(raw_ostream &os) const; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def b/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def index 10f89ecc55a5..3c52c2bc7142 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def @@ -1,9 +1,8 @@ //===-- Regions.def - Metadata about MemRegion kinds ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h index 8eaa9365be1d..1712501b13bd 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h @@ -1,9 +1,8 @@ //== SMTConstraintManager.h -------------------------------------*- C++ -*--==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -15,20 +14,24 @@ #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONSTRAINTMANAGER_H #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONSTRAINTMANAGER_H +#include "clang/Basic/JsonSupport.h" #include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h" +typedef llvm::ImmutableSet< + std::pair<clang::ento::SymbolRef, const llvm::SMTExpr *>> + ConstraintSMTType; +REGISTER_TRAIT_WITH_PROGRAMSTATE(ConstraintSMT, ConstraintSMTType) + namespace clang { namespace ento { -template <typename ConstraintSMT, typename SMTExprTy> class SMTConstraintManager : public clang::ento::SimpleConstraintManager { - SMTSolverRef &Solver; + mutable llvm::SMTSolverRef Solver = llvm::CreateZ3Solver(); public: - SMTConstraintManager(clang::ento::SubEngine *SE, clang::ento::SValBuilder &SB, - SMTSolverRef &S) - : SimpleConstraintManager(SE, SB), Solver(S) {} + SMTConstraintManager(clang::ento::SubEngine *SE, clang::ento::SValBuilder &SB) + : SimpleConstraintManager(SE, SB) {} virtual ~SMTConstraintManager() = default; //===------------------------------------------------------------------===// @@ -42,7 +45,8 @@ public: QualType RetTy; bool hasComparison; - SMTExprRef Exp = SMTConv::getExpr(Solver, Ctx, Sym, &RetTy, &hasComparison); + llvm::SMTExprRef Exp = + SMTConv::getExpr(Solver, Ctx, Sym, &RetTy, &hasComparison); // Create zero comparison for implicit boolean cast, with reversed // assumption @@ -78,12 +82,12 @@ public: QualType RetTy; // The expression may be casted, so we cannot call getZ3DataExpr() directly - SMTExprRef VarExp = SMTConv::getExpr(Solver, Ctx, Sym, &RetTy); - SMTExprRef Exp = + llvm::SMTExprRef VarExp = SMTConv::getExpr(Solver, Ctx, Sym, &RetTy); + llvm::SMTExprRef Exp = SMTConv::getZeroExpr(Solver, Ctx, VarExp, RetTy, /*Assumption=*/true); // Negate the constraint - SMTExprRef NotExp = + llvm::SMTExprRef NotExp = SMTConv::getZeroExpr(Solver, Ctx, VarExp, RetTy, /*Assumption=*/false); ConditionTruthVal isSat = checkModel(State, Sym, Exp); @@ -116,7 +120,7 @@ public: // this method tries to get the interpretation (the actual value) from // the solver, which is currently not cached. - SMTExprRef Exp = + llvm::SMTExprRef Exp = SMTConv::fromData(Solver, SD->getSymbolID(), Ty, Ctx.getTypeSize(Ty)); Solver->reset(); @@ -132,7 +136,7 @@ public: return nullptr; // A value has been obtained, check if it is the only value - SMTExprRef NotExp = SMTConv::fromBinOp( + llvm::SMTExprRef NotExp = SMTConv::fromBinOp( Solver, Exp, BO_NE, Ty->isBooleanType() ? Solver->mkBoolean(Value.getBoolValue()) : Solver->mkBitvector(Value, Value.getBitWidth()), @@ -205,17 +209,37 @@ public: return State->set<ConstraintSMT>(CZ); } - void print(ProgramStateRef St, raw_ostream &OS, const char *nl, - const char *sep) override { + void printJson(raw_ostream &Out, ProgramStateRef State, const char *NL = "\n", + unsigned int Space = 0, bool IsDot = false) const override { + ConstraintSMTType Constraints = State->get<ConstraintSMT>(); - auto CZ = St->get<ConstraintSMT>(); + Indent(Out, Space, IsDot) << "\"constraints\": "; + if (Constraints.isEmpty()) { + Out << "null," << NL; + return; + } - OS << nl << sep << "Constraints:"; - for (auto I = CZ.begin(), E = CZ.end(); I != E; ++I) { - OS << nl << ' ' << I->first << " : "; - I->second.print(OS); + ++Space; + Out << '[' << NL; + for (ConstraintSMTType::iterator I = Constraints.begin(); + I != Constraints.end(); ++I) { + Indent(Out, Space, IsDot) + << "{ \"symbol\": \"" << I->first << "\", \"range\": \""; + I->second->print(Out); + Out << "\" }"; + + if (std::next(I) != Constraints.end()) + Out << ','; + Out << NL; } - OS << nl; + + --Space; + Indent(Out, Space, IsDot) << "],"; + } + + bool haveEqualConstraints(ProgramStateRef S1, + ProgramStateRef S2) const override { + return S1->get<ConstraintSMT>() == S2->get<ConstraintSMT>(); } bool canReasonAbout(SVal X) const override { @@ -270,11 +294,10 @@ public: protected: // Check whether a new model is satisfiable, and update the program state. virtual ProgramStateRef assumeExpr(ProgramStateRef State, SymbolRef Sym, - const SMTExprRef &Exp) { + const llvm::SMTExprRef &Exp) { // Check the model, avoid simplifying AST to save time if (checkModel(State, Sym, Exp).isConstrainedTrue()) - return State->add<ConstraintSMT>( - std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp))); + return State->add<ConstraintSMT>(std::make_pair(Sym, Exp)); return nullptr; } @@ -288,11 +311,11 @@ protected: // Construct the logical AND of all the constraints if (I != IE) { - std::vector<SMTExprRef> ASTs; + std::vector<llvm::SMTExprRef> ASTs; - SMTExprRef Constraint = Solver->newExprRef(I++->second); + llvm::SMTExprRef Constraint = I++->second; while (I != IE) { - Constraint = Solver->mkAnd(Constraint, Solver->newExprRef(I++->second)); + Constraint = Solver->mkAnd(Constraint, I++->second); } Solver->addConstraint(Constraint); @@ -301,9 +324,9 @@ protected: // Generate and check a Z3 model, using the given constraint. ConditionTruthVal checkModel(ProgramStateRef State, SymbolRef Sym, - const SMTExprRef &Exp) const { - ProgramStateRef NewState = State->add<ConstraintSMT>( - std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp))); + const llvm::SMTExprRef &Exp) const { + ProgramStateRef NewState = + State->add<ConstraintSMT>(std::make_pair(Sym, Exp)); llvm::FoldingSetNodeID ID; NewState->get<ConstraintSMT>().Profile(ID); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h index cdca2a09700d..bdebe238829e 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h @@ -1,9 +1,8 @@ //== SMTConv.h --------------------------------------------------*- C++ -*--==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -16,8 +15,8 @@ #include "clang/AST/Expr.h" #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" +#include "llvm/Support/SMTAPI.h" namespace clang { namespace ento { @@ -25,8 +24,8 @@ namespace ento { class SMTConv { public: // Returns an appropriate sort, given a QualType and it's bit width. - static inline SMTSortRef mkSort(SMTSolverRef &Solver, const QualType &Ty, - unsigned BitWidth) { + static inline llvm::SMTSortRef mkSort(llvm::SMTSolverRef &Solver, + const QualType &Ty, unsigned BitWidth) { if (Ty->isBooleanType()) return Solver->getBoolSort(); @@ -36,10 +35,10 @@ public: return Solver->getBitvectorSort(BitWidth); } - /// Constructs an SMTExprRef from an unary operator. - static inline SMTExprRef fromUnOp(SMTSolverRef &Solver, - const UnaryOperator::Opcode Op, - const SMTExprRef &Exp) { + /// Constructs an SMTSolverRef from an unary operator. + static inline llvm::SMTExprRef fromUnOp(llvm::SMTSolverRef &Solver, + const UnaryOperator::Opcode Op, + const llvm::SMTExprRef &Exp) { switch (Op) { case UO_Minus: return Solver->mkBVNeg(Exp); @@ -55,10 +54,10 @@ public: llvm_unreachable("Unimplemented opcode"); } - /// Constructs an SMTExprRef from a floating-point unary operator. - static inline SMTExprRef fromFloatUnOp(SMTSolverRef &Solver, - const UnaryOperator::Opcode Op, - const SMTExprRef &Exp) { + /// Constructs an SMTSolverRef from a floating-point unary operator. + static inline llvm::SMTExprRef fromFloatUnOp(llvm::SMTSolverRef &Solver, + const UnaryOperator::Opcode Op, + const llvm::SMTExprRef &Exp) { switch (Op) { case UO_Minus: return Solver->mkFPNeg(Exp); @@ -71,27 +70,28 @@ public: llvm_unreachable("Unimplemented opcode"); } - /// Construct an SMTExprRef from a n-ary binary operator. - static inline SMTExprRef fromNBinOp(SMTSolverRef &Solver, - const BinaryOperator::Opcode Op, - const std::vector<SMTExprRef> &ASTs) { + /// Construct an SMTSolverRef from a n-ary binary operator. + static inline llvm::SMTExprRef + fromNBinOp(llvm::SMTSolverRef &Solver, const BinaryOperator::Opcode Op, + const std::vector<llvm::SMTExprRef> &ASTs) { assert(!ASTs.empty()); if (Op != BO_LAnd && Op != BO_LOr) llvm_unreachable("Unimplemented opcode"); - SMTExprRef res = ASTs.front(); + llvm::SMTExprRef res = ASTs.front(); for (std::size_t i = 1; i < ASTs.size(); ++i) res = (Op == BO_LAnd) ? Solver->mkAnd(res, ASTs[i]) : Solver->mkOr(res, ASTs[i]); return res; } - /// Construct an SMTExprRef from a binary operator. - static inline SMTExprRef fromBinOp(SMTSolverRef &Solver, - const SMTExprRef &LHS, - const BinaryOperator::Opcode Op, - const SMTExprRef &RHS, bool isSigned) { + /// Construct an SMTSolverRef from a binary operator. + static inline llvm::SMTExprRef fromBinOp(llvm::SMTSolverRef &Solver, + const llvm::SMTExprRef &LHS, + const BinaryOperator::Opcode Op, + const llvm::SMTExprRef &RHS, + bool isSigned) { assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) && "AST's must have the same sort!"); @@ -163,9 +163,10 @@ public: llvm_unreachable("Unimplemented opcode"); } - /// Construct an SMTExprRef from a special floating-point binary operator. - static inline SMTExprRef - fromFloatSpecialBinOp(SMTSolverRef &Solver, const SMTExprRef &LHS, + /// Construct an SMTSolverRef from a special floating-point binary + /// operator. + static inline llvm::SMTExprRef + fromFloatSpecialBinOp(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &LHS, const BinaryOperator::Opcode Op, const llvm::APFloat::fltCategory &RHS) { switch (Op) { @@ -196,11 +197,11 @@ public: llvm_unreachable("Unimplemented opcode"); } - /// Construct an SMTExprRef from a floating-point binary operator. - static inline SMTExprRef fromFloatBinOp(SMTSolverRef &Solver, - const SMTExprRef &LHS, - const BinaryOperator::Opcode Op, - const SMTExprRef &RHS) { + /// Construct an SMTSolverRef from a floating-point binary operator. + static inline llvm::SMTExprRef fromFloatBinOp(llvm::SMTSolverRef &Solver, + const llvm::SMTExprRef &LHS, + const BinaryOperator::Opcode Op, + const llvm::SMTExprRef &RHS) { assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) && "AST's must have the same sort!"); @@ -254,11 +255,13 @@ public: llvm_unreachable("Unimplemented opcode"); } - /// Construct an SMTExprRef from a QualType FromTy to a QualType ToTy, and - /// their bit widths. - static inline SMTExprRef fromCast(SMTSolverRef &Solver, const SMTExprRef &Exp, - QualType ToTy, uint64_t ToBitWidth, - QualType FromTy, uint64_t FromBitWidth) { + /// Construct an SMTSolverRef from a QualType FromTy to a QualType ToTy, + /// and their bit widths. + static inline llvm::SMTExprRef fromCast(llvm::SMTSolverRef &Solver, + const llvm::SMTExprRef &Exp, + QualType ToTy, uint64_t ToBitWidth, + QualType FromTy, + uint64_t FromBitWidth) { if ((FromTy->isIntegralOrEnumerationType() && ToTy->isIntegralOrEnumerationType()) || (FromTy->isAnyPointerType() ^ ToTy->isAnyPointerType()) || @@ -292,7 +295,7 @@ public: } if (FromTy->isIntegralOrEnumerationType() && ToTy->isRealFloatingType()) { - SMTSortRef Sort = Solver->getFloatSort(ToBitWidth); + llvm::SMTSortRef Sort = Solver->getFloatSort(ToBitWidth); return FromTy->isSignedIntegerOrEnumerationType() ? Solver->mkSBVtoFP(Exp, Sort) : Solver->mkUBVtoFP(Exp, Sort); @@ -307,7 +310,7 @@ public: } // Callback function for doCast parameter on APSInt type. - static inline llvm::APSInt castAPSInt(SMTSolverRef &Solver, + static inline llvm::APSInt castAPSInt(llvm::SMTSolverRef &Solver, const llvm::APSInt &V, QualType ToTy, uint64_t ToWidth, QualType FromTy, uint64_t FromWidth) { @@ -315,30 +318,32 @@ public: return TargetType.convert(V); } - /// Construct an SMTExprRef from a SymbolData. - static inline SMTExprRef fromData(SMTSolverRef &Solver, const SymbolID ID, - const QualType &Ty, uint64_t BitWidth) { + /// Construct an SMTSolverRef from a SymbolData. + static inline llvm::SMTExprRef fromData(llvm::SMTSolverRef &Solver, + const SymbolID ID, const QualType &Ty, + uint64_t BitWidth) { llvm::Twine Name = "$" + llvm::Twine(ID); return Solver->mkSymbol(Name.str().c_str(), mkSort(Solver, Ty, BitWidth)); } - // Wrapper to generate SMTExprRef from SymbolCast data. - static inline SMTExprRef getCastExpr(SMTSolverRef &Solver, ASTContext &Ctx, - const SMTExprRef &Exp, QualType FromTy, - QualType ToTy) { + // Wrapper to generate SMTSolverRef from SymbolCast data. + static inline llvm::SMTExprRef getCastExpr(llvm::SMTSolverRef &Solver, + ASTContext &Ctx, + const llvm::SMTExprRef &Exp, + QualType FromTy, QualType ToTy) { return fromCast(Solver, Exp, ToTy, Ctx.getTypeSize(ToTy), FromTy, Ctx.getTypeSize(FromTy)); } - // Wrapper to generate SMTExprRef from unpacked binary symbolic expression. - // Sets the RetTy parameter. See getSMTExprRef(). - static inline SMTExprRef getBinExpr(SMTSolverRef &Solver, ASTContext &Ctx, - const SMTExprRef &LHS, QualType LTy, - BinaryOperator::Opcode Op, - const SMTExprRef &RHS, QualType RTy, - QualType *RetTy) { - SMTExprRef NewLHS = LHS; - SMTExprRef NewRHS = RHS; + // Wrapper to generate SMTSolverRef from unpacked binary symbolic + // expression. Sets the RetTy parameter. See getSMTSolverRef(). + static inline llvm::SMTExprRef + getBinExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, + const llvm::SMTExprRef &LHS, QualType LTy, + BinaryOperator::Opcode Op, const llvm::SMTExprRef &RHS, + QualType RTy, QualType *RetTy) { + llvm::SMTExprRef NewLHS = LHS; + llvm::SMTExprRef NewRHS = RHS; doTypeConversion(Solver, Ctx, NewLHS, NewRHS, LTy, RTy); // Update the return type parameter if the output type has changed. @@ -366,36 +371,40 @@ public: LTy->isSignedIntegerOrEnumerationType()); } - // Wrapper to generate SMTExprRef from BinarySymExpr. - // Sets the hasComparison and RetTy parameters. See getSMTExprRef(). - static inline SMTExprRef getSymBinExpr(SMTSolverRef &Solver, ASTContext &Ctx, - const BinarySymExpr *BSE, - bool *hasComparison, QualType *RetTy) { + // Wrapper to generate SMTSolverRef from BinarySymExpr. + // Sets the hasComparison and RetTy parameters. See getSMTSolverRef(). + static inline llvm::SMTExprRef getSymBinExpr(llvm::SMTSolverRef &Solver, + ASTContext &Ctx, + const BinarySymExpr *BSE, + bool *hasComparison, + QualType *RetTy) { QualType LTy, RTy; BinaryOperator::Opcode Op = BSE->getOpcode(); if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) { - SMTExprRef LHS = + llvm::SMTExprRef LHS = getSymExpr(Solver, Ctx, SIE->getLHS(), <y, hasComparison); llvm::APSInt NewRInt; std::tie(NewRInt, RTy) = fixAPSInt(Ctx, SIE->getRHS()); - SMTExprRef RHS = Solver->mkBitvector(NewRInt, NewRInt.getBitWidth()); + llvm::SMTExprRef RHS = + Solver->mkBitvector(NewRInt, NewRInt.getBitWidth()); return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy); } if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) { llvm::APSInt NewLInt; std::tie(NewLInt, LTy) = fixAPSInt(Ctx, ISE->getLHS()); - SMTExprRef LHS = Solver->mkBitvector(NewLInt, NewLInt.getBitWidth()); - SMTExprRef RHS = + llvm::SMTExprRef LHS = + Solver->mkBitvector(NewLInt, NewLInt.getBitWidth()); + llvm::SMTExprRef RHS = getSymExpr(Solver, Ctx, ISE->getRHS(), &RTy, hasComparison); return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy); } if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) { - SMTExprRef LHS = + llvm::SMTExprRef LHS = getSymExpr(Solver, Ctx, SSM->getLHS(), <y, hasComparison); - SMTExprRef RHS = + llvm::SMTExprRef RHS = getSymExpr(Solver, Ctx, SSM->getRHS(), &RTy, hasComparison); return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy); } @@ -405,9 +414,10 @@ public: // Recursive implementation to unpack and generate symbolic expression. // Sets the hasComparison and RetTy parameters. See getExpr(). - static inline SMTExprRef getSymExpr(SMTSolverRef &Solver, ASTContext &Ctx, - SymbolRef Sym, QualType *RetTy, - bool *hasComparison) { + static inline llvm::SMTExprRef getSymExpr(llvm::SMTSolverRef &Solver, + ASTContext &Ctx, SymbolRef Sym, + QualType *RetTy, + bool *hasComparison) { if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) { if (RetTy) *RetTy = Sym->getType(); @@ -421,7 +431,7 @@ public: *RetTy = Sym->getType(); QualType FromTy; - SMTExprRef Exp = + llvm::SMTExprRef Exp = getSymExpr(Solver, Ctx, SC->getOperand(), &FromTy, hasComparison); // Casting an expression with a comparison invalidates it. Note that this @@ -433,7 +443,8 @@ public: } if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) { - SMTExprRef Exp = getSymBinExpr(Solver, Ctx, BSE, hasComparison, RetTy); + llvm::SMTExprRef Exp = + getSymBinExpr(Solver, Ctx, BSE, hasComparison, RetTy); // Set the hasComparison parameter, in post-order traversal order. if (hasComparison) *hasComparison = BinaryOperator::isComparisonOp(BSE->getOpcode()); @@ -443,13 +454,14 @@ public: llvm_unreachable("Unsupported SymbolRef type!"); } - // Generate an SMTExprRef that represents the given symbolic expression. + // Generate an SMTSolverRef that represents the given symbolic expression. // Sets the hasComparison parameter if the expression has a comparison // operator. Sets the RetTy parameter to the final return type after // promotions and casts. - static inline SMTExprRef getExpr(SMTSolverRef &Solver, ASTContext &Ctx, - SymbolRef Sym, QualType *RetTy = nullptr, - bool *hasComparison = nullptr) { + static inline llvm::SMTExprRef getExpr(llvm::SMTSolverRef &Solver, + ASTContext &Ctx, SymbolRef Sym, + QualType *RetTy = nullptr, + bool *hasComparison = nullptr) { if (hasComparison) { *hasComparison = false; } @@ -457,11 +469,11 @@ public: return getSymExpr(Solver, Ctx, Sym, RetTy, hasComparison); } - // Generate an SMTExprRef that compares the expression to zero. - static inline SMTExprRef getZeroExpr(SMTSolverRef &Solver, ASTContext &Ctx, - const SMTExprRef &Exp, QualType Ty, - bool Assumption) { - + // Generate an SMTSolverRef that compares the expression to zero. + static inline llvm::SMTExprRef getZeroExpr(llvm::SMTSolverRef &Solver, + ASTContext &Ctx, + const llvm::SMTExprRef &Exp, + QualType Ty, bool Assumption) { if (Ty->isRealFloatingType()) { llvm::APFloat Zero = llvm::APFloat::getZero(Ctx.getFloatTypeSemantics(Ty)); @@ -486,21 +498,21 @@ public: llvm_unreachable("Unsupported type for zero value!"); } - // Wrapper to generate SMTExprRef from a range. If From == To, an equality - // will be created instead. - static inline SMTExprRef getRangeExpr(SMTSolverRef &Solver, ASTContext &Ctx, - SymbolRef Sym, const llvm::APSInt &From, - const llvm::APSInt &To, bool InRange) { + // Wrapper to generate SMTSolverRef from a range. If From == To, an + // equality will be created instead. + static inline llvm::SMTExprRef + getRangeExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, + const llvm::APSInt &From, const llvm::APSInt &To, bool InRange) { // Convert lower bound QualType FromTy; llvm::APSInt NewFromInt; std::tie(NewFromInt, FromTy) = fixAPSInt(Ctx, From); - SMTExprRef FromExp = + llvm::SMTExprRef FromExp = Solver->mkBitvector(NewFromInt, NewFromInt.getBitWidth()); // Convert symbol QualType SymTy; - SMTExprRef Exp = getExpr(Solver, Ctx, Sym, &SymTy); + llvm::SMTExprRef Exp = getExpr(Solver, Ctx, Sym, &SymTy); // Construct single (in)equality if (From == To) @@ -510,16 +522,17 @@ public: QualType ToTy; llvm::APSInt NewToInt; std::tie(NewToInt, ToTy) = fixAPSInt(Ctx, To); - SMTExprRef ToExp = Solver->mkBitvector(NewToInt, NewToInt.getBitWidth()); + llvm::SMTExprRef ToExp = + Solver->mkBitvector(NewToInt, NewToInt.getBitWidth()); assert(FromTy == ToTy && "Range values have different types!"); // Construct two (in)equalities, and a logical and/or - SMTExprRef LHS = + llvm::SMTExprRef LHS = getBinExpr(Solver, Ctx, Exp, SymTy, InRange ? BO_GE : BO_LT, FromExp, FromTy, /*RetTy=*/nullptr); - SMTExprRef RHS = getBinExpr(Solver, Ctx, Exp, SymTy, - InRange ? BO_LE : BO_GT, ToExp, ToTy, - /*RetTy=*/nullptr); + llvm::SMTExprRef RHS = getBinExpr(Solver, Ctx, Exp, SymTy, + InRange ? BO_LE : BO_GT, ToExp, ToTy, + /*RetTy=*/nullptr); return fromBinOp(Solver, LHS, InRange ? BO_LAnd : BO_LOr, RHS, SymTy->isSignedIntegerOrEnumerationType()); @@ -551,23 +564,24 @@ public: // Perform implicit type conversion on binary symbolic expressions. // May modify all input parameters. // TODO: Refactor to use built-in conversion functions - static inline void doTypeConversion(SMTSolverRef &Solver, ASTContext &Ctx, - SMTExprRef &LHS, SMTExprRef &RHS, - QualType <y, QualType &RTy) { + static inline void doTypeConversion(llvm::SMTSolverRef &Solver, + ASTContext &Ctx, llvm::SMTExprRef &LHS, + llvm::SMTExprRef &RHS, QualType <y, + QualType &RTy) { assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!"); // Perform type conversion if ((LTy->isIntegralOrEnumerationType() && RTy->isIntegralOrEnumerationType()) && (LTy->isArithmeticType() && RTy->isArithmeticType())) { - SMTConv::doIntTypeConversion<SMTExprRef, &fromCast>(Solver, Ctx, LHS, LTy, - RHS, RTy); + SMTConv::doIntTypeConversion<llvm::SMTExprRef, &fromCast>( + Solver, Ctx, LHS, LTy, RHS, RTy); return; } if (LTy->isRealFloatingType() || RTy->isRealFloatingType()) { - SMTConv::doFloatTypeConversion<SMTExprRef, &fromCast>(Solver, Ctx, LHS, - LTy, RHS, RTy); + SMTConv::doFloatTypeConversion<llvm::SMTExprRef, &fromCast>( + Solver, Ctx, LHS, LTy, RHS, RTy); return; } @@ -625,12 +639,11 @@ public: // Perform implicit integer type conversion. // May modify all input parameters. // TODO: Refactor to use Sema::handleIntegerConversion() - template <typename T, T (*doCast)(SMTSolverRef &Solver, const T &, QualType, - uint64_t, QualType, uint64_t)> - static inline void doIntTypeConversion(SMTSolverRef &Solver, ASTContext &Ctx, - T &LHS, QualType <y, T &RHS, - QualType &RTy) { - + template <typename T, T (*doCast)(llvm::SMTSolverRef &Solver, const T &, + QualType, uint64_t, QualType, uint64_t)> + static inline void doIntTypeConversion(llvm::SMTSolverRef &Solver, + ASTContext &Ctx, T &LHS, QualType <y, + T &RHS, QualType &RTy) { uint64_t LBitWidth = Ctx.getTypeSize(LTy); uint64_t RBitWidth = Ctx.getTypeSize(RTy); @@ -708,12 +721,11 @@ public: // Perform implicit floating-point type conversion. // May modify all input parameters. // TODO: Refactor to use Sema::handleFloatConversion() - template <typename T, T (*doCast)(SMTSolverRef &Solver, const T &, QualType, - uint64_t, QualType, uint64_t)> + template <typename T, T (*doCast)(llvm::SMTSolverRef &Solver, const T &, + QualType, uint64_t, QualType, uint64_t)> static inline void - doFloatTypeConversion(SMTSolverRef &Solver, ASTContext &Ctx, T &LHS, + doFloatTypeConversion(llvm::SMTSolverRef &Solver, ASTContext &Ctx, T &LHS, QualType <y, T &RHS, QualType &RTy) { - uint64_t LBitWidth = Ctx.getTypeSize(LTy); uint64_t RBitWidth = Ctx.getTypeSize(RTy); @@ -750,4 +762,4 @@ public: } // namespace ento } // namespace clang -#endif
\ No newline at end of file +#endif diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h deleted file mode 100644 index 9dedf96cfaf8..000000000000 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h +++ /dev/null @@ -1,62 +0,0 @@ -//== SMTExpr.h --------------------------------------------------*- C++ -*--==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a SMT generic Expr API, which will be the base class -// for every SMT solver expr specific class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTEXPR_H -#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTEXPR_H - -#include "clang/Basic/TargetInfo.h" -#include "llvm/ADT/FoldingSet.h" - -namespace clang { -namespace ento { - -/// Generic base class for SMT exprs -class SMTExpr { -public: - SMTExpr() = default; - virtual ~SMTExpr() = default; - - bool operator<(const SMTExpr &Other) const { - llvm::FoldingSetNodeID ID1, ID2; - Profile(ID1); - Other.Profile(ID2); - return ID1 < ID2; - } - - virtual void Profile(llvm::FoldingSetNodeID &ID) const { - static int Tag = 0; - ID.AddPointer(&Tag); - } - - friend bool operator==(SMTExpr const &LHS, SMTExpr const &RHS) { - return LHS.equal_to(RHS); - } - - virtual void print(raw_ostream &OS) const = 0; - - LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); } - -protected: - /// Query the SMT solver and returns true if two sorts are equal (same kind - /// and bit width). This does not check if the two sorts are the same objects. - virtual bool equal_to(SMTExpr const &other) const = 0; -}; - -/// Shared pointer for SMTExprs, used by SMTSolver API. -using SMTExprRef = std::shared_ptr<SMTExpr>; - -} // namespace ento -} // namespace clang - -#endif diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h deleted file mode 100644 index 2abe5fc98744..000000000000 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h +++ /dev/null @@ -1,303 +0,0 @@ -//== SMTSolver.h ------------------------------------------------*- C++ -*--==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a SMT generic Solver API, which will be the base class -// for every SMT solver specific class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSOLVER_H -#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSOLVER_H - -#include "clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h" -#include "llvm/ADT/APSInt.h" - -namespace clang { -namespace ento { - -/// Generic base class for SMT Solvers -/// -/// This class is responsible for wrapping all sorts and expression generation, -/// through the mk* methods. It also provides methods to create SMT expressions -/// straight from clang's AST, through the from* methods. -class SMTSolver { -public: - SMTSolver() = default; - virtual ~SMTSolver() = default; - - LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); } - - // Returns an appropriate floating-point sort for the given bitwidth. - SMTSortRef getFloatSort(unsigned BitWidth) { - switch (BitWidth) { - case 16: - return getFloat16Sort(); - case 32: - return getFloat32Sort(); - case 64: - return getFloat64Sort(); - case 128: - return getFloat128Sort(); - default:; - } - llvm_unreachable("Unsupported floating-point bitwidth!"); - } - - // Returns a boolean sort. - virtual SMTSortRef getBoolSort() = 0; - - // Returns an appropriate bitvector sort for the given bitwidth. - virtual SMTSortRef getBitvectorSort(const unsigned BitWidth) = 0; - - // Returns a floating-point sort of width 16 - virtual SMTSortRef getFloat16Sort() = 0; - - // Returns a floating-point sort of width 32 - virtual SMTSortRef getFloat32Sort() = 0; - - // Returns a floating-point sort of width 64 - virtual SMTSortRef getFloat64Sort() = 0; - - // Returns a floating-point sort of width 128 - virtual SMTSortRef getFloat128Sort() = 0; - - // Returns an appropriate sort for the given AST. - virtual SMTSortRef getSort(const SMTExprRef &AST) = 0; - - // Returns a new SMTExprRef from an SMTExpr - virtual SMTExprRef newExprRef(const SMTExpr &E) const = 0; - - /// Given a constraint, adds it to the solver - virtual void addConstraint(const SMTExprRef &Exp) const = 0; - - /// Creates a bitvector addition operation - virtual SMTExprRef mkBVAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector subtraction operation - virtual SMTExprRef mkBVSub(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector multiplication operation - virtual SMTExprRef mkBVMul(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector signed modulus operation - virtual SMTExprRef mkBVSRem(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector unsigned modulus operation - virtual SMTExprRef mkBVURem(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector signed division operation - virtual SMTExprRef mkBVSDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector unsigned division operation - virtual SMTExprRef mkBVUDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector logical shift left operation - virtual SMTExprRef mkBVShl(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector arithmetic shift right operation - virtual SMTExprRef mkBVAshr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector logical shift right operation - virtual SMTExprRef mkBVLshr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector negation operation - virtual SMTExprRef mkBVNeg(const SMTExprRef &Exp) = 0; - - /// Creates a bitvector not operation - virtual SMTExprRef mkBVNot(const SMTExprRef &Exp) = 0; - - /// Creates a bitvector xor operation - virtual SMTExprRef mkBVXor(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector or operation - virtual SMTExprRef mkBVOr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector and operation - virtual SMTExprRef mkBVAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector unsigned less-than operation - virtual SMTExprRef mkBVUlt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector signed less-than operation - virtual SMTExprRef mkBVSlt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector unsigned greater-than operation - virtual SMTExprRef mkBVUgt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector signed greater-than operation - virtual SMTExprRef mkBVSgt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector unsigned less-equal-than operation - virtual SMTExprRef mkBVUle(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector signed less-equal-than operation - virtual SMTExprRef mkBVSle(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector unsigned greater-equal-than operation - virtual SMTExprRef mkBVUge(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a bitvector signed greater-equal-than operation - virtual SMTExprRef mkBVSge(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a boolean not operation - virtual SMTExprRef mkNot(const SMTExprRef &Exp) = 0; - - /// Creates a boolean equality operation - virtual SMTExprRef mkEqual(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a boolean and operation - virtual SMTExprRef mkAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a boolean or operation - virtual SMTExprRef mkOr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a boolean ite operation - virtual SMTExprRef mkIte(const SMTExprRef &Cond, const SMTExprRef &T, - const SMTExprRef &F) = 0; - - /// Creates a bitvector sign extension operation - virtual SMTExprRef mkBVSignExt(unsigned i, const SMTExprRef &Exp) = 0; - - /// Creates a bitvector zero extension operation - virtual SMTExprRef mkBVZeroExt(unsigned i, const SMTExprRef &Exp) = 0; - - /// Creates a bitvector extract operation - virtual SMTExprRef mkBVExtract(unsigned High, unsigned Low, - const SMTExprRef &Exp) = 0; - - /// Creates a bitvector concat operation - virtual SMTExprRef mkBVConcat(const SMTExprRef &LHS, - const SMTExprRef &RHS) = 0; - - /// Creates a floating-point negation operation - virtual SMTExprRef mkFPNeg(const SMTExprRef &Exp) = 0; - - /// Creates a floating-point isInfinite operation - virtual SMTExprRef mkFPIsInfinite(const SMTExprRef &Exp) = 0; - - /// Creates a floating-point isNaN operation - virtual SMTExprRef mkFPIsNaN(const SMTExprRef &Exp) = 0; - - /// Creates a floating-point isNormal operation - virtual SMTExprRef mkFPIsNormal(const SMTExprRef &Exp) = 0; - - /// Creates a floating-point isZero operation - virtual SMTExprRef mkFPIsZero(const SMTExprRef &Exp) = 0; - - /// Creates a floating-point multiplication operation - virtual SMTExprRef mkFPMul(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a floating-point division operation - virtual SMTExprRef mkFPDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a floating-point remainder operation - virtual SMTExprRef mkFPRem(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a floating-point addition operation - virtual SMTExprRef mkFPAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a floating-point subtraction operation - virtual SMTExprRef mkFPSub(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a floating-point less-than operation - virtual SMTExprRef mkFPLt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a floating-point greater-than operation - virtual SMTExprRef mkFPGt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a floating-point less-than-or-equal operation - virtual SMTExprRef mkFPLe(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a floating-point greater-than-or-equal operation - virtual SMTExprRef mkFPGe(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0; - - /// Creates a floating-point equality operation - virtual SMTExprRef mkFPEqual(const SMTExprRef &LHS, - const SMTExprRef &RHS) = 0; - - /// Creates a floating-point conversion from floatint-point to floating-point - /// operation - virtual SMTExprRef mkFPtoFP(const SMTExprRef &From, const SMTSortRef &To) = 0; - - /// Creates a floating-point conversion from signed bitvector to - /// floatint-point operation - virtual SMTExprRef mkSBVtoFP(const SMTExprRef &From, - const SMTSortRef &To) = 0; - - /// Creates a floating-point conversion from unsigned bitvector to - /// floatint-point operation - virtual SMTExprRef mkUBVtoFP(const SMTExprRef &From, - const SMTSortRef &To) = 0; - - /// Creates a floating-point conversion from floatint-point to signed - /// bitvector operation - virtual SMTExprRef mkFPtoSBV(const SMTExprRef &From, unsigned ToWidth) = 0; - - /// Creates a floating-point conversion from floatint-point to unsigned - /// bitvector operation - virtual SMTExprRef mkFPtoUBV(const SMTExprRef &From, unsigned ToWidth) = 0; - - /// Creates a new symbol, given a name and a sort - virtual SMTExprRef mkSymbol(const char *Name, SMTSortRef Sort) = 0; - - // Returns an appropriate floating-point rounding mode. - virtual SMTExprRef getFloatRoundingMode() = 0; - - // If the a model is available, returns the value of a given bitvector symbol - virtual llvm::APSInt getBitvector(const SMTExprRef &Exp, unsigned BitWidth, - bool isUnsigned) = 0; - - // If the a model is available, returns the value of a given boolean symbol - virtual bool getBoolean(const SMTExprRef &Exp) = 0; - - /// Constructs an SMTExprRef from a boolean. - virtual SMTExprRef mkBoolean(const bool b) = 0; - - /// Constructs an SMTExprRef from a finite APFloat. - virtual SMTExprRef mkFloat(const llvm::APFloat Float) = 0; - - /// Constructs an SMTExprRef from an APSInt and its bit width - virtual SMTExprRef mkBitvector(const llvm::APSInt Int, unsigned BitWidth) = 0; - - /// Given an expression, extract the value of this operand in the model. - virtual bool getInterpretation(const SMTExprRef &Exp, llvm::APSInt &Int) = 0; - - /// Given an expression extract the value of this operand in the model. - virtual bool getInterpretation(const SMTExprRef &Exp, - llvm::APFloat &Float) = 0; - - /// Check if the constraints are satisfiable - virtual Optional<bool> check() const = 0; - - /// Push the current solver state - virtual void push() = 0; - - /// Pop the previous solver state - virtual void pop(unsigned NumStates = 1) = 0; - - /// Reset the solver and remove all constraints. - virtual void reset() = 0; - - /// Checks if the solver supports floating-points. - virtual bool isFPSupported() = 0; - - virtual void print(raw_ostream &OS) const = 0; -}; - -/// Shared pointer for SMTSolvers. -using SMTSolverRef = std::shared_ptr<SMTSolver>; - -/// Convenience method to create and Z3Solver object -SMTSolverRef CreateZ3Solver(); - -} // namespace ento -} // namespace clang - -#endif diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h deleted file mode 100644 index 41ef573f0c71..000000000000 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h +++ /dev/null @@ -1,91 +0,0 @@ -//== SMTSort.h --------------------------------------------------*- C++ -*--==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a SMT generic Sort API, which will be the base class -// for every SMT solver sort specific class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSORT_H -#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSORT_H - -#include "clang/Basic/TargetInfo.h" - -namespace clang { -namespace ento { - -/// Generic base class for SMT sorts -class SMTSort { -public: - SMTSort() = default; - virtual ~SMTSort() = default; - - /// Returns true if the sort is a bitvector, calls isBitvectorSortImpl(). - virtual bool isBitvectorSort() const { return isBitvectorSortImpl(); } - - /// Returns true if the sort is a floating-point, calls isFloatSortImpl(). - virtual bool isFloatSort() const { return isFloatSortImpl(); } - - /// Returns true if the sort is a boolean, calls isBooleanSortImpl(). - virtual bool isBooleanSort() const { return isBooleanSortImpl(); } - - /// Returns the bitvector size, fails if the sort is not a bitvector - /// Calls getBitvectorSortSizeImpl(). - virtual unsigned getBitvectorSortSize() const { - assert(isBitvectorSort() && "Not a bitvector sort!"); - unsigned Size = getBitvectorSortSizeImpl(); - assert(Size && "Size is zero!"); - return Size; - }; - - /// Returns the floating-point size, fails if the sort is not a floating-point - /// Calls getFloatSortSizeImpl(). - virtual unsigned getFloatSortSize() const { - assert(isFloatSort() && "Not a floating-point sort!"); - unsigned Size = getFloatSortSizeImpl(); - assert(Size && "Size is zero!"); - return Size; - }; - - friend bool operator==(SMTSort const &LHS, SMTSort const &RHS) { - return LHS.equal_to(RHS); - } - - virtual void print(raw_ostream &OS) const = 0; - - LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); } - -protected: - /// Query the SMT solver and returns true if two sorts are equal (same kind - /// and bit width). This does not check if the two sorts are the same objects. - virtual bool equal_to(SMTSort const &other) const = 0; - - /// Query the SMT solver and checks if a sort is bitvector. - virtual bool isBitvectorSortImpl() const = 0; - - /// Query the SMT solver and checks if a sort is floating-point. - virtual bool isFloatSortImpl() const = 0; - - /// Query the SMT solver and checks if a sort is boolean. - virtual bool isBooleanSortImpl() const = 0; - - /// Query the SMT solver and returns the sort bit width. - virtual unsigned getBitvectorSortSizeImpl() const = 0; - - /// Query the SMT solver and returns the sort bit width. - virtual unsigned getFloatSortSizeImpl() const = 0; -}; - -/// Shared pointer for SMTSorts, used by SMTSolver API. -using SMTSortRef = std::shared_ptr<SMTSort>; - -} // namespace ento -} // namespace clang - -#endif diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index c9e284a1a3e8..35ebefdc00d6 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -1,9 +1,8 @@ // SValBuilder.h - Construction of SVals from evaluating expressions -*- C++ -*- // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h index f87fdce1561b..fc83e26183b3 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h @@ -1,9 +1,8 @@ //===--- SValVisitor.h - Visitor for SVal subclasses ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def index a0e309937892..eb05de6d9933 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def @@ -1,9 +1,8 @@ //===-- SVals.def - Metadata about SVal kinds -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index 0efe96f67f8e..1abe29782088 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -1,9 +1,8 @@ //===- SVals.h - Abstract Values for Static Analysis ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -191,6 +190,9 @@ public: const MemRegion *getAsRegion() const; + /// printJson - Pretty-prints in JSON format. + void printJson(raw_ostream &Out, bool AddQuotes) const; + void dumpToStream(raw_ostream &OS) const; void dump() const; @@ -304,7 +306,7 @@ public: static bool isCompoundType(QualType T) { return T->isArrayType() || T->isRecordType() || - T->isComplexType() || T->isVectorType(); + T->isAnyComplexType() || T->isVectorType(); } private: @@ -668,13 +670,4 @@ private: } // namespace clang -namespace llvm { - -template <typename T> struct isPodLike; -template <> struct isPodLike<clang::ento::SVal> { - static const bool value = true; -}; - -} // namespace llvm - #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h index d64b90e2d380..6bf5e94afdbb 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h @@ -1,9 +1,8 @@ //== SimpleConstraintManager.h ----------------------------------*- C++ -*--==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index f49f761c77eb..cbff29953944 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -1,9 +1,8 @@ //===- Store.h - Interface for maps from Locations to Values ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -254,7 +253,8 @@ public: virtual bool scanReachableSymbols(Store S, const MemRegion *R, ScanReachableSymbols &Visitor) = 0; - virtual void print(Store store, raw_ostream &Out, const char* nl) = 0; + virtual void printJson(raw_ostream &Out, Store S, const char *NL, + unsigned int Space, bool IsDot) const = 0; class BindingsHandler { public: diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h index 22259a239cf6..a2dd05cfdf4c 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h @@ -1,9 +1,8 @@ //===- StoreRef.h - Smart pointer for store objects -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h index d745b0f51ab0..7789b431c0a6 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h @@ -1,9 +1,8 @@ //== SubEngine.h - Interface of the subengine of CoreEngine --------*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -159,10 +158,10 @@ public: const CallEvent *Call, RegionAndSymbolInvalidationTraits &HTraits) = 0; - /// printState - Called by ProgramStateManager to print checker-specific data. - virtual void printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep, - const LocationContext *LCtx = nullptr) = 0; + /// printJson - Called by ProgramStateManager to print checker-specific data. + virtual void printJson(raw_ostream &Out, ProgramStateRef State, + const LocationContext *LCtx, const char *NL, + unsigned int Space, bool IsDot) const = 0; /// Called by CoreEngine when the analysis worklist is either empty or the // maximum number of analysis steps have been reached. diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h index 0a75eeb3ea53..1a56153da11e 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h @@ -1,9 +1,8 @@ //== SummaryManager.h - Generic handling of function summaries --*- C++ -*--==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h index 69b9858d3feb..abfcd1d80faa 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h @@ -1,9 +1,8 @@ //===- SymExpr.h - Management of Symbolic Values ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index d02a8abd1148..d212e23da6fc 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -1,9 +1,8 @@ //===- SymbolManager.h - Management of Symbolic Values ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def b/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def index 7d4d8fe0a55a..7163a16263ab 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def @@ -1,9 +1,8 @@ //===-- Symbols.def - Metadata about SymExpr kinds --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h deleted file mode 100644 index 8218fb1eeafe..000000000000 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h +++ /dev/null @@ -1,59 +0,0 @@ -//===- TaintManager.h - Managing taint --------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides APIs for adding, removing, querying symbol taint. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H -#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H - -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h" -#include "llvm/ADT/ImmutableMap.h" - -namespace clang { -namespace ento { - -/// The GDM component containing the tainted root symbols. We lazily infer the -/// taint of the dependent symbols. Currently, this is a map from a symbol to -/// tag kind. TODO: Should support multiple tag kinds. -// FIXME: This does not use the nice trait macros because it must be accessible -// from multiple translation units. -struct TaintMap {}; - -using TaintMapImpl = llvm::ImmutableMap<SymbolRef, TaintTagType>; - -template<> struct ProgramStateTrait<TaintMap> - : public ProgramStatePartialTrait<TaintMapImpl> { - static void *GDMIndex(); -}; - -/// The GDM component mapping derived symbols' parent symbols to their -/// underlying regions. This is used to efficiently check whether a symbol is -/// tainted when it represents a sub-region of a tainted symbol. -struct DerivedSymTaint {}; - -using DerivedSymTaintImpl = llvm::ImmutableMap<SymbolRef, TaintedSubRegions>; - -template<> struct ProgramStateTrait<DerivedSymTaint> - : public ProgramStatePartialTrait<DerivedSymTaintImpl> { - static void *GDMIndex(); -}; - -class TaintManager { - TaintManager() = default; -}; - -} // namespace ento -} // namespace clang - -#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h deleted file mode 100644 index 50c4b8194cff..000000000000 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h +++ /dev/null @@ -1,30 +0,0 @@ -//===- TaintTag.h - Path-sensitive "State" for tracking values --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Defines a set of taint tags. Several tags are used to differentiate kinds -// of taint. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H -#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H - -namespace clang { -namespace ento { - -/// The type of taint, which helps to differentiate between different types of -/// taint. -using TaintTagType = unsigned; - -static const TaintTagType TaintTagGeneric = 0; - -} // namespace ento -} // namespace clang - -#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h index ef3c2694b283..7beb7ddf5bce 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h @@ -1,9 +1,8 @@ //==- WorkList.h - Worklist class used by CoreEngine ---------------*- C++ -*-// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h index 59fbbc3ca80f..2d24e6a9586b 100644 --- a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h +++ b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h @@ -1,9 +1,8 @@ //===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h index 61709548aed1..52a534499002 100644 --- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h +++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h @@ -1,9 +1,8 @@ //===-- CheckerRegistration.h - Checker Registration Function ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 966234492fe0..bc258160ada4 100644 --- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -1,9 +1,8 @@ //===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -70,6 +69,7 @@ namespace clang { class AnalyzerOptions; class DiagnosticsEngine; +class LangOptions; namespace ento { @@ -81,73 +81,245 @@ namespace ento { /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker". class CheckerRegistry { public: - CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags); + CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags, + AnalyzerOptions &AnOpts, const LangOptions &LangOpts, + ArrayRef<std::function<void(CheckerRegistry &)>> + checkerRegistrationFns = {}); /// Initialization functions perform any necessary setup for a checker. /// They should include a call to CheckerManager::registerChecker. using InitializationFunction = void (*)(CheckerManager &); + using ShouldRegisterFunction = bool (*)(const LangOptions &); + + /// Specifies a command line option. It may either belong to a checker or a + /// package. + struct CmdLineOption { + StringRef OptionType; + StringRef OptionName; + StringRef DefaultValStr; + StringRef Description; + StringRef DevelopmentStatus; + bool IsHidden; + + CmdLineOption(StringRef OptionType, StringRef OptionName, + StringRef DefaultValStr, StringRef Description, + StringRef DevelopmentStatus, bool IsHidden) + : OptionType(OptionType), OptionName(OptionName), + DefaultValStr(DefaultValStr), Description(Description), + DevelopmentStatus(DevelopmentStatus), IsHidden(IsHidden) { + + assert((OptionType == "bool" || OptionType == "string" || + OptionType == "int") && + "Unknown command line option type!"); + + assert((OptionType != "bool" || + (DefaultValStr == "true" || DefaultValStr == "false")) && + "Invalid value for boolean command line option! Maybe incorrect " + "parameters to the addCheckerOption or addPackageOption method?"); + + int Tmp; + assert((OptionType != "int" || !DefaultValStr.getAsInteger(0, Tmp)) && + "Invalid value for integer command line option! Maybe incorrect " + "parameters to the addCheckerOption or addPackageOption method?"); + (void)Tmp; + + assert((DevelopmentStatus == "alpha" || DevelopmentStatus == "beta" || + DevelopmentStatus == "released") && + "Invalid development status!"); + } + }; + + using CmdLineOptionList = llvm::SmallVector<CmdLineOption, 0>; + + struct CheckerInfo; + using CheckerInfoList = std::vector<CheckerInfo>; + using CheckerInfoListRange = llvm::iterator_range<CheckerInfoList::iterator>; + using ConstCheckerInfoList = llvm::SmallVector<const CheckerInfo *, 0>; + using CheckerInfoSet = llvm::SetVector<const CheckerInfo *>; + + /// Specifies a checker. Note that this isn't what we call a checker object, + /// it merely contains everything required to create one. struct CheckerInfo { - InitializationFunction Initialize; + enum class StateFromCmdLine { + // This checker wasn't explicitly enabled or disabled. + State_Unspecified, + // This checker was explicitly disabled. + State_Disabled, + // This checker was explicitly enabled. + State_Enabled + }; + + InitializationFunction Initialize = nullptr; + ShouldRegisterFunction ShouldRegister = nullptr; StringRef FullName; StringRef Desc; StringRef DocumentationUri; + CmdLineOptionList CmdLineOptions; + bool IsHidden = false; + StateFromCmdLine State = StateFromCmdLine::State_Unspecified; + + ConstCheckerInfoList Dependencies; + + bool isEnabled(const LangOptions &LO) const { + return State == StateFromCmdLine::State_Enabled && ShouldRegister(LO); + } - CheckerInfo(InitializationFunction Fn, StringRef Name, StringRef Desc, - StringRef DocsUri) - : Initialize(Fn), FullName(Name), Desc(Desc), - DocumentationUri(DocsUri) {} + bool isDisabled(const LangOptions &LO) const { + return State == StateFromCmdLine::State_Disabled && ShouldRegister(LO); + } + + // Since each checker must have a different full name, we can identify + // CheckerInfo objects by them. + bool operator==(const CheckerInfo &Rhs) const { + return FullName == Rhs.FullName; + } + + CheckerInfo(InitializationFunction Fn, ShouldRegisterFunction sfn, + StringRef Name, StringRef Desc, StringRef DocsUri, + bool IsHidden) + : Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc), + DocumentationUri(DocsUri), IsHidden(IsHidden) {} + + // Used for lower_bound. + explicit CheckerInfo(StringRef FullName) : FullName(FullName) {} }; - using CheckerInfoList = std::vector<CheckerInfo>; - using CheckerInfoSet = llvm::SetVector<const CheckerRegistry::CheckerInfo *>; + using StateFromCmdLine = CheckerInfo::StateFromCmdLine; + + /// Specifies a package. Each package option is implicitly an option for all + /// checkers within the package. + struct PackageInfo { + StringRef FullName; + CmdLineOptionList CmdLineOptions; + + // Since each package must have a different full name, we can identify + // CheckerInfo objects by them. + bool operator==(const PackageInfo &Rhs) const { + return FullName == Rhs.FullName; + } + + explicit PackageInfo(StringRef FullName) : FullName(FullName) {} + }; + + using PackageInfoList = llvm::SmallVector<PackageInfo, 0>; private: - template <typename T> - static void initializeManager(CheckerManager &mgr) { + template <typename T> static void initializeManager(CheckerManager &mgr) { mgr.registerChecker<T>(); } + template <typename T> static bool returnTrue(const LangOptions &LO) { + return true; + } + public: /// Adds a checker to the registry. Use this non-templated overload when your /// checker requires custom initialization. - void addChecker(InitializationFunction Fn, StringRef FullName, StringRef Desc, - StringRef DocsUri); + void addChecker(InitializationFunction Fn, ShouldRegisterFunction sfn, + StringRef FullName, StringRef Desc, StringRef DocsUri, + bool IsHidden); /// Adds a checker to the registry. Use this templated overload when your /// checker does not require any custom initialization. template <class T> - void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri) { + void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri, + bool IsHidden = false) { // Avoid MSVC's Compiler Error C2276: // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx - addChecker(&CheckerRegistry::initializeManager<T>, FullName, Desc, DocsUri); + addChecker(&CheckerRegistry::initializeManager<T>, + &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri, + IsHidden); } + /// Makes the checker with the full name \p fullName depends on the checker + /// called \p dependency. + void addDependency(StringRef FullName, StringRef Dependency); + + /// Registers an option to a given checker. A checker option will always have + /// the following format: + /// CheckerFullName:OptionName=Value + /// And can be specified from the command line like this: + /// -analyzer-config CheckerFullName:OptionName=Value + /// + /// Options for unknown checkers, or unknown options for a given checker, or + /// invalid value types for that given option are reported as an error in + /// non-compatibility mode. + void addCheckerOption(StringRef OptionType, StringRef CheckerFullName, + StringRef OptionName, StringRef DefaultValStr, + StringRef Description, StringRef DevelopmentStatus, + bool IsHidden = false); + + /// Adds a package to the registry. + void addPackage(StringRef FullName); + + /// Registers an option to a given package. A package option will always have + /// the following format: + /// PackageFullName:OptionName=Value + /// And can be specified from the command line like this: + /// -analyzer-config PackageFullName:OptionName=Value + /// + /// Options for unknown packages, or unknown options for a given package, or + /// invalid value types for that given option are reported as an error in + /// non-compatibility mode. + void addPackageOption(StringRef OptionType, StringRef PackageFullName, + StringRef OptionName, StringRef DefaultValStr, + StringRef Description, StringRef DevelopmentStatus, + bool IsHidden = false); + + // FIXME: This *really* should be added to the frontend flag descriptions. /// Initializes a CheckerManager by calling the initialization functions for /// all checkers specified by the given CheckerOptInfo list. The order of this /// list is significant; later options can be used to reverse earlier ones. /// This can be used to exclude certain checkers in an included package. - void initializeManager(CheckerManager &mgr, - const AnalyzerOptions &Opts) const; + void initializeManager(CheckerManager &CheckerMgr) const; /// Check if every option corresponds to a specific checker or package. - void validateCheckerOptions(const AnalyzerOptions &opts) const; + void validateCheckerOptions() const; /// Prints the name and description of all checkers in this registry. /// This output is not intended to be machine-parseable. - void printHelp(raw_ostream &out, size_t maxNameChars = 30) const; - void printList(raw_ostream &out, const AnalyzerOptions &opts) const; + void printCheckerWithDescList(raw_ostream &Out, + size_t MaxNameChars = 30) const; + void printEnabledCheckerList(raw_ostream &Out) const; + void printCheckerOptionList(raw_ostream &Out) const; private: - CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts) const; + /// Collect all enabled checkers. The returned container preserves the order + /// of insertion, as dependencies have to be enabled before the checkers that + /// depend on them. + CheckerInfoSet getEnabledCheckers() const; + + /// Return an iterator range of mutable CheckerInfos \p CmdLineArg applies to. + /// For example, it'll return the checkers for the core package, if + /// \p CmdLineArg is "core". + CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg); + + CheckerInfoList Checkers; + PackageInfoList Packages; + /// Used for couting how many checkers belong to a certain package in the + /// \c Checkers field. For convenience purposes. + llvm::StringMap<size_t> PackageSizes; + + /// Contains all (Dependendent checker, Dependency) pairs. We need this, as + /// we'll resolve dependencies after all checkers were added first. + llvm::SmallVector<std::pair<StringRef, StringRef>, 0> Dependencies; + void resolveDependencies(); + + /// Contains all (FullName, CmdLineOption) pairs. Similarly to dependencies, + /// we only modify the actual CheckerInfo and PackageInfo objects once all + /// of them have been added. + llvm::SmallVector<std::pair<StringRef, CmdLineOption>, 0> PackageOptions; + llvm::SmallVector<std::pair<StringRef, CmdLineOption>, 0> CheckerOptions; + + void resolveCheckerAndPackageOptions(); - mutable CheckerInfoList Checkers; - mutable llvm::StringMap<size_t> Packages; DiagnosticsEngine &Diags; + AnalyzerOptions &AnOpts; + const LangOptions &LangOpts; }; } // namespace ento - } // namespace clang #endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h index 2e9d0502e6f3..878b65a1b143 100644 --- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -1,9 +1,8 @@ //===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -52,12 +51,20 @@ private: llvm::StringMap<Stmt *> &Bodies; }; -void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins, - DiagnosticsEngine &diags); +void printCheckerHelp(raw_ostream &OS, + ArrayRef<std::string> plugins, + AnalyzerOptions &opts, + DiagnosticsEngine &diags, + const LangOptions &LangOpts); void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins, - const AnalyzerOptions &opts, - DiagnosticsEngine &diags); + AnalyzerOptions &opts, + DiagnosticsEngine &diags, + const LangOptions &LangOpts); void printAnalyzerConfigList(raw_ostream &OS); +void printCheckerConfigList(raw_ostream &OS, ArrayRef<std::string> plugins, + AnalyzerOptions &opts, + DiagnosticsEngine &diags, + const LangOptions &LangOpts); } // end GR namespace diff --git a/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h b/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h index fa00ffd16553..5f9ae78dac63 100644 --- a/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h +++ b/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h @@ -1,9 +1,8 @@ //===-- ModelConsumer.h -----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Tooling/ASTDiff/ASTDiff.h b/include/clang/Tooling/ASTDiff/ASTDiff.h index dd11c91ac0dd..d6cbc09dcede 100644 --- a/include/clang/Tooling/ASTDiff/ASTDiff.h +++ b/include/clang/Tooling/ASTDiff/ASTDiff.h @@ -1,10 +1,9 @@ //===- ASTDiff.h - AST differencing API -----------------------*- C++ -*- -===// // // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/ASTDiff/ASTDiffInternal.h b/include/clang/Tooling/ASTDiff/ASTDiffInternal.h index a76ad37336a6..0c15b30cc69c 100644 --- a/include/clang/Tooling/ASTDiff/ASTDiffInternal.h +++ b/include/clang/Tooling/ASTDiff/ASTDiffInternal.h @@ -1,10 +1,9 @@ //===- ASTDiffInternal.h --------------------------------------*- C++ -*- -===// // // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/AllTUsExecution.h b/include/clang/Tooling/AllTUsExecution.h index 94bf01632fb4..e670f54234a6 100644 --- a/include/clang/Tooling/AllTUsExecution.h +++ b/include/clang/Tooling/AllTUsExecution.h @@ -1,9 +1,8 @@ //===--- AllTUsExecution.h - Execute actions on all TUs. -*- C++ --------*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/ArgumentsAdjusters.h b/include/clang/Tooling/ArgumentsAdjusters.h index 94ccf1f34e57..bf0886034324 100644 --- a/include/clang/Tooling/ArgumentsAdjusters.h +++ b/include/clang/Tooling/ArgumentsAdjusters.h @@ -1,9 +1,8 @@ //===- ArgumentsAdjusters.h - Command line arguments adjuster ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -61,6 +60,10 @@ ArgumentsAdjuster getInsertArgumentAdjuster( const char *Extra, ArgumentInsertPosition Pos = ArgumentInsertPosition::END); +/// Gets an argument adjuster which strips plugin related command line +/// arguments. +ArgumentsAdjuster getStripPluginsAdjuster(); + /// Gets an argument adjuster which adjusts the arguments in sequence /// with the \p First adjuster and then with the \p Second one. ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h index 7aaa712f9baf..a5bfeeeaf77f 100644 --- a/include/clang/Tooling/CommonOptionsParser.h +++ b/include/clang/Tooling/CommonOptionsParser.h @@ -1,9 +1,8 @@ //===- CommonOptionsParser.h - common options for clang tools -*- C++ -*-=====// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h index aa07cc30e5f5..dea046a2dc7c 100644 --- a/include/clang/Tooling/CompilationDatabase.h +++ b/include/clang/Tooling/CompilationDatabase.h @@ -1,9 +1,8 @@ //===- CompilationDatabase.h ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -60,9 +59,15 @@ struct CompileCommand { /// The output file associated with the command. std::string Output; + /// If this compile command was guessed rather than read from an authoritative + /// source, a short human-readable explanation. + /// e.g. "inferred from foo/bar.h". + std::string Heuristic; + friend bool operator==(const CompileCommand &LHS, const CompileCommand &RHS) { return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename && - LHS.CommandLine == RHS.CommandLine && LHS.Output == RHS.Output; + LHS.CommandLine == RHS.CommandLine && LHS.Output == RHS.Output && + LHS.Heuristic == RHS.Heuristic; } friend bool operator!=(const CompileCommand &LHS, const CompileCommand &RHS) { @@ -208,6 +213,12 @@ private: std::unique_ptr<CompilationDatabase> inferMissingCompileCommands(std::unique_ptr<CompilationDatabase>); +/// Returns a wrapped CompilationDatabase that will add -target and -mode flags +/// to commandline when they can be deduced from argv[0] of commandline returned +/// by underlying database. +std::unique_ptr<CompilationDatabase> +inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base); + } // namespace tooling } // namespace clang diff --git a/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/include/clang/Tooling/CompilationDatabasePluginRegistry.h index 748ddbcf9d8d..8c58ad926a40 100644 --- a/include/clang/Tooling/CompilationDatabasePluginRegistry.h +++ b/include/clang/Tooling/CompilationDatabasePluginRegistry.h @@ -1,9 +1,8 @@ //===- CompilationDatabasePluginRegistry.h ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Core/Diagnostic.h b/include/clang/Tooling/Core/Diagnostic.h index ddb40103e211..4e0feba6d7dc 100644 --- a/include/clang/Tooling/Core/Diagnostic.h +++ b/include/clang/Tooling/Core/Diagnostic.h @@ -1,9 +1,8 @@ //===--- Diagnostic.h - Framework for clang diagnostics tools --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -43,6 +42,9 @@ struct DiagnosticMessage { std::string Message; std::string FilePath; unsigned FileOffset; + + /// Fixes for this diagnostic, grouped by file path. + llvm::StringMap<Replacements> Fix; }; /// Represents the diagnostic with the level of severity and possible @@ -59,7 +61,6 @@ struct Diagnostic { StringRef BuildDirectory); Diagnostic(llvm::StringRef DiagnosticName, const DiagnosticMessage &Message, - const llvm::StringMap<Replacements> &Fix, const SmallVector<DiagnosticMessage, 1> &Notes, Level DiagLevel, llvm::StringRef BuildDirectory); @@ -69,9 +70,6 @@ struct Diagnostic { /// Message associated to the diagnostic. DiagnosticMessage Message; - /// Fixes to apply, grouped by file path. - llvm::StringMap<Replacements> Fix; - /// Potential notes about the diagnostic. SmallVector<DiagnosticMessage, 1> Notes; @@ -95,6 +93,10 @@ struct TranslationUnitDiagnostics { std::vector<Diagnostic> Diagnostics; }; +/// Get the first fix to apply for this diagnostic. +/// \returns nullptr if no fixes are attached to the diagnostic. +const llvm::StringMap<Replacements> *selectFirstFix(const Diagnostic& D); + } // end namespace tooling } // end namespace clang #endif // LLVM_CLANG_TOOLING_CORE_DIAGNOSTIC_H diff --git a/include/clang/Tooling/Core/Lookup.h b/include/clang/Tooling/Core/Lookup.h index bc2b4db383cf..02b561c14f29 100644 --- a/include/clang/Tooling/Core/Lookup.h +++ b/include/clang/Tooling/Core/Lookup.h @@ -1,9 +1,8 @@ //===--- Lookup.h - Framework for clang refactoring tools --*- C++ -*------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -15,6 +14,7 @@ #define LLVM_CLANG_TOOLING_CORE_LOOKUP_H #include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" #include <string> namespace clang { @@ -31,6 +31,7 @@ namespace tooling { /// This does not perform a full C++ lookup so ADL will not work. /// /// \param Use The nested name to be replaced. +/// \param UseLoc The location of name to be replaced. /// \param UseContext The context in which the nested name is contained. This /// will be used to minimize namespace qualifications. /// \param FromDecl The declaration to which the nested name points. @@ -38,6 +39,7 @@ namespace tooling { /// qualified including a leading "::". /// \returns The new name to be inserted in place of the current nested name. std::string replaceNestedName(const NestedNameSpecifier *Use, + SourceLocation UseLoc, const DeclContext *UseContext, const NamedDecl *FromDecl, StringRef ReplacementString); diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h index ba11ca4a7fee..09374c5b1c17 100644 --- a/include/clang/Tooling/Core/Replacement.h +++ b/include/clang/Tooling/Core/Replacement.h @@ -1,9 +1,8 @@ //===- Replacement.h - Framework for clang refactoring tools ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h new file mode 100644 index 000000000000..3ea261a30d0f --- /dev/null +++ b/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h @@ -0,0 +1,58 @@ +//===- DependencyScanningWorker.h - clang-scan-deps worker ===---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_WORKER_H +#define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_WORKER_H + +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/LLVM.h" +#include "clang/Frontend/PCHContainerOperations.h" +#include "clang/Tooling/CompilationDatabase.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include <string> + +namespace clang { +namespace tooling { +namespace dependencies { + +/// An individual dependency scanning worker that is able to run on its own +/// thread. +/// +/// The worker computes the dependencies for the input files by preprocessing +/// sources either using a fast mode where the source files are minimized, or +/// using the regular processing run. +class DependencyScanningWorker { +public: + DependencyScanningWorker(); + + /// Print out the dependency information into a string using the dependency + /// file format that is specified in the options (-MD is the default) and + /// return it. + /// + /// \returns A \c StringError with the diagnostic output if clang errors + /// occurred, dependency file contents otherwise. + llvm::Expected<std::string> getDependencyFile(const std::string &Input, + StringRef WorkingDirectory, + const CompilationDatabase &CDB); + +private: + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; + std::shared_ptr<PCHContainerOperations> PCHContainerOps; + + /// The file system that is used by each worker when scanning for + /// dependencies. This filesystem persists accross multiple compiler + /// invocations. + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> WorkerFS; +}; + +} // end namespace dependencies +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_WORKER_H diff --git a/include/clang/Tooling/DiagnosticsYaml.h b/include/clang/Tooling/DiagnosticsYaml.h index d869450529bc..366ee6f6703b 100644 --- a/include/clang/Tooling/DiagnosticsYaml.h +++ b/include/clang/Tooling/DiagnosticsYaml.h @@ -1,9 +1,8 @@ //===-- DiagnosticsYaml.h -- Serialiazation for Diagnosticss ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -32,6 +31,20 @@ template <> struct MappingTraits<clang::tooling::DiagnosticMessage> { Io.mapRequired("Message", M.Message); Io.mapOptional("FilePath", M.FilePath); Io.mapOptional("FileOffset", M.FileOffset); + std::vector<clang::tooling::Replacement> Fixes; + for (auto &Replacements : M.Fix) { + for (auto &Replacement : Replacements.second) + Fixes.push_back(Replacement); + } + Io.mapRequired("Replacements", Fixes); + for (auto &Fix : Fixes) { + llvm::Error Err = M.Fix[Fix.getFilePath()].add(Fix); + if (Err) { + // FIXME: Implement better conflict handling. + llvm::errs() << "Fix conflicts with existing fix: " + << llvm::toString(std::move(Err)) << "\n"; + } + } } }; @@ -44,12 +57,11 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> { : DiagLevel(clang::tooling::Diagnostic::Level::Warning) {} NormalizedDiagnostic(const IO &, const clang::tooling::Diagnostic &D) - : DiagnosticName(D.DiagnosticName), Message(D.Message), Fix(D.Fix), - Notes(D.Notes), DiagLevel(D.DiagLevel), - BuildDirectory(D.BuildDirectory) {} + : DiagnosticName(D.DiagnosticName), Message(D.Message), Notes(D.Notes), + DiagLevel(D.DiagLevel), BuildDirectory(D.BuildDirectory) {} clang::tooling::Diagnostic denormalize(const IO &) { - return clang::tooling::Diagnostic(DiagnosticName, Message, Fix, Notes, + return clang::tooling::Diagnostic(DiagnosticName, Message, Notes, DiagLevel, BuildDirectory); } @@ -65,28 +77,10 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> { MappingNormalization<NormalizedDiagnostic, clang::tooling::Diagnostic> Keys( Io, D); Io.mapRequired("DiagnosticName", Keys->DiagnosticName); - Io.mapRequired("Message", Keys->Message.Message); - Io.mapRequired("FileOffset", Keys->Message.FileOffset); - Io.mapRequired("FilePath", Keys->Message.FilePath); + Io.mapRequired("DiagnosticMessage", Keys->Message); Io.mapOptional("Notes", Keys->Notes); // FIXME: Export properly all the different fields. - - std::vector<clang::tooling::Replacement> Fixes; - for (auto &Replacements : Keys->Fix) { - for (auto &Replacement : Replacements.second) { - Fixes.push_back(Replacement); - } - } - Io.mapRequired("Replacements", Fixes); - for (auto &Fix : Fixes) { - llvm::Error Err = Keys->Fix[Fix.getFilePath()].add(Fix); - if (Err) { - // FIXME: Implement better conflict handling. - llvm::errs() << "Fix conflicts with existing fix: " - << llvm::toString(std::move(Err)) << "\n"; - } - } } }; diff --git a/include/clang/Tooling/Execution.h b/include/clang/Tooling/Execution.h index 6bf1cf391b75..74f0df5a5b91 100644 --- a/include/clang/Tooling/Execution.h +++ b/include/clang/Tooling/Execution.h @@ -1,9 +1,8 @@ //===--- Execution.h - Executing clang frontend actions -*- C++ ---------*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h index 11d12f3d30ce..6f5c8dab7b75 100644 --- a/include/clang/Tooling/FileMatchTrie.h +++ b/include/clang/Tooling/FileMatchTrie.h @@ -1,9 +1,8 @@ //===- FileMatchTrie.h ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/FixIt.h b/include/clang/Tooling/FixIt.h index b36f378d6361..5fce71f2d8f7 100644 --- a/include/clang/Tooling/FixIt.h +++ b/include/clang/Tooling/FixIt.h @@ -1,9 +1,8 @@ //===--- FixIt.h - FixIt Hint utilities -------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -27,25 +26,26 @@ namespace tooling { namespace fixit { namespace internal { -StringRef getText(SourceRange Range, const ASTContext &Context); +StringRef getText(CharSourceRange Range, const ASTContext &Context); -/// Returns the SourceRange of a SourceRange. This identity function is -/// used by the following template abstractions. -inline SourceRange getSourceRange(const SourceRange &Range) { return Range; } +/// Returns the token CharSourceRange corresponding to \p Range. +inline CharSourceRange getSourceRange(const SourceRange &Range) { + return CharSourceRange::getTokenRange(Range); +} -/// Returns the SourceRange of the token at Location \p Loc. -inline SourceRange getSourceRange(const SourceLocation &Loc) { - return SourceRange(Loc); +/// Returns the CharSourceRange of the token at Location \p Loc. +inline CharSourceRange getSourceRange(const SourceLocation &Loc) { + return CharSourceRange::getTokenRange(Loc, Loc); } -/// Returns the SourceRange of an given Node. \p Node is typically a +/// Returns the CharSourceRange of an given Node. \p Node is typically a /// 'Stmt', 'Expr' or a 'Decl'. -template <typename T> SourceRange getSourceRange(const T &Node) { - return Node.getSourceRange(); +template <typename T> CharSourceRange getSourceRange(const T &Node) { + return CharSourceRange::getTokenRange(Node.getSourceRange()); } } // end namespace internal -// Returns a textual representation of \p Node. +/// Returns a textual representation of \p Node. template <typename T> StringRef getText(const T &Node, const ASTContext &Context) { return internal::getText(internal::getSourceRange(Node), Context); diff --git a/include/clang/Tooling/Inclusions/HeaderIncludes.h b/include/clang/Tooling/Inclusions/HeaderIncludes.h index d99a3283168c..ec6f0ea45ffe 100644 --- a/include/clang/Tooling/Inclusions/HeaderIncludes.h +++ b/include/clang/Tooling/Inclusions/HeaderIncludes.h @@ -1,9 +1,8 @@ //===--- HeaderIncludes.h - Insert/Delete #includes for C++ code--*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Inclusions/IncludeStyle.h b/include/clang/Tooling/Inclusions/IncludeStyle.h index a093dff27728..a0f236e6fc46 100644 --- a/include/clang/Tooling/Inclusions/IncludeStyle.h +++ b/include/clang/Tooling/Inclusions/IncludeStyle.h @@ -1,9 +1,8 @@ //===--- IncludeStyle.h - Style of C++ #include directives -------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -68,7 +67,7 @@ struct IncludeStyle { /// used for ordering ``#includes``. /// /// `POSIX extended - /// <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_ + /// <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_ /// regular expressions are supported. /// /// These regular expressions are matched against the filename of an include @@ -80,7 +79,7 @@ struct IncludeStyle { /// If none of the regular expressions match, INT_MAX is assigned as /// category. The main header for a source file automatically gets category 0. /// so that it is generally kept at the beginning of the ``#includes`` - /// (http://llvm.org/docs/CodingStandards.html#include-style). However, you + /// (https://llvm.org/docs/CodingStandards.html#include-style). However, you /// can also assign negative priorities if you have certain headers that /// always need to be first. /// diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h index 882afc6d9ece..96582457c63d 100644 --- a/include/clang/Tooling/JSONCompilationDatabase.h +++ b/include/clang/Tooling/JSONCompilationDatabase.h @@ -1,9 +1,8 @@ //===- JSONCompilationDatabase.h --------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h index 64b018ea26c2..b82b09f0f92d 100644 --- a/include/clang/Tooling/Refactoring.h +++ b/include/clang/Tooling/Refactoring.h @@ -1,9 +1,8 @@ //===--- Refactoring.h - Framework for clang refactoring tools --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/Refactoring/ASTSelection.h b/include/clang/Tooling/Refactoring/ASTSelection.h index aa02a6899e8f..b87ed28b30ad 100644 --- a/include/clang/Tooling/Refactoring/ASTSelection.h +++ b/include/clang/Tooling/Refactoring/ASTSelection.h @@ -1,9 +1,8 @@ //===--- ASTSelection.h - Clang refactoring library -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/AtomicChange.h b/include/clang/Tooling/Refactoring/AtomicChange.h index bfe042fc53c5..32e4624fc8e7 100644 --- a/include/clang/Tooling/Refactoring/AtomicChange.h +++ b/include/clang/Tooling/Refactoring/AtomicChange.h @@ -1,9 +1,8 @@ //===--- AtomicChange.h - AtomicChange class --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/Refactoring/Extract/Extract.h b/include/clang/Tooling/Refactoring/Extract/Extract.h index 2fd76d252c62..930991328ca0 100644 --- a/include/clang/Tooling/Refactoring/Extract/Extract.h +++ b/include/clang/Tooling/Refactoring/Extract/Extract.h @@ -1,9 +1,8 @@ //===--- Extract.h - Clang refactoring library ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RangeSelector.h b/include/clang/Tooling/Refactoring/RangeSelector.h new file mode 100644 index 000000000000..b117e4d82ad4 --- /dev/null +++ b/include/clang/Tooling/Refactoring/RangeSelector.h @@ -0,0 +1,89 @@ +//===--- RangeSelector.h - Source-selection library ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Defines a combinator library supporting the definition of _selectors_, +/// which select source ranges based on (bound) AST nodes. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_ +#define LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_ + +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/Support/Error.h" +#include <functional> +#include <string> + +namespace clang { +namespace tooling { +using RangeSelector = std::function<Expected<CharSourceRange>( + const ast_matchers::MatchFinder::MatchResult &)>; + +inline RangeSelector charRange(CharSourceRange R) { + return [R](const ast_matchers::MatchFinder::MatchResult &) + -> Expected<CharSourceRange> { return R; }; +} + +/// Selects from the start of \p Begin and to the end of \p End. +RangeSelector range(RangeSelector Begin, RangeSelector End); + +/// Convenience version of \c range where end-points are bound nodes. +RangeSelector range(std::string BeginID, std::string EndID); + +/// Selects the (empty) range [B,B) when \p Selector selects the range [B,E). +RangeSelector before(RangeSelector Selector); + +/// Selects the the point immediately following \p Selector. That is, the +/// (empty) range [E,E), when \p Selector selects either +/// * the CharRange [B,E) or +/// * the TokenRange [B,E'] where the token at E' spans the range [E,E'). +RangeSelector after(RangeSelector Selector); + +/// Selects a node, including trailing semicolon (for non-expression +/// statements). \p ID is the node's binding in the match result. +RangeSelector node(std::string ID); + +/// Selects a node, including trailing semicolon (always). Useful for selecting +/// expression statements. \p ID is the node's binding in the match result. +RangeSelector statement(std::string ID); + +/// Given a \c MemberExpr, selects the member token. \p ID is the node's +/// binding in the match result. +RangeSelector member(std::string ID); + +/// Given a node with a "name", (like \c NamedDecl, \c DeclRefExpr or \c +/// CxxCtorInitializer) selects the name's token. Only selects the final +/// identifier of a qualified name, but not any qualifiers or template +/// arguments. For example, for `::foo::bar::baz` and `::foo::bar::baz<int>`, +/// it selects only `baz`. +/// +/// \param ID is the node's binding in the match result. +RangeSelector name(std::string ID); + +// Given a \c CallExpr (bound to \p ID), selects the arguments' source text (all +// source between the call's parentheses). +RangeSelector callArgs(std::string ID); + +// Given a \c CompoundStmt (bound to \p ID), selects the source of the +// statements (all source between the braces). +RangeSelector statements(std::string ID); + +// Given a \c InitListExpr (bound to \p ID), selects the range of the elements +// (all source between the braces). +RangeSelector initListElements(std::string ID); + +/// Selects the range from which `S` was expanded (possibly along with other +/// source), if `S` is an expansion, and `S` itself, otherwise. Corresponds to +/// `SourceManager::getExpansionRange`. +RangeSelector expansion(RangeSelector S); +} // namespace tooling +} // namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_ diff --git a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h index bd314f03cd3a..41a448f035a4 100644 --- a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h +++ b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h @@ -1,9 +1,8 @@ //===--- RecursiveSymbolVisitor.h - Clang refactoring library -------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Tooling/Refactoring/RefactoringAction.h b/include/clang/Tooling/Refactoring/RefactoringAction.h index c4080237f1c3..d4294ddb2f66 100644 --- a/include/clang/Tooling/Refactoring/RefactoringAction.h +++ b/include/clang/Tooling/Refactoring/RefactoringAction.h @@ -1,9 +1,8 @@ //===--- RefactoringAction.h - Clang refactoring library ------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRule.h b/include/clang/Tooling/Refactoring/RefactoringActionRule.h index ce4a91cbbadc..0c6e38af381f 100644 --- a/include/clang/Tooling/Refactoring/RefactoringActionRule.h +++ b/include/clang/Tooling/Refactoring/RefactoringActionRule.h @@ -1,9 +1,8 @@ //===--- RefactoringActionRule.h - Clang refactoring library -------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h b/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h index 355a6a55f22f..6a6dd83731e9 100644 --- a/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h +++ b/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h @@ -1,9 +1,8 @@ //===--- RefactoringActionRuleRequirements.h - Clang refactoring library --===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRules.h b/include/clang/Tooling/Refactoring/RefactoringActionRules.h index 33206d9a5dd1..e9606fd6018e 100644 --- a/include/clang/Tooling/Refactoring/RefactoringActionRules.h +++ b/include/clang/Tooling/Refactoring/RefactoringActionRules.h @@ -1,9 +1,8 @@ //===--- RefactoringActionRules.h - Clang refactoring library -------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h b/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h index 75b6c8f70d17..cc6ae83202f1 100644 --- a/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h +++ b/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h @@ -1,9 +1,8 @@ //===--- RefactoringActionRulesInternal.h - Clang refactoring library -----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h b/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h index dc1d998396db..967e7b5860ff 100644 --- a/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h +++ b/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h @@ -1,9 +1,8 @@ //===--- RefactoringDiagnostic.h - ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringOption.h b/include/clang/Tooling/Refactoring/RefactoringOption.h index 5011223cce69..659e02b48e5c 100644 --- a/include/clang/Tooling/Refactoring/RefactoringOption.h +++ b/include/clang/Tooling/Refactoring/RefactoringOption.h @@ -1,9 +1,8 @@ //===--- RefactoringOption.h - Clang refactoring library ------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h b/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h index aea8fa549392..d58b11355a26 100644 --- a/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h +++ b/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h @@ -1,9 +1,8 @@ //===--- RefactoringOptionVisitor.h - Clang refactoring library -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringOptions.h b/include/clang/Tooling/Refactoring/RefactoringOptions.h index e45c0a09fd67..f25f526e146c 100644 --- a/include/clang/Tooling/Refactoring/RefactoringOptions.h +++ b/include/clang/Tooling/Refactoring/RefactoringOptions.h @@ -1,9 +1,8 @@ //===--- RefactoringOptions.h - Clang refactoring library -----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h b/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h index 005eb877bf0f..2035c02bc17a 100644 --- a/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h +++ b/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h @@ -1,9 +1,8 @@ //===--- RefactoringResultConsumer.h - Clang refactoring library ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/RefactoringRuleContext.h b/include/clang/Tooling/Refactoring/RefactoringRuleContext.h index 882ab824b639..5271a54075ea 100644 --- a/include/clang/Tooling/Refactoring/RefactoringRuleContext.h +++ b/include/clang/Tooling/Refactoring/RefactoringRuleContext.h @@ -1,9 +1,8 @@ //===--- RefactoringRuleContext.h - Clang refactoring library -------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h index 5771a1c2d132..b04bc3e2d202 100644 --- a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h +++ b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h @@ -1,9 +1,8 @@ //===--- RenamingAction.h - Clang refactoring library ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -55,6 +54,8 @@ public: static const RefactoringDescriptor &describe(); + const NamedDecl *getRenameDecl() const; + private: RenameOccurrences(const NamedDecl *ND, std::string NewName) : ND(ND), NewName(std::move(NewName)) {} diff --git a/include/clang/Tooling/Refactoring/Rename/SymbolName.h b/include/clang/Tooling/Refactoring/Rename/SymbolName.h index 42e0a5cb6697..9131a4565da7 100644 --- a/include/clang/Tooling/Refactoring/Rename/SymbolName.h +++ b/include/clang/Tooling/Refactoring/Rename/SymbolName.h @@ -1,9 +1,8 @@ //===--- SymbolName.h - Clang refactoring library -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h b/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h index 0f853011978f..3b903cb822f3 100644 --- a/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h +++ b/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h @@ -1,9 +1,8 @@ //===--- SymbolOccurrences.h - Clang refactoring library ------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Refactoring/Rename/USRFinder.h b/include/clang/Tooling/Refactoring/Rename/USRFinder.h index 3622bd0daf85..30f7f0a0008c 100644 --- a/include/clang/Tooling/Refactoring/Rename/USRFinder.h +++ b/include/clang/Tooling/Refactoring/Rename/USRFinder.h @@ -1,9 +1,8 @@ //===--- USRFinder.h - Clang refactoring library --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h b/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h index ebc9790e9cb6..726987d9d46a 100644 --- a/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h +++ b/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h @@ -1,9 +1,8 @@ //===--- USRFindingAction.h - Clang refactoring library -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h b/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h index e1228e9f39f7..7a7dd76c4238 100644 --- a/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h +++ b/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h @@ -1,9 +1,8 @@ //===--- USRLocFinder.h - Clang refactoring library -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// diff --git a/include/clang/Tooling/Refactoring/SourceCode.h b/include/clang/Tooling/Refactoring/SourceCode.h new file mode 100644 index 000000000000..498dbea96c70 --- /dev/null +++ b/include/clang/Tooling/Refactoring/SourceCode.h @@ -0,0 +1,77 @@ +//===--- SourceCode.h - Source code manipulation routines -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides functions that simplify extraction of source code. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_H +#define LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_H + +#include "clang/AST/ASTContext.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TokenKinds.h" + +namespace clang { +namespace tooling { + +/// Extends \p Range to include the token \p Next, if it immediately follows the +/// end of the range. Otherwise, returns \p Range unchanged. +CharSourceRange maybeExtendRange(CharSourceRange Range, tok::TokenKind Next, + ASTContext &Context); + +/// Returns the source range spanning the node, extended to include \p Next, if +/// it immediately follows \p Node. Otherwise, returns the normal range of \p +/// Node. See comments on `getExtendedText()` for examples. +template <typename T> +CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next, + ASTContext &Context) { + return maybeExtendRange(CharSourceRange::getTokenRange(Node.getSourceRange()), + Next, Context); +} + +/// Returns the source-code text in the specified range. +StringRef getText(CharSourceRange Range, const ASTContext &Context); + +/// Returns the source-code text corresponding to \p Node. +template <typename T> +StringRef getText(const T &Node, const ASTContext &Context) { + return getText(CharSourceRange::getTokenRange(Node.getSourceRange()), + Context); +} + +/// Returns the source text of the node, extended to include \p Next, if it +/// immediately follows the node. Otherwise, returns the text of just \p Node. +/// +/// For example, given statements S1 and S2 below: +/// \code +/// { +/// // S1: +/// if (!x) return foo(); +/// // S2: +/// if (!x) { return 3; } +/// } +/// \endcode +/// then +/// \code +/// getText(S1, Context) = "if (!x) return foo()" +/// getExtendedText(S1, tok::TokenKind::semi, Context) +/// = "if (!x) return foo();" +/// getExtendedText(*S1.getThen(), tok::TokenKind::semi, Context) +/// = "return foo();" +/// getExtendedText(*S2.getThen(), tok::TokenKind::semi, Context) +/// = getText(S2, Context) = "{ return 3; }" +/// \endcode +template <typename T> +StringRef getExtendedText(const T &Node, tok::TokenKind Next, + ASTContext &Context) { + return getText(getExtendedRange(Node, Next, Context), Context); +} +} // namespace tooling +} // namespace clang +#endif // LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_H diff --git a/include/clang/Tooling/Refactoring/Stencil.h b/include/clang/Tooling/Refactoring/Stencil.h new file mode 100644 index 000000000000..e57a576e5575 --- /dev/null +++ b/include/clang/Tooling/Refactoring/Stencil.h @@ -0,0 +1,173 @@ +//===--- Stencil.h - Stencil class ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// /file +/// This file defines the *Stencil* abstraction: a code-generating object, +/// parameterized by named references to (bound) AST nodes. Given a match +/// result, a stencil can be evaluated to a string of source code. +/// +/// A stencil is similar in spirit to a format string: it is composed of a +/// series of raw text strings, references to nodes (the parameters) and helper +/// code-generation operations. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTOR_STENCIL_H_ +#define LLVM_CLANG_TOOLING_REFACTOR_STENCIL_H_ + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTTypeTraits.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Tooling/Refactoring/RangeSelector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include <string> +#include <vector> + +namespace clang { +namespace tooling { + +/// A stencil is represented as a sequence of "parts" that can each individually +/// generate a code string based on a match result. The different kinds of +/// parts include (raw) text, references to bound nodes and assorted operations +/// on bound nodes. +/// +/// Users can create custom Stencil operations by implementing this interface. +class StencilPartInterface { +public: + virtual ~StencilPartInterface() = default; + + /// Evaluates this part to a string and appends it to \c Result. \c Result is + /// undefined in the case of an error. + virtual llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &Match, + std::string *Result) const = 0; + + virtual bool isEqual(const StencilPartInterface &other) const = 0; + + const void *typeId() const { return TypeId; } + +protected: + StencilPartInterface(const void *DerivedId) : TypeId(DerivedId) {} + + // Since this is an abstract class, copying/assigning only make sense for + // derived classes implementing `clone()`. + StencilPartInterface(const StencilPartInterface &) = default; + StencilPartInterface &operator=(const StencilPartInterface &) = default; + + /// Unique identifier of the concrete type of this instance. Supports safe + /// downcasting. + const void *TypeId; +}; + +/// A copyable facade for a std::unique_ptr<StencilPartInterface>. Copies result +/// in a copy of the underlying pointee object. +class StencilPart { +public: + explicit StencilPart(std::shared_ptr<StencilPartInterface> Impl) + : Impl(std::move(Impl)) {} + + /// See `StencilPartInterface::eval()`. + llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &Match, + std::string *Result) const { + return Impl->eval(Match, Result); + } + + bool operator==(const StencilPart &Other) const { + if (Impl == Other.Impl) + return true; + if (Impl == nullptr || Other.Impl == nullptr) + return false; + return Impl->isEqual(*Other.Impl); + } + +private: + std::shared_ptr<StencilPartInterface> Impl; +}; + +/// A sequence of code fragments, references to parameters and code-generation +/// operations that together can be evaluated to (a fragment of) source code, +/// given a match result. +class Stencil { +public: + Stencil() = default; + + /// Composes a stencil from a series of parts. + template <typename... Ts> static Stencil cat(Ts &&... Parts) { + Stencil S; + S.Parts = {wrap(std::forward<Ts>(Parts))...}; + return S; + } + + /// Appends data from a \p OtherStencil to this stencil. + void append(Stencil OtherStencil); + + // Evaluates the stencil given a match result. Requires that the nodes in the + // result includes any ids referenced in the stencil. References to missing + // nodes will result in an invalid_argument error. + llvm::Expected<std::string> + eval(const ast_matchers::MatchFinder::MatchResult &Match) const; + + // Allow Stencils to operate as std::function, for compatibility with + // Transformer's TextGenerator. + llvm::Expected<std::string> + operator()(const ast_matchers::MatchFinder::MatchResult &Result) const { + return eval(Result); + } + +private: + friend bool operator==(const Stencil &A, const Stencil &B); + static StencilPart wrap(llvm::StringRef Text); + static StencilPart wrap(RangeSelector Selector); + static StencilPart wrap(StencilPart Part) { return Part; } + + std::vector<StencilPart> Parts; +}; + +inline bool operator==(const Stencil &A, const Stencil &B) { + return A.Parts == B.Parts; +} + +inline bool operator!=(const Stencil &A, const Stencil &B) { return !(A == B); } + +// Functions for conveniently building stencils. +namespace stencil { +/// Convenience wrapper for Stencil::cat that can be imported with a using decl. +template <typename... Ts> Stencil cat(Ts &&... Parts) { + return Stencil::cat(std::forward<Ts>(Parts)...); +} + +/// \returns exactly the text provided. +StencilPart text(llvm::StringRef Text); + +/// \returns the source corresponding to the selected range. +StencilPart selection(RangeSelector Selector); + +/// \returns the source corresponding to the identified node. +/// FIXME: Deprecated. Write `selection(node(Id))` instead. +inline StencilPart node(llvm::StringRef Id) { + return selection(tooling::node(Id)); +} + +/// Variant of \c node() that identifies the node as a statement, for purposes +/// of deciding whether to include any trailing semicolon. Only relevant for +/// Expr nodes, which, by default, are *not* considered as statements. +/// \returns the source corresponding to the identified node, considered as a +/// statement. +/// FIXME: Deprecated. Write `selection(statement(Id))` instead. +inline StencilPart sNode(llvm::StringRef Id) { + return selection(tooling::statement(Id)); +} + +/// For debug use only; semantics are not guaranteed. +/// +/// \returns the string resulting from calling the node's print() method. +StencilPart dPrint(llvm::StringRef Id); +} // namespace stencil +} // namespace tooling +} // namespace clang +#endif // LLVM_CLANG_TOOLING_REFACTOR_STENCIL_H_ diff --git a/include/clang/Tooling/Refactoring/Transformer.h b/include/clang/Tooling/Refactoring/Transformer.h new file mode 100644 index 000000000000..6d9c5a37cc18 --- /dev/null +++ b/include/clang/Tooling/Refactoring/Transformer.h @@ -0,0 +1,308 @@ +//===--- Transformer.h - Clang source-rewriting library ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Defines a library supporting the concise specification of clang-based +/// source-to-source transformations. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_ +#define LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_ + +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersInternal.h" +#include "clang/Tooling/Refactoring/AtomicChange.h" +#include "clang/Tooling/Refactoring/RangeSelector.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Error.h" +#include <deque> +#include <functional> +#include <string> +#include <type_traits> +#include <utility> + +namespace clang { +namespace tooling { + +// Note that \p TextGenerator is allowed to fail, e.g. when trying to access a +// matched node that was not bound. Allowing this to fail simplifies error +// handling for interactive tools like clang-query. +using TextGenerator = std::function<Expected<std::string>( + const ast_matchers::MatchFinder::MatchResult &)>; + +/// Wraps a string as a TextGenerator. +inline TextGenerator text(std::string M) { + return [M](const ast_matchers::MatchFinder::MatchResult &) + -> Expected<std::string> { return M; }; +} + +// Description of a source-code edit, expressed in terms of an AST node. +// Includes: an ID for the (bound) node, a selector for source related to the +// node, a replacement and, optionally, an explanation for the edit. +// +// * Target: the source code impacted by the rule. This identifies an AST node, +// or part thereof (\c Part), whose source range indicates the extent of the +// replacement applied by the replacement term. By default, the extent is the +// node matched by the pattern term (\c NodePart::Node). Target's are typed +// (\c Kind), which guides the determination of the node extent. +// +// * Replacement: a function that produces a replacement string for the target, +// based on the match result. +// +// * Note: (optional) a note specifically for this edit, potentially referencing +// elements of the match. This will be displayed to the user, where possible; +// for example, in clang-tidy diagnostics. Use of notes should be rare -- +// explanations of the entire rewrite should be set in the rule +// (`RewriteRule::Explanation`) instead. Notes serve the rare cases wherein +// edit-specific diagnostics are required. +// +// `ASTEdit` should be built using the `change` convenience functions. For +// example, +// \code +// change(name(fun), text("Frodo")) +// \endcode +// Or, if we use Stencil for the TextGenerator: +// \code +// using stencil::cat; +// change(statement(thenNode), cat("{", thenNode, "}")) +// change(callArgs(call), cat(x, ",", y)) +// \endcode +// Or, if you are changing the node corresponding to the rule's matcher, you can +// use the single-argument override of \c change: +// \code +// change(cat("different_expr")) +// \endcode +struct ASTEdit { + RangeSelector TargetRange; + TextGenerator Replacement; + TextGenerator Note; +}; + +/// Format of the path in an include directive -- angle brackets or quotes. +enum class IncludeFormat { + Quoted, + Angled, +}; + +/// Description of a source-code transformation. +// +// A *rewrite rule* describes a transformation of source code. A simple rule +// contains each of the following components: +// +// * Matcher: the pattern term, expressed as clang matchers (with Transformer +// extensions). +// +// * Edits: a set of Edits to the source code, described with ASTEdits. +// +// * Explanation: explanation of the rewrite. This will be displayed to the +// user, where possible; for example, in clang-tidy diagnostics. +// +// However, rules can also consist of (sub)rules, where the first that matches +// is applied and the rest are ignored. So, the above components are gathered +// as a `Case` and a rule is a list of cases. +// +// Rule cases have an additional, implicit, component: the parameters. These are +// portions of the pattern which are left unspecified, yet bound in the pattern +// so that we can reference them in the edits. +// +// The \c Transformer class can be used to apply the rewrite rule and obtain the +// corresponding replacements. +struct RewriteRule { + struct Case { + ast_matchers::internal::DynTypedMatcher Matcher; + SmallVector<ASTEdit, 1> Edits; + TextGenerator Explanation; + // Include paths to add to the file affected by this case. These are + // bundled with the `Case`, rather than the `RewriteRule`, because each case + // might have different associated changes to the includes. + std::vector<std::pair<std::string, IncludeFormat>> AddedIncludes; + }; + // We expect RewriteRules will most commonly include only one case. + SmallVector<Case, 1> Cases; + + // ID used as the default target of each match. The node described by the + // matcher is should always be bound to this id. + static constexpr llvm::StringLiteral RootID = "___root___"; +}; + +/// Convenience function for constructing a simple \c RewriteRule. +RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M, + SmallVector<ASTEdit, 1> Edits, + TextGenerator Explanation = nullptr); + +/// Convenience overload of \c makeRule for common case of only one edit. +inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M, + ASTEdit Edit, + TextGenerator Explanation = nullptr) { + SmallVector<ASTEdit, 1> Edits; + Edits.emplace_back(std::move(Edit)); + return makeRule(std::move(M), std::move(Edits), std::move(Explanation)); +} + +/// For every case in Rule, adds an include directive for the given header. The +/// common use is assumed to be a rule with only one case. For example, to +/// replace a function call and add headers corresponding to the new code, one +/// could write: +/// \code +/// auto R = makeRule(callExpr(callee(functionDecl(hasName("foo")))), +/// change(text("bar()"))); +/// AddInclude(R, "path/to/bar_header.h"); +/// AddInclude(R, "vector", IncludeFormat::Angled); +/// \endcode +void addInclude(RewriteRule &Rule, llvm::StringRef Header, + IncludeFormat Format = IncludeFormat::Quoted); + +/// Applies the first rule whose pattern matches; other rules are ignored. +/// +/// N.B. All of the rules must use the same kind of matcher (that is, share a +/// base class in the AST hierarchy). However, this constraint is caused by an +/// implementation detail and should be lifted in the future. +// +// `applyFirst` is like an `anyOf` matcher with an edit action attached to each +// of its cases. Anywhere you'd use `anyOf(m1.bind("id1"), m2.bind("id2"))` and +// then dispatch on those ids in your code for control flow, `applyFirst` lifts +// that behavior to the rule level. So, you can write `applyFirst({makeRule(m1, +// action1), makeRule(m2, action2), ...});` +// +// For example, consider a type `T` with a deterministic serialization function, +// `serialize()`. For performance reasons, we would like to make it +// non-deterministic. Therefore, we want to drop the expectation that +// `a.serialize() = b.serialize() iff a = b` (although we'll maintain +// `deserialize(a.serialize()) = a`). +// +// We have three cases to consider (for some equality function, `eq`): +// ``` +// eq(a.serialize(), b.serialize()) --> eq(a,b) +// eq(a, b.serialize()) --> eq(deserialize(a), b) +// eq(a.serialize(), b) --> eq(a, deserialize(b)) +// ``` +// +// `applyFirst` allows us to specify each independently: +// ``` +// auto eq_fun = functionDecl(...); +// auto method_call = cxxMemberCallExpr(...); +// +// auto two_calls = callExpr(callee(eq_fun), hasArgument(0, method_call), +// hasArgument(1, method_call)); +// auto left_call = +// callExpr(callee(eq_fun), callExpr(hasArgument(0, method_call))); +// auto right_call = +// callExpr(callee(eq_fun), callExpr(hasArgument(1, method_call))); +// +// RewriteRule R = applyFirst({makeRule(two_calls, two_calls_action), +// makeRule(left_call, left_call_action), +// makeRule(right_call, right_call_action)}); +// ``` +RewriteRule applyFirst(ArrayRef<RewriteRule> Rules); + +/// Replaces a portion of the source text with \p Replacement. +ASTEdit change(RangeSelector Target, TextGenerator Replacement); + +/// Replaces the entirety of a RewriteRule's match with \p Replacement. For +/// example, to replace a function call, one could write: +/// \code +/// makeRule(callExpr(callee(functionDecl(hasName("foo")))), +/// change(text("bar()"))) +/// \endcode +inline ASTEdit change(TextGenerator Replacement) { + return change(node(RewriteRule::RootID), std::move(Replacement)); +} + +/// Inserts \p Replacement before \p S, leaving the source selected by \S +/// unchanged. +inline ASTEdit insertBefore(RangeSelector S, TextGenerator Replacement) { + return change(before(std::move(S)), std::move(Replacement)); +} + +/// Inserts \p Replacement after \p S, leaving the source selected by \S +/// unchanged. +inline ASTEdit insertAfter(RangeSelector S, TextGenerator Replacement) { + return change(after(std::move(S)), std::move(Replacement)); +} + +/// Removes the source selected by \p S. +inline ASTEdit remove(RangeSelector S) { + return change(std::move(S), text("")); +} + +/// The following three functions are a low-level part of the RewriteRule +/// API. We expose them for use in implementing the fixtures that interpret +/// RewriteRule, like Transformer and TransfomerTidy, or for more advanced +/// users. +// +// FIXME: These functions are really public, if advanced, elements of the +// RewriteRule API. Recast them as such. Or, just declare these functions +// public and well-supported and move them out of `detail`. +namespace detail { +/// Builds a single matcher for the rule, covering all of the rule's cases. +ast_matchers::internal::DynTypedMatcher buildMatcher(const RewriteRule &Rule); + +/// Returns the \c Case of \c Rule that was selected in the match result. +/// Assumes a matcher built with \c buildMatcher. +const RewriteRule::Case & +findSelectedCase(const ast_matchers::MatchFinder::MatchResult &Result, + const RewriteRule &Rule); + +/// A source "transformation," represented by a character range in the source to +/// be replaced and a corresponding replacement string. +struct Transformation { + CharSourceRange Range; + std::string Replacement; +}; + +/// Attempts to translate `Edits`, which are in terms of AST nodes bound in the +/// match `Result`, into Transformations, which are in terms of the source code +/// text. +/// +/// Returns an empty vector if any of the edits apply to portions of the source +/// that are ineligible for rewriting (certain interactions with macros, for +/// example). Fails if any invariants are violated relating to bound nodes in +/// the match. However, it does not fail in the case of conflicting edits -- +/// conflict handling is left to clients. We recommend use of the \c +/// AtomicChange or \c Replacements classes for assistance in detecting such +/// conflicts. +Expected<SmallVector<Transformation, 1>> +translateEdits(const ast_matchers::MatchFinder::MatchResult &Result, + llvm::ArrayRef<ASTEdit> Edits); +} // namespace detail + +/// Handles the matcher and callback registration for a single rewrite rule, as +/// defined by the arguments of the constructor. +class Transformer : public ast_matchers::MatchFinder::MatchCallback { +public: + using ChangeConsumer = + std::function<void(Expected<clang::tooling::AtomicChange> Change)>; + + /// \param Consumer Receives each rewrite or error. Will not necessarily be + /// called for each match; for example, if the rewrite is not applicable + /// because of macros, but doesn't fail. Note that clients are responsible + /// for handling the case that independent \c AtomicChanges conflict with each + /// other. + Transformer(RewriteRule Rule, ChangeConsumer Consumer) + : Rule(std::move(Rule)), Consumer(std::move(Consumer)) {} + + /// N.B. Passes `this` pointer to `MatchFinder`. So, this object should not + /// be moved after this call. + void registerMatchers(ast_matchers::MatchFinder *MatchFinder); + + /// Not called directly by users -- called by the framework, via base class + /// pointer. + void run(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + RewriteRule Rule; + /// Receives each successful rewrites as an \c AtomicChange. + ChangeConsumer Consumer; +}; +} // namespace tooling +} // namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_ diff --git a/include/clang/Tooling/RefactoringCallbacks.h b/include/clang/Tooling/RefactoringCallbacks.h index 2137e0035d62..ac3f28dce80c 100644 --- a/include/clang/Tooling/RefactoringCallbacks.h +++ b/include/clang/Tooling/RefactoringCallbacks.h @@ -1,9 +1,8 @@ //===--- RefactoringCallbacks.h - Structural query framework ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h index 8e41525a9412..2e3e401652e2 100644 --- a/include/clang/Tooling/ReplacementsYaml.h +++ b/include/clang/Tooling/ReplacementsYaml.h @@ -1,9 +1,8 @@ //===-- ReplacementsYaml.h -- Serialiazation for Replacements ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -36,7 +35,13 @@ template <> struct MappingTraits<clang::tooling::Replacement> { NormalizedReplacement(const IO &, const clang::tooling::Replacement &R) : FilePath(R.getFilePath()), Offset(R.getOffset()), - Length(R.getLength()), ReplacementText(R.getReplacementText()) {} + Length(R.getLength()), ReplacementText(R.getReplacementText()) { + size_t lineBreakPos = ReplacementText.find('\n'); + while (lineBreakPos != std::string::npos) { + ReplacementText.replace(lineBreakPos, 1, "\n\n"); + lineBreakPos = ReplacementText.find('\n', lineBreakPos + 2); + } + } clang::tooling::Replacement denormalize(const IO &) { return clang::tooling::Replacement(FilePath, Offset, Length, diff --git a/include/clang/Tooling/StandaloneExecution.h b/include/clang/Tooling/StandaloneExecution.h index 96487b4bb1dd..5fbc1e479c59 100644 --- a/include/clang/Tooling/StandaloneExecution.h +++ b/include/clang/Tooling/StandaloneExecution.h @@ -1,9 +1,8 @@ //===--- StandaloneExecution.h - Standalone execution. -*- C++ ----------*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/include/clang/Tooling/Syntax/BuildTree.h b/include/clang/Tooling/Syntax/BuildTree.h new file mode 100644 index 000000000000..055d6462eabd --- /dev/null +++ b/include/clang/Tooling/Syntax/BuildTree.h @@ -0,0 +1,24 @@ +//===- BuildTree.h - build syntax trees -----------------------*- C++ -*-=====// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Functions to construct a syntax tree from an AST. +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_TOOLING_SYNTAX_TREE_H +#define LLVM_CLANG_TOOLING_SYNTAX_TREE_H + +#include "clang/AST/Decl.h" +#include "clang/Tooling/Syntax/Nodes.h" + +namespace clang { +namespace syntax { + +/// Build a syntax tree for the main file. +syntax::TranslationUnit *buildSyntaxTree(Arena &A, + const clang::TranslationUnitDecl &TU); +} // namespace syntax +} // namespace clang +#endif diff --git a/include/clang/Tooling/Syntax/Nodes.h b/include/clang/Tooling/Syntax/Nodes.h new file mode 100644 index 000000000000..d20c7cb7b171 --- /dev/null +++ b/include/clang/Tooling/Syntax/Nodes.h @@ -0,0 +1,92 @@ +//===- Nodes.h - syntax nodes for C/C++ grammar constructs ----*- C++ -*-=====// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Syntax tree nodes for C, C++ and Objective-C grammar constructs. +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_TOOLING_SYNTAX_NODES_H +#define LLVM_CLANG_TOOLING_SYNTAX_NODES_H + +#include "clang/Basic/TokenKinds.h" +#include "clang/Lex/Token.h" +#include "clang/Tooling/Syntax/Tokens.h" +#include "clang/Tooling/Syntax/Tree.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { +namespace syntax { + +/// A kind of a syntax node, used for implementing casts. +enum class NodeKind : uint16_t { + Leaf, + TranslationUnit, + TopLevelDeclaration, + CompoundStatement +}; +/// For debugging purposes. +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeKind K); + +/// A relation between a parent and child node. Used for implementing accessors. +enum class NodeRole : uint8_t { + // A node without a parent. + Detached, + // Children of an unknown semantic nature, e.g. skipped tokens, comments. + Unknown, + // FIXME: should this be shared for all other nodes with braces, e.g. init + // lists? + CompoundStatement_lbrace, + CompoundStatement_rbrace +}; + +/// A root node for a translation unit. Parent is always null. +class TranslationUnit final : public Tree { +public: + TranslationUnit() : Tree(NodeKind::TranslationUnit) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::TranslationUnit; + } +}; + +/// FIXME: this node is temporary and will be replaced with nodes for various +/// 'declarations' and 'declarators' from the C/C++ grammar +/// +/// Represents any top-level declaration. Only there to give the syntax tree a +/// bit of structure until we implement syntax nodes for declarations and +/// declarators. +class TopLevelDeclaration final : public Tree { +public: + TopLevelDeclaration() : Tree(NodeKind::TopLevelDeclaration) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::TopLevelDeclaration; + } +}; + +/// An abstract node for C++ statements, e.g. 'while', 'if', etc. +class Statement : public Tree { +public: + Statement(NodeKind K) : Tree(K) {} + static bool classof(const Node *N) { + return NodeKind::CompoundStatement <= N->kind() && + N->kind() <= NodeKind::CompoundStatement; + } +}; + +/// { statement1; statement2; … } +class CompoundStatement final : public Statement { +public: + CompoundStatement() : Statement(NodeKind::CompoundStatement) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::CompoundStatement; + } + syntax::Leaf *lbrace(); + syntax::Leaf *rbrace(); +}; + +} // namespace syntax +} // namespace clang +#endif diff --git a/include/clang/Tooling/Syntax/Tokens.h b/include/clang/Tooling/Syntax/Tokens.h new file mode 100644 index 000000000000..4640ccb2d30a --- /dev/null +++ b/include/clang/Tooling/Syntax/Tokens.h @@ -0,0 +1,355 @@ +//===- Tokens.h - collect tokens from preprocessing --------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Record tokens that a preprocessor emits and define operations to map between +// the tokens written in a file and tokens produced by the preprocessor. +// +// When running the compiler, there are two token streams we are interested in: +// - "spelled" tokens directly correspond to a substring written in some +// source file. +// - "expanded" tokens represent the result of preprocessing, parses consumes +// this token stream to produce the AST. +// +// Expanded tokens correspond directly to locations found in the AST, allowing +// to find subranges of the token stream covered by various AST nodes. Spelled +// tokens correspond directly to the source code written by the user. +// +// To allow composing these two use-cases, we also define operations that map +// between expanded and spelled tokens that produced them (macro calls, +// directives, etc). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_SYNTAX_TOKENS_H +#define LLVM_CLANG_TOOLING_SYNTAX_TOKENS_H + +#include "clang/Basic/FileManager.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TokenKinds.h" +#include "clang/Lex/Token.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" +#include <cstdint> +#include <tuple> + +namespace clang { +class Preprocessor; + +namespace syntax { + +/// A half-open character range inside a particular file, the start offset is +/// included and the end offset is excluded from the range. +struct FileRange { + /// EXPECTS: File.isValid() && Begin <= End. + FileRange(FileID File, unsigned BeginOffset, unsigned EndOffset); + /// EXPECTS: BeginLoc.isValid() && BeginLoc.isFileID(). + FileRange(const SourceManager &SM, SourceLocation BeginLoc, unsigned Length); + /// EXPECTS: BeginLoc.isValid() && BeginLoc.isFileID(), Begin <= End and files + /// are the same. + FileRange(const SourceManager &SM, SourceLocation BeginLoc, + SourceLocation EndLoc); + + FileID file() const { return File; } + /// Start is a start offset (inclusive) in the corresponding file. + unsigned beginOffset() const { return Begin; } + /// End offset (exclusive) in the corresponding file. + unsigned endOffset() const { return End; } + + unsigned length() const { return End - Begin; } + + /// Check if \p Offset is inside the range. + bool contains(unsigned Offset) const { + return Begin <= Offset && Offset < End; + } + /// Check \p Offset is inside the range or equal to its endpoint. + bool touches(unsigned Offset) const { + return Begin <= Offset && Offset <= End; + } + + /// Gets the substring that this FileRange refers to. + llvm::StringRef text(const SourceManager &SM) const; + + friend bool operator==(const FileRange &L, const FileRange &R) { + return std::tie(L.File, L.Begin, L.End) == std::tie(R.File, R.Begin, R.End); + } + friend bool operator!=(const FileRange &L, const FileRange &R) { + return !(L == R); + } + +private: + FileID File; + unsigned Begin; + unsigned End; +}; + +/// For debugging purposes. +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FileRange &R); + +/// A token coming directly from a file or from a macro invocation. Has just +/// enough information to locate the token in the source code. +/// Can represent both expanded and spelled tokens. +class Token { +public: + Token(SourceLocation Location, unsigned Length, tok::TokenKind Kind); + /// EXPECTS: clang::Token is not an annotation token. + explicit Token(const clang::Token &T); + + tok::TokenKind kind() const { return Kind; } + /// Location of the first character of a token. + SourceLocation location() const { return Location; } + /// Location right after the last character of a token. + SourceLocation endLocation() const { + return Location.getLocWithOffset(Length); + } + unsigned length() const { return Length; } + + /// Get the substring covered by the token. Note that will include all + /// digraphs, newline continuations, etc. E.g. tokens for 'int' and + /// in\ + /// t + /// both have the same kind tok::kw_int, but results of text() are different. + llvm::StringRef text(const SourceManager &SM) const; + + /// Gets a range of this token. + /// EXPECTS: token comes from a file, not from a macro expansion. + FileRange range(const SourceManager &SM) const; + + /// Given two tokens inside the same file, returns a file range that starts at + /// \p First and ends at \p Last. + /// EXPECTS: First and Last are file tokens from the same file, Last starts + /// after First. + static FileRange range(const SourceManager &SM, const syntax::Token &First, + const syntax::Token &Last); + + std::string dumpForTests(const SourceManager &SM) const; + /// For debugging purposes. + std::string str() const; + +private: + SourceLocation Location; + unsigned Length; + tok::TokenKind Kind; +}; +/// For debugging purposes. Equivalent to a call to Token::str(). +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Token &T); + +/// A list of tokens obtained by preprocessing a text buffer and operations to +/// map between the expanded and spelled tokens, i.e. TokenBuffer has +/// information about two token streams: +/// 1. Expanded tokens: tokens produced by the preprocessor after all macro +/// replacements, +/// 2. Spelled tokens: corresponding directly to the source code of a file +/// before any macro replacements occurred. +/// Here's an example to illustrate a difference between those two: +/// #define FOO 10 +/// int a = FOO; +/// +/// Spelled tokens are {'#','define','FOO','10','int','a','=','FOO',';'}. +/// Expanded tokens are {'int','a','=','10',';','eof'}. +/// +/// Note that the expanded token stream has a tok::eof token at the end, the +/// spelled tokens never store a 'eof' token. +/// +/// The full list expanded tokens can be obtained with expandedTokens(). Spelled +/// tokens for each of the files can be obtained via spelledTokens(FileID). +/// +/// To map between the expanded and spelled tokens use findSpelledByExpanded(). +/// +/// To build a token buffer use the TokenCollector class. You can also compute +/// the spelled tokens of a file using the tokenize() helper. +/// +/// FIXME: allow to map from spelled to expanded tokens when use-case shows up. +/// FIXME: allow mappings into macro arguments. +class TokenBuffer { +public: + TokenBuffer(const SourceManager &SourceMgr) : SourceMgr(&SourceMgr) {} + /// All tokens produced by the preprocessor after all macro replacements, + /// directives, etc. Source locations found in the clang AST will always + /// point to one of these tokens. + /// FIXME: figure out how to handle token splitting, e.g. '>>' can be split + /// into two '>' tokens by the parser. However, TokenBuffer currently + /// keeps it as a single '>>' token. + llvm::ArrayRef<syntax::Token> expandedTokens() const { + return ExpandedTokens; + } + + /// Find the subrange of spelled tokens that produced the corresponding \p + /// Expanded tokens. + /// + /// EXPECTS: \p Expanded is a subrange of expandedTokens(). + /// + /// Will fail if the expanded tokens do not correspond to a + /// sequence of spelled tokens. E.g. for the following example: + /// + /// #define FIRST f1 f2 f3 + /// #define SECOND s1 s2 s3 + /// + /// a FIRST b SECOND c // expanded tokens are: a f1 f2 f3 b s1 s2 s3 c + /// + /// the results would be: + /// expanded => spelled + /// ------------------------ + /// a => a + /// s1 s2 s3 => SECOND + /// a f1 f2 f3 => a FIRST + /// a f1 => can't map + /// s1 s2 => can't map + /// + /// If \p Expanded is empty, the returned value is llvm::None. + /// Complexity is logarithmic. + llvm::Optional<llvm::ArrayRef<syntax::Token>> + spelledForExpanded(llvm::ArrayRef<syntax::Token> Expanded) const; + + /// An expansion produced by the preprocessor, includes macro expansions and + /// preprocessor directives. Preprocessor always maps a non-empty range of + /// spelled tokens to a (possibly empty) range of expanded tokens. Here is a + /// few examples of expansions: + /// #pragma once // Expands to an empty range. + /// #define FOO 1 2 3 // Expands an empty range. + /// FOO // Expands to "1 2 3". + /// FIXME(ibiryukov): implement this, currently #include expansions are empty. + /// #include <vector> // Expands to tokens produced by the include. + struct Expansion { + llvm::ArrayRef<syntax::Token> Spelled; + llvm::ArrayRef<syntax::Token> Expanded; + }; + /// If \p Spelled starts a mapping (e.g. if it's a macro name or '#' starting + /// a preprocessor directive) return the subrange of expanded tokens that the + /// macro expands to. + llvm::Optional<Expansion> + expansionStartingAt(const syntax::Token *Spelled) const; + + /// Lexed tokens of a file before preprocessing. E.g. for the following input + /// #define DECL(name) int name = 10 + /// DECL(a); + /// spelledTokens() returns {"#", "define", "DECL", "(", "name", ")", "eof"}. + /// FIXME: we do not yet store tokens of directives, like #include, #define, + /// #pragma, etc. + llvm::ArrayRef<syntax::Token> spelledTokens(FileID FID) const; + + const SourceManager &sourceManager() const { return *SourceMgr; } + + std::string dumpForTests() const; + +private: + /// Describes a mapping between a continuous subrange of spelled tokens and + /// expanded tokens. Represents macro expansions, preprocessor directives, + /// conditionally disabled pp regions, etc. + /// #define FOO 1+2 + /// #define BAR(a) a + 1 + /// FOO // invocation #1, tokens = {'1','+','2'}, macroTokens = {'FOO'}. + /// BAR(1) // invocation #2, tokens = {'a', '+', '1'}, + /// macroTokens = {'BAR', '(', '1', ')'}. + struct Mapping { + // Positions in the corresponding spelled token stream. The corresponding + // range is never empty. + unsigned BeginSpelled = 0; + unsigned EndSpelled = 0; + // Positions in the expanded token stream. The corresponding range can be + // empty. + unsigned BeginExpanded = 0; + unsigned EndExpanded = 0; + + /// For debugging purposes. + std::string str() const; + }; + /// Spelled tokens of the file with information about the subranges. + struct MarkedFile { + /// Lexed, but not preprocessed, tokens of the file. These map directly to + /// text in the corresponding files and include tokens of all preprocessor + /// directives. + /// FIXME: spelled tokens don't change across FileID that map to the same + /// FileEntry. We could consider deduplicating them to save memory. + std::vector<syntax::Token> SpelledTokens; + /// A sorted list to convert between the spelled and expanded token streams. + std::vector<Mapping> Mappings; + /// The first expanded token produced for this FileID. + unsigned BeginExpanded = 0; + unsigned EndExpanded = 0; + }; + + friend class TokenCollector; + + /// Maps a single expanded token to its spelled counterpart or a mapping that + /// produced it. + std::pair<const syntax::Token *, const Mapping *> + spelledForExpandedToken(const syntax::Token *Expanded) const; + + /// Token stream produced after preprocessing, conceputally this captures the + /// same stream as 'clang -E' (excluding the preprocessor directives like + /// #file, etc.). + std::vector<syntax::Token> ExpandedTokens; + llvm::DenseMap<FileID, MarkedFile> Files; + // The value is never null, pointer instead of reference to avoid disabling + // implicit assignment operator. + const SourceManager *SourceMgr; +}; + +/// Lex the text buffer, corresponding to \p FID, in raw mode and record the +/// resulting spelled tokens. Does minimal post-processing on raw identifiers, +/// setting the appropriate token kind (instead of the raw_identifier reported +/// by lexer in raw mode). This is a very low-level function, most users should +/// prefer to use TokenCollector. Lexing in raw mode produces wildly different +/// results from what one might expect when running a C++ frontend, e.g. +/// preprocessor does not run at all. +/// The result will *not* have a 'eof' token at the end. +std::vector<syntax::Token> tokenize(FileID FID, const SourceManager &SM, + const LangOptions &LO); + +/// Collects tokens for the main file while running the frontend action. An +/// instance of this object should be created on +/// FrontendAction::BeginSourceFile() and the results should be consumed after +/// FrontendAction::Execute() finishes. +class TokenCollector { +public: + /// Adds the hooks to collect the tokens. Should be called before the + /// preprocessing starts, i.e. as a part of BeginSourceFile() or + /// CreateASTConsumer(). + TokenCollector(Preprocessor &P); + + /// Finalizes token collection. Should be called after preprocessing is + /// finished, i.e. after running Execute(). + LLVM_NODISCARD TokenBuffer consume() &&; + +private: + /// Maps from a start to an end spelling location of transformations + /// performed by the preprocessor. These include: + /// 1. range from '#' to the last token in the line for PP directives, + /// 2. macro name and arguments for macro expansions. + /// Note that we record only top-level macro expansions, intermediate + /// expansions (e.g. inside macro arguments) are ignored. + /// + /// Used to find correct boundaries of macro calls and directives when + /// building mappings from spelled to expanded tokens. + /// + /// Logically, at each point of the preprocessor execution there is a stack of + /// macro expansions being processed and we could use it to recover the + /// location information we need. However, the public preprocessor API only + /// exposes the points when macro expansions start (when we push a macro onto + /// the stack) and not when they end (when we pop a macro from the stack). + /// To workaround this limitation, we rely on source location information + /// stored in this map. + using PPExpansions = llvm::DenseMap</*SourceLocation*/ int, SourceLocation>; + class Builder; + class CollectPPExpansions; + + std::vector<syntax::Token> Expanded; + // FIXME: we only store macro expansions, also add directives(#pragma, etc.) + PPExpansions Expansions; + Preprocessor &PP; + CollectPPExpansions *Collector; +}; + +} // namespace syntax +} // namespace clang + +#endif diff --git a/include/clang/Tooling/Syntax/Tree.h b/include/clang/Tooling/Syntax/Tree.h new file mode 100644 index 000000000000..b66777561a6a --- /dev/null +++ b/include/clang/Tooling/Syntax/Tree.h @@ -0,0 +1,142 @@ +//===- Tree.h - structure of the syntax tree ------------------*- C++ -*-=====// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Defines the basic structure of the syntax tree. There are two kinds of nodes: +// - leaf nodes correspond to a token in the expanded token stream, +// - tree nodes correspond to language grammar constructs. +// +// The tree is initially built from an AST. Each node of a newly built tree +// covers a continous subrange of expanded tokens (i.e. tokens after +// preprocessing), the specific tokens coverered are stored in the leaf nodes of +// a tree. A post-order traversal of a tree will visit leaf nodes in an order +// corresponding the original order of expanded tokens. +// +// This is still work in progress and highly experimental, we leave room for +// ourselves to completely change the design and/or implementation. +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_TOOLING_SYNTAX_TREE_CASCADE_H +#define LLVM_CLANG_TOOLING_SYNTAX_TREE_CASCADE_H + +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TokenKinds.h" +#include "clang/Tooling/Syntax/Tokens.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Allocator.h" +#include <cstdint> + +namespace clang { +namespace syntax { + +/// A memory arena for syntax trees. Also tracks the underlying token buffers, +/// source manager, etc. +class Arena { +public: + Arena(SourceManager &SourceMgr, const LangOptions &LangOpts, + TokenBuffer Tokens); + + const SourceManager &sourceManager() const { return SourceMgr; } + const LangOptions &langOptions() const { return LangOpts; } + + const TokenBuffer &tokenBuffer() const; + llvm::BumpPtrAllocator &allocator() { return Allocator; } + + /// Add \p Buffer to the underlying source manager, tokenize it and store the + /// resulting tokens. Useful when there is a need to materialize tokens that + /// were not written in user code. + std::pair<FileID, llvm::ArrayRef<syntax::Token>> + lexBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer); + +private: + SourceManager &SourceMgr; + const LangOptions &LangOpts; + TokenBuffer Tokens; + /// IDs and storage for additional tokenized files. + llvm::DenseMap<FileID, std::vector<syntax::Token>> ExtraTokens; + /// Keeps all the allocated nodes and their intermediate data structures. + llvm::BumpPtrAllocator Allocator; +}; + +class Tree; +class TreeBuilder; +enum class NodeKind : uint16_t; +enum class NodeRole : uint8_t; + +/// A node in a syntax tree. Each node is either a Leaf (representing tokens) or +/// a Tree (representing language constructrs). +class Node { +public: + /// Newly created nodes are detached from a tree, parent and sibling links are + /// set when the node is added as a child to another one. + Node(NodeKind Kind); + + NodeKind kind() const { return static_cast<NodeKind>(Kind); } + NodeRole role() const { return static_cast<NodeRole>(Role); } + + const Tree *parent() const { return Parent; } + Tree *parent() { return Parent; } + + const Node *nextSibling() const { return NextSibling; } + Node *nextSibling() { return NextSibling; } + + /// Dumps the structure of a subtree. For debugging and testing purposes. + std::string dump(const Arena &A) const; + /// Dumps the tokens forming this subtree. + std::string dumpTokens(const Arena &A) const; + +private: + // Tree is allowed to change the Parent link and Role. + friend class Tree; + + Tree *Parent; + Node *NextSibling; + unsigned Kind : 16; + unsigned Role : 8; +}; + +/// A leaf node points to a single token inside the expanded token stream. +class Leaf final : public Node { +public: + Leaf(const syntax::Token *T); + static bool classof(const Node *N); + + const syntax::Token *token() const { return Tok; } + +private: + const syntax::Token *Tok; +}; + +/// A node that has children and represents a syntactic language construct. +class Tree : public Node { +public: + using Node::Node; + static bool classof(const Node *N); + + Node *firstChild() { return FirstChild; } + const Node *firstChild() const { return FirstChild; } + +protected: + /// Find the first node with a corresponding role. + syntax::Node *findChild(NodeRole R); + +private: + /// Prepend \p Child to the list of children and and sets the parent pointer. + /// A very low-level operation that does not check any invariants, only used + /// by TreeBuilder. + /// EXPECTS: Role != NodeRoleDetached. + void prependChildLowLevel(Node *Child, NodeRole Role); + friend class TreeBuilder; + + Node *FirstChild = nullptr; +}; + +} // namespace syntax +} // namespace clang + +#endif diff --git a/include/clang/Tooling/ToolExecutorPluginRegistry.h b/include/clang/Tooling/ToolExecutorPluginRegistry.h index 921689dff86f..5304ff26252d 100644 --- a/include/clang/Tooling/ToolExecutorPluginRegistry.h +++ b/include/clang/Tooling/ToolExecutorPluginRegistry.h @@ -1,9 +1,8 @@ //===- ToolExecutorPluginRegistry.h -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h index 662a980547df..83fe43ac59e0 100644 --- a/include/clang/Tooling/Tooling.h +++ b/include/clang/Tooling/Tooling.h @@ -1,9 +1,8 @@ //===- Tooling.h - Framework for standalone Clang tools ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -361,6 +360,10 @@ public: /// turn this off when running on multiple threads to avoid the raciness. void setRestoreWorkingDir(bool RestoreCWD); + /// Sets whether an error message should be printed out if an action fails. By + /// default, if an action fails, a message is printed out to stderr. + void setPrintErrorMessage(bool PrintErrorMessage); + /// Returns the file manager used in the tool. /// /// The file manager is shared between all translation units. @@ -387,6 +390,7 @@ private: DiagnosticConsumer *DiagConsumer = nullptr; bool RestoreCWD = true; + bool PrintErrorMessage = true; }; template <typename T> |