aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/APValue.h46
-rw-r--r--include/clang/AST/ASTContext.h136
-rw-r--r--include/clang/AST/ASTFwd.h2
-rw-r--r--include/clang/AST/ASTImporter.h43
-rw-r--r--include/clang/AST/ASTImporterSharedState.h2
-rw-r--r--include/clang/AST/ASTNodeTraverser.h3
-rw-r--r--include/clang/AST/ASTStructuralEquivalence.h19
-rw-r--r--include/clang/AST/ASTTypeTraits.h4
-rw-r--r--include/clang/AST/Attr.h151
-rw-r--r--include/clang/AST/CXXRecordDeclDefinitionBits.def236
-rw-r--r--include/clang/AST/CharUnits.h5
-rw-r--r--include/clang/AST/CommentCommands.td1
-rw-r--r--include/clang/AST/CommentLexer.h3
-rw-r--r--include/clang/AST/Decl.h52
-rw-r--r--include/clang/AST/DeclBase.h2
-rw-r--r--include/clang/AST/DeclCXX.h343
-rw-r--r--include/clang/AST/DeclTemplate.h178
-rw-r--r--include/clang/AST/Expr.h16
-rw-r--r--include/clang/AST/ExprCXX.h235
-rw-r--r--include/clang/AST/ExternalASTMerger.h38
-rw-r--r--include/clang/AST/FormatString.h22
-rw-r--r--include/clang/AST/GlobalDecl.h1
-rw-r--r--include/clang/AST/JSONNodeDumper.h2
-rw-r--r--include/clang/AST/Mangle.h18
-rw-r--r--include/clang/AST/NSAPI.h3
-rw-r--r--include/clang/AST/OpenMPClause.h157
-rw-r--r--include/clang/AST/OperationKinds.def5
-rw-r--r--include/clang/AST/OptionalDiagnostic.h78
-rw-r--r--include/clang/AST/RawCommentList.h23
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h100
-rw-r--r--include/clang/AST/Stmt.h10
-rw-r--r--include/clang/AST/StmtOpenMP.h302
-rw-r--r--include/clang/AST/TextNodeDumper.h2
-rw-r--r--include/clang/AST/Type.h105
-rw-r--r--include/clang/AST/TypeLoc.h2
-rw-r--r--include/clang/AST/TypeLocNodes.def2
-rw-r--r--include/clang/AST/TypeNodes.def135
-rw-r--r--include/clang/AST/TypeVisitor.h4
38 files changed, 1618 insertions, 868 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index 6943479831ec..63359294ef63 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -53,6 +53,34 @@ public:
void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const;
};
+
+/// Symbolic representation of a dynamic allocation.
+class DynamicAllocLValue {
+ unsigned Index;
+
+public:
+ DynamicAllocLValue() : Index(0) {}
+ explicit DynamicAllocLValue(unsigned Index) : Index(Index + 1) {}
+ unsigned getIndex() { return Index - 1; }
+
+ explicit operator bool() const { return Index != 0; }
+
+ void *getOpaqueValue() {
+ return reinterpret_cast<void *>(static_cast<uintptr_t>(Index)
+ << NumLowBitsAvailable);
+ }
+ static DynamicAllocLValue getFromOpaqueValue(void *Value) {
+ DynamicAllocLValue V;
+ V.Index = reinterpret_cast<uintptr_t>(Value) >> NumLowBitsAvailable;
+ return V;
+ }
+
+ static unsigned getMaxIndex() {
+ return (std::numeric_limits<unsigned>::max() >> NumLowBitsAvailable) - 1;
+ }
+
+ static constexpr int NumLowBitsAvailable = 3;
+};
}
namespace llvm {
@@ -67,6 +95,17 @@ template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> {
// to include Type.h.
static constexpr int NumLowBitsAvailable = 3;
};
+
+template<> struct PointerLikeTypeTraits<clang::DynamicAllocLValue> {
+ static void *getAsVoidPointer(clang::DynamicAllocLValue V) {
+ return V.getOpaqueValue();
+ }
+ static clang::DynamicAllocLValue getFromVoidPointer(void *P) {
+ return clang::DynamicAllocLValue::getFromOpaqueValue(P);
+ }
+ static constexpr int NumLowBitsAvailable =
+ clang::DynamicAllocLValue::NumLowBitsAvailable;
+};
}
namespace clang {
@@ -97,13 +136,15 @@ public:
};
class LValueBase {
- typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue>
+ typedef llvm::PointerUnion<const ValueDecl *, const Expr *, TypeInfoLValue,
+ DynamicAllocLValue>
PtrTy;
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 getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
template <class T>
@@ -124,6 +165,7 @@ public:
unsigned getCallIndex() const;
unsigned getVersion() const;
QualType getTypeInfoType() const;
+ QualType getDynamicAllocType() const;
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
@@ -140,6 +182,8 @@ public:
LocalState Local;
/// The type std::type_info, if this is a TypeInfoLValue.
void *TypeInfoType;
+ /// The QualType, if this is a DynamicAllocLValue.
+ void *DynamicAllocType;
};
};
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 1d1aaf4fb115..5e2f4031d96c 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -139,6 +139,12 @@ class FullComment;
} // namespace comments
+namespace interp {
+
+class Context;
+
+} // namespace interp
+
struct TypeInfo {
uint64_t Width = 0;
unsigned Align = 0;
@@ -179,7 +185,8 @@ private:
mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
mutable llvm::FoldingSet<MemberPointerType> MemberPointerTypes;
- mutable llvm::FoldingSet<ConstantArrayType> ConstantArrayTypes;
+ mutable llvm::ContextualFoldingSet<ConstantArrayType, ASTContext &>
+ ConstantArrayTypes;
mutable llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
mutable std::vector<VariableArrayType*> VariableArrayTypes;
mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
@@ -507,6 +514,8 @@ private:
/// need to be consistently numbered for the mangler).
llvm::DenseMap<const DeclContext *, std::unique_ptr<MangleNumberingContext>>
MangleNumberingContexts;
+ llvm::DenseMap<const Decl *, std::unique_ptr<MangleNumberingContext>>
+ ExtraMangleNumberingContexts;
/// Side-table of mangling numbers for declarations which rarely
/// need them (like static local vars).
@@ -564,6 +573,7 @@ private:
const TargetInfo *Target = nullptr;
const TargetInfo *AuxTarget = nullptr;
clang::PrintingPolicy PrintingPolicy;
+ std::unique_ptr<interp::Context> InterpContext;
public:
IdentifierTable &Idents;
@@ -573,6 +583,9 @@ public:
IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
ASTMutationListener *Listener = nullptr;
+ /// Returns the clang bytecode interpreter context.
+ interp::Context &getInterpContext();
+
/// Container for either a single DynTypedNode or for an ArrayRef to
/// DynTypedNode. For use with ParentMap.
class DynTypedNodeList {
@@ -729,71 +742,49 @@ public:
/// True if comments are already loaded from ExternalASTSource.
mutable bool CommentsLoaded = false;
- class RawCommentAndCacheFlags {
- public:
- enum Kind {
- /// We searched for a comment attached to the particular declaration, but
- /// didn't find any.
- ///
- /// getRaw() == 0.
- NoCommentInDecl = 0,
-
- /// We have found a comment attached to this particular declaration.
- ///
- /// getRaw() != 0.
- FromDecl,
-
- /// This declaration does not have an attached comment, and we have
- /// searched the redeclaration chain.
- ///
- /// If getRaw() == 0, the whole redeclaration chain does not have any
- /// comments.
- ///
- /// If getRaw() != 0, it is a comment propagated from other
- /// redeclaration.
- FromRedecl
- };
-
- Kind getKind() const LLVM_READONLY {
- return Data.getInt();
- }
-
- void setKind(Kind K) {
- Data.setInt(K);
- }
-
- const RawComment *getRaw() const LLVM_READONLY {
- return Data.getPointer();
- }
-
- void setRaw(const RawComment *RC) {
- Data.setPointer(RC);
- }
-
- const Decl *getOriginalDecl() const LLVM_READONLY {
- return OriginalDecl;
- }
-
- void setOriginalDecl(const Decl *Orig) {
- OriginalDecl = Orig;
- }
-
- private:
- llvm::PointerIntPair<const RawComment *, 2, Kind> Data;
- const Decl *OriginalDecl;
- };
+ /// Mapping from declaration to directly attached comment.
+ ///
+ /// Raw comments are owned by Comments list. This mapping is populated
+ /// lazily.
+ mutable llvm::DenseMap<const Decl *, const RawComment *> DeclRawComments;
- /// Mapping from declarations to comments attached to any
- /// redeclaration.
+ /// Mapping from canonical declaration to the first redeclaration in chain
+ /// that has a comment attached.
///
/// Raw comments are owned by Comments list. This mapping is populated
/// lazily.
- mutable llvm::DenseMap<const Decl *, RawCommentAndCacheFlags> RedeclComments;
+ mutable llvm::DenseMap<const Decl *, const Decl *> RedeclChainComments;
+
+ /// Keeps track of redeclaration chains that don't have any comment attached.
+ /// Mapping from canonical declaration to redeclaration chain that has no
+ /// comments attached to any redeclaration. Specifically it's mapping to
+ /// the last redeclaration we've checked.
+ ///
+ /// Shall not contain declarations that have comments attached to any
+ /// redeclaration in their chain.
+ mutable llvm::DenseMap<const Decl *, const Decl *> CommentlessRedeclChains;
/// Mapping from declarations to parsed comments attached to any
/// redeclaration.
mutable llvm::DenseMap<const Decl *, comments::FullComment *> ParsedComments;
+ /// Attaches \p Comment to \p OriginalD and to its redeclaration chain
+ /// and removes the redeclaration chain from the set of commentless chains.
+ ///
+ /// Don't do anything if a comment has already been attached to \p OriginalD
+ /// or its redeclaration chain.
+ void cacheRawCommentForDecl(const Decl &OriginalD,
+ const RawComment &Comment) const;
+
+ /// \returns searches \p CommentsInFile for doc comment for \p D.
+ ///
+ /// \p RepresentativeLocForDecl is used as a location for searching doc
+ /// comments. \p CommentsInFile is a mapping offset -> comment of files in the
+ /// same file where \p RepresentativeLocForDecl is.
+ RawComment *getRawCommentForDeclNoCacheImpl(
+ const Decl *D, const SourceLocation RepresentativeLocForDecl,
+ const std::map<unsigned, RawComment *> &CommentsInFile) const;
+
/// Return the documentation comment attached to a given declaration,
/// without looking into cache.
RawComment *getRawCommentForDeclNoCache(const Decl *D) const;
@@ -818,6 +809,16 @@ public:
getRawCommentForAnyRedecl(const Decl *D,
const Decl **OriginalDecl = nullptr) const;
+ /// Searches existing comments for doc comments that should be attached to \p
+ /// Decls. If any doc comment is found, it is parsed.
+ ///
+ /// Requirement: All \p Decls are in the same file.
+ ///
+ /// If the last comment in the file is already attached we assume
+ /// there are not comments left to be attached to \p Decls.
+ void attachCommentsToJustParsedDecls(ArrayRef<Decl *> Decls,
+ const Preprocessor *PP);
+
/// Return parsed documentation comment attached to a given declaration.
/// Returns nullptr if no comment is attached.
///
@@ -1054,6 +1055,9 @@ public:
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
CanQualType Id##Ty;
#include "clang/Basic/OpenCLExtensionTypes.def"
+#define SVE_TYPE(Name, Id, SingletonId) \
+ CanQualType SingletonId;
+#include "clang/Basic/AArch64SVEACLETypes.def"
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
@@ -1329,6 +1333,7 @@ public:
/// Return the unique reference to the type for a constant array of
/// the specified element type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
+ const Expr *SizeExpr,
ArrayType::ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
@@ -1498,8 +1503,7 @@ public:
bool isKindOf) const;
QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
- ArrayRef<ObjCProtocolDecl *> protocols,
- QualType Canonical = QualType()) const;
+ ArrayRef<ObjCProtocolDecl *> protocols) const;
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
@@ -2054,6 +2058,11 @@ public:
/// types.
bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);
+ /// Return true if the type has been explicitly qualified with ObjC ownership.
+ /// A type may be implicitly qualified with ownership under ObjC ARC, and in
+ /// some cases the compiler treats these differently.
+ bool hasDirectOwnershipQualifier(QualType Ty) const;
+
/// Return true if this is an \c NSObject object with its \c NSObject
/// attribute set.
static bool isObjCNSObjectType(QualType Ty) {
@@ -2577,10 +2586,12 @@ public:
return T == getObjCSelType();
}
- bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
+ bool ObjCQualifiedIdTypesAreCompatible(const ObjCObjectPointerType *LHS,
+ const ObjCObjectPointerType *RHS,
bool ForCompare);
- bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS);
+ bool ObjCQualifiedClassTypesAreCompatible(const ObjCObjectPointerType *LHS,
+ const ObjCObjectPointerType *RHS);
// Check the safety of assignment from LHS to RHS
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
@@ -2802,6 +2813,9 @@ public:
/// Retrieve the context for computing mangling numbers in the given
/// DeclContext.
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
+ enum NeedExtraManglingDecl_t { NeedExtraManglingDecl };
+ MangleNumberingContext &getManglingNumberContext(NeedExtraManglingDecl_t,
+ const Decl *D);
std::unique_ptr<MangleNumberingContext> createMangleNumberingContext() const;
diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h
index 93919bbdd52f..25c321485443 100644
--- a/include/clang/AST/ASTFwd.h
+++ b/include/clang/AST/ASTFwd.h
@@ -24,7 +24,7 @@ class Stmt;
#include "clang/AST/StmtNodes.inc"
class Type;
#define TYPE(DERIVED, BASE) class DERIVED##Type;
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
class CXXCtorInitializer;
} // end namespace clang
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index 4a55c120a457..c82dcab35db5 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -87,6 +87,10 @@ class TypeSourceInfo;
using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>;
using ImportedCXXBaseSpecifierMap =
llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;
+ using FileIDImportHandlerType =
+ std::function<void(FileID /*ToID*/, FileID /*FromID*/)>;
+
+ enum class ODRHandlingType { Conservative, Liberal };
// An ImportPath is the list of the AST nodes which we visit during an
// Import call.
@@ -210,6 +214,8 @@ class TypeSourceInfo;
};
private:
+ FileIDImportHandlerType FileIDImportHandler;
+
std::shared_ptr<ASTImporterSharedState> SharedState = nullptr;
/// The path which we go through during the import of a given AST node.
@@ -232,6 +238,8 @@ class TypeSourceInfo;
/// Whether to perform a minimal import.
bool Minimal;
+ ODRHandlingType ODRHandling;
+
/// Whether the last diagnostic came from the "from" context.
bool LastDiagFromFrom = false;
@@ -310,10 +318,20 @@ class TypeSourceInfo;
virtual ~ASTImporter();
+ /// Set a callback function for FileID import handling.
+ /// The function is invoked when a FileID is imported from the From context.
+ /// The imported FileID in the To context and the original FileID in the
+ /// From context is passed to it.
+ void setFileIDImportHandler(FileIDImportHandlerType H) {
+ FileIDImportHandler = H;
+ }
+
/// Whether the importer will perform a minimal import, creating
/// to-be-completed forward declarations when possible.
bool isMinimalImport() const { return Minimal; }
+ void setODRHandling(ODRHandlingType T) { ODRHandling = T; }
+
/// \brief Import the given object, returns the result.
///
/// \param To Import the object into this variable.
@@ -366,6 +384,20 @@ class TypeSourceInfo;
/// imported. If it does not exist nullptr is returned.
TranslationUnitDecl *GetFromTU(Decl *ToD);
+ /// Return the declaration in the "from" context from which the declaration
+ /// in the "to" context was imported. If it was not imported or of the wrong
+ /// type a null value is returned.
+ template <typename DeclT>
+ llvm::Optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
+ auto FromI = ImportedFromDecls.find(ToD);
+ if (FromI == ImportedFromDecls.end())
+ return {};
+ auto *FromD = dyn_cast<DeclT>(FromI->second);
+ if (!FromD)
+ return {};
+ return FromD;
+ }
+
/// Import the given declaration context from the "from"
/// AST context into the "to" AST context.
///
@@ -491,12 +523,11 @@ class TypeSourceInfo;
///
/// \param NumDecls the number of conflicting declarations in \p Decls.
///
- /// \returns the name that the newly-imported declaration should have.
- virtual DeclarationName HandleNameConflict(DeclarationName Name,
- DeclContext *DC,
- unsigned IDNS,
- NamedDecl **Decls,
- unsigned NumDecls);
+ /// \returns the name that the newly-imported declaration should have. Or
+ /// an error if we can't handle the name conflict.
+ virtual Expected<DeclarationName>
+ HandleNameConflict(DeclarationName Name, DeclContext *DC, unsigned IDNS,
+ NamedDecl **Decls, unsigned NumDecls);
/// Retrieve the context that AST nodes are being imported into.
ASTContext &getToContext() const { return ToContext; }
diff --git a/include/clang/AST/ASTImporterSharedState.h b/include/clang/AST/ASTImporterSharedState.h
index 3635a62deef0..829eb1c611c3 100644
--- a/include/clang/AST/ASTImporterSharedState.h
+++ b/include/clang/AST/ASTImporterSharedState.h
@@ -47,7 +47,7 @@ public:
ASTImporterSharedState() = default;
ASTImporterSharedState(TranslationUnitDecl &ToTU) {
- LookupTable = llvm::make_unique<ASTImporterLookupTable>(ToTU);
+ LookupTable = std::make_unique<ASTImporterLookupTable>(ToTU);
}
ASTImporterLookupTable *getLookupTable() { return LookupTable.get(); }
diff --git a/include/clang/AST/ASTNodeTraverser.h b/include/clang/AST/ASTNodeTraverser.h
index e43eacef86c6..0bb2aad553fb 100644
--- a/include/clang/AST/ASTNodeTraverser.h
+++ b/include/clang/AST/ASTNodeTraverser.h
@@ -237,6 +237,9 @@ public:
for (const auto &TP : *TPL)
Visit(TP);
+
+ if (const Expr *RC = TPL->getRequiresClause())
+ Visit(RC);
}
void
diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h
index 70e0daa08a9a..36a42070fd28 100644
--- a/include/clang/AST/ASTStructuralEquivalence.h
+++ b/include/clang/AST/ASTStructuralEquivalence.h
@@ -18,7 +18,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
-#include <deque>
+#include <queue>
#include <utility>
namespace clang {
@@ -42,14 +42,13 @@ struct StructuralEquivalenceContext {
/// AST contexts for which we are checking structural equivalence.
ASTContext &FromCtx, &ToCtx;
- /// The set of "tentative" equivalences between two canonical
- /// declarations, mapping from a declaration in the first context to the
- /// declaration in the second context that we believe to be equivalent.
- llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
+ // Queue of from-to Decl pairs that are to be checked to determine the final
+ // result of equivalence of a starting Decl pair.
+ std::queue<std::pair<Decl *, Decl *>> DeclsToCheck;
- /// Queue of declarations in the first context whose equivalence
- /// with a declaration in the second context still needs to be verified.
- std::deque<Decl *> DeclsToCheck;
+ // Set of from-to Decl pairs that are already visited during the check
+ // (are in or were once in \c DeclsToCheck) of a starting Decl pair.
+ llvm::DenseSet<std::pair<Decl *, Decl *>> VisitedDecls;
/// Declaration (from, to) pairs that are known not to be equivalent
/// (which we have already complained about).
@@ -88,14 +87,14 @@ struct StructuralEquivalenceContext {
/// Implementation functions (all static functions in
/// ASTStructuralEquivalence.cpp) must never call this function because that
/// will wreak havoc the internal state (\c DeclsToCheck and
- /// \c TentativeEquivalences members) and can cause faulty equivalent results.
+ /// \c VisitedDecls members) and can cause faulty equivalent results.
bool IsEquivalent(Decl *D1, Decl *D2);
/// Determine whether the two types are structurally equivalent.
/// Implementation functions (all static functions in
/// ASTStructuralEquivalence.cpp) must never call this function because that
/// will wreak havoc the internal state (\c DeclsToCheck and
- /// \c TentativeEquivalences members) and can cause faulty equivalent results.
+ /// \c VisitedDecls members) and can cause faulty equivalent results.
bool IsEquivalent(QualType T1, QualType T2);
/// Find the index of the given anonymous struct/union within its
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index a29a04e5d242..dd4ead2f0c2b 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -148,7 +148,7 @@ private:
#include "clang/AST/StmtNodes.inc"
NKI_Type,
#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
NKI_OMPClause,
#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class,
#include "clang/Basic/OpenMPKinds.def"
@@ -205,7 +205,7 @@ KIND_TO_KIND_ID(OMPClause)
#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"
+#include "clang/AST/TypeNodes.inc"
#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class)
#include "clang/Basic/OpenMPKinds.def"
#undef KIND_TO_KIND_ID
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 1fbed7ceebfa..d315dde6ed45 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -19,6 +19,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
+#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/Sanitizers.h"
@@ -32,6 +33,7 @@
namespace clang {
class ASTContext;
+ class AttributeCommonInfo;
class IdentifierInfo;
class ObjCInterfaceDecl;
class Expr;
@@ -40,84 +42,79 @@ namespace clang {
class TypeSourceInfo;
/// Attr - This represents one attribute.
-class Attr {
-private:
- SourceRange Range;
- unsigned AttrKind : 16;
-
-protected:
- /// An index into the spelling list of an
- /// attribute defined in Attr.td file.
- unsigned SpellingListIndex : 4;
- unsigned Inherited : 1;
- unsigned IsPackExpansion : 1;
- unsigned Implicit : 1;
- // FIXME: These are properties of the attribute kind, not state for this
- // instance of the attribute.
- unsigned IsLateParsed : 1;
- unsigned InheritEvenIfAlreadyPresent : 1;
-
- void *operator new(size_t bytes) noexcept {
- llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
- }
- void operator delete(void *data) noexcept {
- llvm_unreachable("Attrs cannot be released with regular 'delete'.");
- }
-
-public:
- // Forward so that the regular new and delete do not hide global ones.
- void *operator new(size_t Bytes, ASTContext &C,
- size_t Alignment = 8) noexcept {
- return ::operator new(Bytes, C, Alignment);
- }
- void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
- return ::operator delete(Ptr, C, Alignment);
- }
+ class Attr : public AttributeCommonInfo {
+ private:
+ unsigned AttrKind : 16;
+
+ protected:
+ /// An index into the spelling list of an
+ /// attribute defined in Attr.td file.
+ unsigned Inherited : 1;
+ unsigned IsPackExpansion : 1;
+ unsigned Implicit : 1;
+ // FIXME: These are properties of the attribute kind, not state for this
+ // instance of the attribute.
+ unsigned IsLateParsed : 1;
+ unsigned InheritEvenIfAlreadyPresent : 1;
+
+ void *operator new(size_t bytes) noexcept {
+ llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
+ }
+ void operator delete(void *data) noexcept {
+ llvm_unreachable("Attrs cannot be released with regular 'delete'.");
+ }
-protected:
- Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed)
- : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
- Inherited(false), IsPackExpansion(false), Implicit(false),
- IsLateParsed(IsLateParsed), InheritEvenIfAlreadyPresent(false) {}
+ public:
+ // Forward so that the regular new and delete do not hide global ones.
+ void *operator new(size_t Bytes, ASTContext &C,
+ size_t Alignment = 8) noexcept {
+ return ::operator new(Bytes, C, Alignment);
+ }
+ void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
+ return ::operator delete(Ptr, C, Alignment);
+ }
-public:
+ protected:
+ Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
+ attr::Kind AK, bool IsLateParsed)
+ : AttributeCommonInfo(CommonInfo), AttrKind(AK), Inherited(false),
+ IsPackExpansion(false), Implicit(false), IsLateParsed(IsLateParsed),
+ InheritEvenIfAlreadyPresent(false) {}
- attr::Kind getKind() const {
- return static_cast<attr::Kind>(AttrKind);
- }
+ public:
+ attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); }
- unsigned getSpellingListIndex() const { return SpellingListIndex; }
- const char *getSpelling() const;
+ unsigned getSpellingListIndex() const {
+ return getAttributeSpellingListIndex();
+ }
+ const char *getSpelling() const;
- SourceLocation getLocation() const { return Range.getBegin(); }
- SourceRange getRange() const { return Range; }
- void setRange(SourceRange R) { Range = R; }
+ SourceLocation getLocation() const { return getRange().getBegin(); }
- bool isInherited() const { return Inherited; }
+ bool isInherited() const { return Inherited; }
- /// Returns true if the attribute has been implicitly created instead
- /// of explicitly written by the user.
- bool isImplicit() const { return Implicit; }
- void setImplicit(bool I) { Implicit = I; }
+ /// Returns true if the attribute has been implicitly created instead
+ /// of explicitly written by the user.
+ bool isImplicit() const { return Implicit; }
+ void setImplicit(bool I) { Implicit = I; }
- void setPackExpansion(bool PE) { IsPackExpansion = PE; }
- bool isPackExpansion() const { return IsPackExpansion; }
+ void setPackExpansion(bool PE) { IsPackExpansion = PE; }
+ bool isPackExpansion() const { return IsPackExpansion; }
- // Clone this attribute.
- Attr *clone(ASTContext &C) const;
+ // Clone this attribute.
+ Attr *clone(ASTContext &C) const;
- bool isLateParsed() const { return IsLateParsed; }
+ bool isLateParsed() const { return IsLateParsed; }
- // Pretty print this attribute.
- void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
-};
+ // Pretty print this attribute.
+ void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
+ };
class TypeAttr : public Attr {
protected:
- TypeAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed)
- : Attr(AK, R, SpellingListIndex, IsLateParsed) {}
+ TypeAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
+ attr::Kind AK, bool IsLateParsed)
+ : Attr(Context, CommonInfo, AK, IsLateParsed) {}
public:
static bool classof(const Attr *A) {
@@ -128,9 +125,9 @@ public:
class StmtAttr : public Attr {
protected:
- StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed)
- : Attr(AK, R, SpellingListIndex, IsLateParsed) {}
+ StmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
+ attr::Kind AK, bool IsLateParsed)
+ : Attr(Context, CommonInfo, AK, IsLateParsed) {}
public:
static bool classof(const Attr *A) {
@@ -141,9 +138,10 @@ public:
class InheritableAttr : public Attr {
protected:
- InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
- : Attr(AK, R, SpellingListIndex, IsLateParsed) {
+ InheritableAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
+ attr::Kind AK, bool IsLateParsed,
+ bool InheritEvenIfAlreadyPresent)
+ : Attr(Context, CommonInfo, AK, IsLateParsed) {
this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
}
@@ -165,9 +163,10 @@ public:
class InheritableParamAttr : public InheritableAttr {
protected:
- InheritableParamAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
+ InheritableParamAttr(ASTContext &Context,
+ const AttributeCommonInfo &CommonInfo, attr::Kind AK,
bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
- : InheritableAttr(AK, R, SpellingListIndex, IsLateParsed,
+ : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
InheritEvenIfAlreadyPresent) {}
public:
@@ -182,11 +181,11 @@ public:
/// for the parameter.
class ParameterABIAttr : public InheritableParamAttr {
protected:
- ParameterABIAttr(attr::Kind AK, SourceRange R,
- unsigned SpellingListIndex, bool IsLateParsed,
+ ParameterABIAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
+ attr::Kind AK, bool IsLateParsed,
bool InheritEvenIfAlreadyPresent)
- : InheritableParamAttr(AK, R, SpellingListIndex, IsLateParsed,
- InheritEvenIfAlreadyPresent) {}
+ : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed,
+ InheritEvenIfAlreadyPresent) {}
public:
ParameterABI getABI() const {
diff --git a/include/clang/AST/CXXRecordDeclDefinitionBits.def b/include/clang/AST/CXXRecordDeclDefinitionBits.def
new file mode 100644
index 000000000000..bd4d8247aeca
--- /dev/null
+++ b/include/clang/AST/CXXRecordDeclDefinitionBits.def
@@ -0,0 +1,236 @@
+//===-- CXXRecordDeclDefinitionBits.def - Class definition bits -*- 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 enumerates the various bitfields that we want to store on C++ class
+// definitions.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file CXXRecordDeclDefinitionBits.def
+///
+/// In this file, each of the bitfields representing data about a C++ class
+/// results in an expansion of the FIELD macro, which should be defined before
+/// including this file.
+///
+/// The macro have three operands:
+///
+/// Name: The name of the field, as a member of CXXRecordDecl::DefinitionData.
+///
+/// BitWidth: The width of the field in bits.
+///
+/// MergePolicy: How to behave when the value of the field is different in
+/// multiple translation units, one of:
+/// NO_MERGE: It is an ODR violation if the fields do not match.
+/// MERGE_OR: Merge the fields by ORing them together.
+
+#ifndef FIELD
+#error define FIELD before including this file
+#endif
+
+/// True if this class has any user-declared constructors.
+FIELD(UserDeclaredConstructor, 1, NO_MERGE)
+
+/// The user-declared special members which this class has.
+FIELD(UserDeclaredSpecialMembers, 6, NO_MERGE)
+
+/// True when this class is an aggregate.
+FIELD(Aggregate, 1, NO_MERGE)
+
+/// True when this class is a POD-type.
+FIELD(PlainOldData, 1, NO_MERGE)
+
+/// 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.
+FIELD(Empty, 1, NO_MERGE)
+
+/// True when this class is polymorphic, i.e., has at
+/// least one virtual member or derives from a polymorphic class.
+FIELD(Polymorphic, 1, NO_MERGE)
+
+/// True when this class is abstract, i.e., has at least
+/// one pure virtual function, (that can come from a base class).
+FIELD(Abstract, 1, NO_MERGE)
+
+/// True when this class is standard-layout, per the applicable
+/// language rules (including DRs).
+FIELD(IsStandardLayout, 1, NO_MERGE)
+
+/// True when this class was standard-layout under the C++11
+/// definition.
+///
+/// C++11 [class]p7. A standard-layout class is a class that:
+/// * has no non-static data members of type non-standard-layout class (or
+/// array of such types) or reference,
+/// * has no virtual functions (10.3) and no virtual base classes (10.1),
+/// * has the same access control (Clause 11) for all non-static data
+/// members
+/// * has no non-standard-layout base classes,
+/// * either has no non-static data members in the most derived class and at
+/// most one base class with non-static data members, or has no base
+/// classes with non-static data members, and
+/// * has no base classes of the same type as the first non-static data
+/// member.
+FIELD(IsCXX11StandardLayout, 1, NO_MERGE)
+
+/// True when any base class has any declared non-static data
+/// members or bit-fields.
+/// This is a helper bit of state used to implement IsStandardLayout more
+/// efficiently.
+FIELD(HasBasesWithFields, 1, NO_MERGE)
+
+/// True when any base class has any declared non-static data
+/// members.
+/// This is a helper bit of state used to implement IsCXX11StandardLayout
+/// more efficiently.
+FIELD(HasBasesWithNonStaticDataMembers, 1, NO_MERGE)
+
+/// True when there are private non-static data members.
+FIELD(HasPrivateFields, 1, NO_MERGE)
+
+/// True when there are protected non-static data members.
+FIELD(HasProtectedFields, 1, NO_MERGE)
+
+/// True when there are private non-static data members.
+FIELD(HasPublicFields, 1, NO_MERGE)
+
+/// True if this class (or any subobject) has mutable fields.
+FIELD(HasMutableFields, 1, NO_MERGE)
+
+/// True if this class (or any nested anonymous struct or union)
+/// has variant members.
+FIELD(HasVariantMembers, 1, NO_MERGE)
+
+/// True if there no non-field members declared by the user.
+FIELD(HasOnlyCMembers, 1, NO_MERGE)
+
+/// True if any field has an in-class initializer, including those
+/// within anonymous unions or structs.
+FIELD(HasInClassInitializer, 1, NO_MERGE)
+
+/// True if any field is of reference type, and does not have an
+/// in-class initializer.
+///
+/// In this case, value-initialization of this class is illegal in C++98
+/// even if the class has a trivial default constructor.
+FIELD(HasUninitializedReferenceMember, 1, NO_MERGE)
+
+/// True if any non-mutable field whose type doesn't have a user-
+/// provided default ctor also doesn't have an in-class initializer.
+FIELD(HasUninitializedFields, 1, NO_MERGE)
+
+/// True if there are any member using-declarations that inherit
+/// constructors from a base class.
+FIELD(HasInheritedConstructor, 1, NO_MERGE)
+
+/// True if there are any member using-declarations named
+/// 'operator='.
+FIELD(HasInheritedAssignment, 1, NO_MERGE)
+
+/// These flags are \c true if a defaulted corresponding special
+/// member can't be fully analyzed without performing overload resolution.
+/// @{
+FIELD(NeedOverloadResolutionForCopyConstructor, 1, NO_MERGE)
+FIELD(NeedOverloadResolutionForMoveConstructor, 1, NO_MERGE)
+FIELD(NeedOverloadResolutionForMoveAssignment, 1, NO_MERGE)
+FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE)
+/// @}
+
+/// These flags are \c true if an implicit defaulted corresponding
+/// special member would be defined as deleted.
+/// @{
+FIELD(DefaultedCopyConstructorIsDeleted, 1, NO_MERGE)
+FIELD(DefaultedMoveConstructorIsDeleted, 1, NO_MERGE)
+FIELD(DefaultedMoveAssignmentIsDeleted, 1, NO_MERGE)
+FIELD(DefaultedDestructorIsDeleted, 1, NO_MERGE)
+/// @}
+
+/// The trivial special members which this class has, per
+/// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25,
+/// C++11 [class.dtor]p5, or would have if the member were not suppressed.
+///
+/// This excludes any user-declared but not user-provided special members
+/// which have been declared but not yet defined.
+FIELD(HasTrivialSpecialMembers, 6, MERGE_OR)
+
+/// These bits keep track of the triviality of special functions for the
+/// purpose of calls. Only the bits corresponding to SMF_CopyConstructor,
+/// SMF_MoveConstructor, and SMF_Destructor are meaningful here.
+FIELD(HasTrivialSpecialMembersForCall, 6, MERGE_OR)
+
+/// The declared special members of this class which are known to be
+/// non-trivial.
+///
+/// This excludes any user-declared but not user-provided special members
+/// which have been declared but not yet defined, and any implicit special
+/// members which have not yet been declared.
+FIELD(DeclaredNonTrivialSpecialMembers, 6, MERGE_OR)
+
+/// These bits keep track of the declared special members that are
+/// non-trivial for the purpose of calls.
+/// Only the bits corresponding to SMF_CopyConstructor,
+/// SMF_MoveConstructor, and SMF_Destructor are meaningful here.
+FIELD(DeclaredNonTrivialSpecialMembersForCall, 6, MERGE_OR)
+
+/// True when this class has a destructor with no semantic effect.
+FIELD(HasIrrelevantDestructor, 1, NO_MERGE)
+
+/// True when this class has at least one user-declared constexpr
+/// constructor which is neither the copy nor move constructor.
+FIELD(HasConstexprNonCopyMoveConstructor, 1, MERGE_OR)
+
+/// True if this class has a (possibly implicit) defaulted default
+/// constructor.
+FIELD(HasDefaultedDefaultConstructor, 1, MERGE_OR)
+
+/// True if a defaulted default constructor for this class would
+/// be constexpr.
+FIELD(DefaultedDefaultConstructorIsConstexpr, 1, NO_MERGE)
+
+/// True if this class has a constexpr default constructor.
+///
+/// This is true for either a user-declared constexpr default constructor
+/// or an implicitly declared constexpr default constructor.
+FIELD(HasConstexprDefaultConstructor, 1, MERGE_OR)
+
+/// True if a defaulted destructor for this class would be constexpr.
+FIELD(DefaultedDestructorIsConstexpr, 1, NO_MERGE)
+
+/// True when this class contains at least one non-static data
+/// member or base class of non-literal or volatile type.
+FIELD(HasNonLiteralTypeFieldsOrBases, 1, NO_MERGE)
+
+/// Whether we have a C++11 user-provided default constructor (not
+/// explicitly deleted or defaulted).
+FIELD(UserProvidedDefaultConstructor, 1, NO_MERGE)
+
+/// The special members which have been declared for this class,
+/// either by the user or implicitly.
+FIELD(DeclaredSpecialMembers, 6, MERGE_OR)
+
+/// Whether an implicit copy constructor could have a const-qualified
+/// parameter, for initializing virtual bases and for other subobjects.
+FIELD(ImplicitCopyConstructorCanHaveConstParamForVBase, 1, NO_MERGE)
+FIELD(ImplicitCopyConstructorCanHaveConstParamForNonVBase, 1, NO_MERGE)
+
+/// Whether an implicit copy assignment operator would have a
+/// const-qualified parameter.
+FIELD(ImplicitCopyAssignmentHasConstParam, 1, NO_MERGE)
+
+/// Whether any declared copy constructor has a const-qualified
+/// parameter.
+FIELD(HasDeclaredCopyConstructorWithConstParam, 1, MERGE_OR)
+
+/// Whether any declared copy assignment operator has either a
+/// const-qualified reference parameter or a non-reference parameter.
+FIELD(HasDeclaredCopyAssignmentWithConstParam, 1, MERGE_OR)
+
+#undef FIELD
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 37f489c7708a..f14d3abf71e5 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -14,6 +14,7 @@
#define LLVM_CLANG_AST_CHARUNITS_H
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/Alignment.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
@@ -177,6 +178,10 @@ namespace clang {
/// getQuantity - Get the raw integer representation of this quantity.
QuantityType getQuantity() const { return Quantity; }
+ /// getAsAlign - Returns Quantity as a valid llvm::Align,
+ /// Beware llvm::Align assumes power of two 8-bit bytes.
+ llvm::Align getAsAlign() const { return llvm::Align(Quantity); }
+
/// alignTo - Returns the next integer (mod 2**64) that is
/// greater than or equal to this quantity and is a multiple of \p Align.
/// Align must be non-zero.
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
index 958ee032e71f..3b0d1603d407 100644
--- a/include/clang/AST/CommentCommands.td
+++ b/include/clang/AST/CommentCommands.td
@@ -139,6 +139,7 @@ def Post : BlockCommand<"post">;
def Pre : BlockCommand<"pre">;
def Remark : BlockCommand<"remark">;
def Remarks : BlockCommand<"remarks">;
+def Retval : BlockCommand<"retval">;
def Sa : BlockCommand<"sa">;
def See : BlockCommand<"see">;
def Since : BlockCommand<"since">;
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index 9ddbb7d31d99..138fdaca0ff6 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -352,8 +352,7 @@ public:
void lex(Token &T);
- StringRef getSpelling(const Token &Tok, const SourceManager &SourceMgr,
- bool *Invalid = nullptr) const;
+ StringRef getSpelling(const Token &Tok, const SourceManager &SourceMgr) const;
};
} // end namespace comments
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 02742801f37c..ce674e09c44d 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -310,6 +310,14 @@ public:
void printQualifiedName(raw_ostream &OS) const;
void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
+ /// Print only the nested name specifier part of a fully-qualified name,
+ /// including the '::' at the end. E.g.
+ /// when `printQualifiedName(D)` prints "A::B::i",
+ /// this function prints "A::B::".
+ void printNestedNameSpecifier(raw_ostream &OS) const;
+ void printNestedNameSpecifier(raw_ostream &OS,
+ const PrintingPolicy &Policy) const;
+
// FIXME: Remove string version.
std::string getQualifiedNameAsString() const;
@@ -800,12 +808,19 @@ struct EvaluatedStmt {
/// valid if CheckedICE is true.
bool IsICE : 1;
+ /// Whether this variable is known to have constant destruction. That is,
+ /// whether running the destructor on the initial value is a side-effect
+ /// (and doesn't inspect any state that might have changed during program
+ /// execution). This is currently only computed if the destructor is
+ /// non-trivial.
+ bool HasConstantDestruction : 1;
+
Stmt *Value;
APValue Evaluated;
- EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
- CheckingICE(false), IsICE(false) {}
-
+ EvaluatedStmt()
+ : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
+ CheckingICE(false), IsICE(false), HasConstantDestruction(false) {}
};
/// Represents a variable declaration or definition.
@@ -1226,6 +1241,14 @@ public:
void setInit(Expr *I);
+ /// Get the initializing declaration of this variable, if any. This is
+ /// usually the definition, except that for a static data member it can be
+ /// the in-class declaration.
+ VarDecl *getInitializingDeclaration();
+ const VarDecl *getInitializingDeclaration() const {
+ return const_cast<VarDecl *>(this)->getInitializingDeclaration();
+ }
+
/// 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
@@ -1251,6 +1274,14 @@ public:
/// to untyped APValue if the value could not be evaluated.
APValue *getEvaluatedValue() const;
+ /// Evaluate the destruction of this variable to determine if it constitutes
+ /// constant destruction.
+ ///
+ /// \pre isInitICE()
+ /// \return \c true if this variable has constant destruction, \c false if
+ /// not.
+ bool evaluateDestruction(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+
/// Determines whether it is already known whether the
/// initializer is an integral constant expression or not.
bool isInitKnownICE() const;
@@ -1489,9 +1520,14 @@ public:
// has no definition within this source file.
bool isKnownToBeDefined() const;
- /// Do we need to emit an exit-time destructor for this variable?
+ /// Is destruction of this variable entirely suppressed? If so, the variable
+ /// need not have a usable destructor at all.
bool isNoDestroy(const ASTContext &) const;
+ /// Do we need to emit an exit-time destructor for this variable, and if so,
+ /// what kind?
+ QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
@@ -4078,13 +4114,9 @@ public:
void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures,
bool CapturesCXXThis);
- unsigned getBlockManglingNumber() const {
- return ManglingNumber;
- }
+ unsigned getBlockManglingNumber() const { return ManglingNumber; }
- Decl *getBlockManglingContextDecl() const {
- return ManglingContextDecl;
- }
+ Decl *getBlockManglingContextDecl() const { return ManglingContextDecl; }
void setBlockMangling(unsigned Number, Decl *Ctx) {
ManglingNumber = Number;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index d64d0cb425db..01c2f1809771 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -959,7 +959,7 @@ public:
/// as this declaration, or NULL if there is no previous declaration.
Decl *getPreviousDecl() { return getPreviousDeclImpl(); }
- /// Retrieve the most recent declaration that declares the same entity
+ /// Retrieve the previous declaration that declares the same entity
/// as this declaration, or NULL if there is no previous declaration.
const Decl *getPreviousDecl() const {
return const_cast<Decl *>(this)->getPreviousDeclImpl();
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 7add83f89624..66212f72b787 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -42,6 +42,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
@@ -73,52 +74,6 @@ class TemplateDecl;
class TemplateParameterList;
class UsingDecl;
-/// Represents any kind of function declaration, whether it is a
-/// concrete function or a function template.
-class AnyFunctionDecl {
- NamedDecl *Function;
-
- AnyFunctionDecl(NamedDecl *ND) : Function(ND) {}
-
-public:
- AnyFunctionDecl(FunctionDecl *FD) : Function(FD) {}
- AnyFunctionDecl(FunctionTemplateDecl *FTD);
-
- /// Implicily converts any function or function template into a
- /// named declaration.
- operator NamedDecl *() const { return Function; }
-
- /// Retrieve the underlying function or function template.
- NamedDecl *get() const { return Function; }
-
- static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
- return AnyFunctionDecl(ND);
- }
-};
-
-} // namespace clang
-
-namespace llvm {
-
- // Provide PointerLikeTypeTraits for non-cvr pointers.
- template<>
- struct PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
- static void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
- return F.get();
- }
-
- static ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
- return ::clang::AnyFunctionDecl::getFromNamedDecl(
- static_cast< ::clang::NamedDecl*>(P));
- }
-
- enum { NumLowBitsAvailable = 2 };
- };
-
-} // namespace llvm
-
-namespace clang {
-
/// Represents an access specifier followed by colon ':'.
///
/// An objects of this class represents sugar for the syntactic occurrence
@@ -322,207 +277,9 @@ class CXXRecordDecl : public RecordDecl {
};
struct DefinitionData {
- /// True if this class has any user-declared constructors.
- unsigned UserDeclaredConstructor : 1;
-
- /// The user-declared special members which this class has.
- unsigned UserDeclaredSpecialMembers : 6;
-
- /// True when this class is an aggregate.
- unsigned Aggregate : 1;
-
- /// True when this class is a POD-type.
- unsigned PlainOldData : 1;
-
- /// 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
- /// least one virtual member or derives from a polymorphic class.
- unsigned Polymorphic : 1;
-
- /// True when this class is abstract, i.e., has at least
- /// one pure virtual function, (that can come from a base class).
- unsigned Abstract : 1;
-
- /// True when this class is standard-layout, per the applicable
- /// language rules (including DRs).
- unsigned IsStandardLayout : 1;
-
- /// True when this class was standard-layout under the C++11
- /// definition.
- ///
- /// C++11 [class]p7. A standard-layout class is a class that:
- /// * has no non-static data members of type non-standard-layout class (or
- /// array of such types) or reference,
- /// * has no virtual functions (10.3) and no virtual base classes (10.1),
- /// * has the same access control (Clause 11) for all non-static data
- /// members
- /// * has no non-standard-layout base classes,
- /// * either has no non-static data members in the most derived class and at
- /// most one base class with non-static data members, or has no base
- /// classes with non-static data members, and
- /// * has no base classes of the same type as the first non-static data
- /// member.
- unsigned IsCXX11StandardLayout : 1;
-
- /// True when any base class has any declared non-static data
- /// members or bit-fields.
- /// This is a helper bit of state used to implement IsStandardLayout more
- /// efficiently.
- unsigned HasBasesWithFields : 1;
-
- /// True when any base class has any declared non-static data
- /// members.
- /// This is a helper bit of state used to implement IsCXX11StandardLayout
- /// more efficiently.
- unsigned HasBasesWithNonStaticDataMembers : 1;
-
- /// True when there are private non-static data members.
- unsigned HasPrivateFields : 1;
-
- /// True when there are protected non-static data members.
- unsigned HasProtectedFields : 1;
-
- /// True when there are private non-static data members.
- unsigned HasPublicFields : 1;
-
- /// True if this class (or any subobject) has mutable fields.
- unsigned HasMutableFields : 1;
-
- /// True if this class (or any nested anonymous struct or union)
- /// has variant members.
- unsigned HasVariantMembers : 1;
-
- /// True if there no non-field members declared by the user.
- unsigned HasOnlyCMembers : 1;
-
- /// True if any field has an in-class initializer, including those
- /// within anonymous unions or structs.
- unsigned HasInClassInitializer : 1;
-
- /// True if any field is of reference type, and does not have an
- /// in-class initializer.
- ///
- /// In this case, value-initialization of this class is illegal in C++98
- /// even if the class has a trivial default constructor.
- unsigned HasUninitializedReferenceMember : 1;
-
- /// True if any non-mutable field whose type doesn't have a user-
- /// provided default ctor also doesn't have an in-class initializer.
- unsigned HasUninitializedFields : 1;
-
- /// True if there are any member using-declarations that inherit
- /// constructors from a base class.
- unsigned HasInheritedConstructor : 1;
-
- /// True if there are any member using-declarations named
- /// 'operator='.
- unsigned HasInheritedAssignment : 1;
-
- /// These flags are \c true if a defaulted corresponding special
- /// member can't be fully analyzed without performing overload resolution.
- /// @{
- unsigned NeedOverloadResolutionForCopyConstructor : 1;
- unsigned NeedOverloadResolutionForMoveConstructor : 1;
- unsigned NeedOverloadResolutionForMoveAssignment : 1;
- unsigned NeedOverloadResolutionForDestructor : 1;
- /// @}
-
- /// These flags are \c true if an implicit defaulted corresponding
- /// special member would be defined as deleted.
- /// @{
- unsigned DefaultedCopyConstructorIsDeleted : 1;
- unsigned DefaultedMoveConstructorIsDeleted : 1;
- unsigned DefaultedMoveAssignmentIsDeleted : 1;
- unsigned DefaultedDestructorIsDeleted : 1;
- /// @}
-
- /// The trivial special members which this class has, per
- /// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25,
- /// C++11 [class.dtor]p5, or would have if the member were not suppressed.
- ///
- /// This excludes any user-declared but not user-provided special members
- /// which have been declared but not yet defined.
- unsigned HasTrivialSpecialMembers : 6;
-
- /// These bits keep track of the triviality of special functions for the
- /// purpose of calls. Only the bits corresponding to SMF_CopyConstructor,
- /// SMF_MoveConstructor, and SMF_Destructor are meaningful here.
- unsigned HasTrivialSpecialMembersForCall : 6;
-
- /// The declared special members of this class which are known to be
- /// non-trivial.
- ///
- /// This excludes any user-declared but not user-provided special members
- /// which have been declared but not yet defined, and any implicit special
- /// members which have not yet been declared.
- unsigned DeclaredNonTrivialSpecialMembers : 6;
-
- /// These bits keep track of the declared special members that are
- /// non-trivial for the purpose of calls.
- /// Only the bits corresponding to SMF_CopyConstructor,
- /// SMF_MoveConstructor, and SMF_Destructor are meaningful here.
- unsigned DeclaredNonTrivialSpecialMembersForCall : 6;
-
- /// True when this class has a destructor with no semantic effect.
- unsigned HasIrrelevantDestructor : 1;
-
- /// True when this class has at least one user-declared constexpr
- /// constructor which is neither the copy nor move constructor.
- unsigned HasConstexprNonCopyMoveConstructor : 1;
-
- /// True if this class has a (possibly implicit) defaulted default
- /// constructor.
- unsigned HasDefaultedDefaultConstructor : 1;
-
- /// True if a defaulted default constructor for this class would
- /// be constexpr.
- unsigned DefaultedDefaultConstructorIsConstexpr : 1;
-
- /// True if this class has a constexpr default constructor.
- ///
- /// This is true for either a user-declared constexpr default constructor
- /// or an implicitly declared constexpr default constructor.
- unsigned HasConstexprDefaultConstructor : 1;
-
- /// True when this class contains at least one non-static data
- /// member or base class of non-literal or volatile type.
- unsigned HasNonLiteralTypeFieldsOrBases : 1;
-
- /// True when visible conversion functions are already computed
- /// and are available.
- unsigned ComputedVisibleConversions : 1;
-
- /// Whether we have a C++11 user-provided default constructor (not
- /// explicitly deleted or defaulted).
- unsigned UserProvidedDefaultConstructor : 1;
-
- /// The special members which have been declared for this class,
- /// either by the user or implicitly.
- unsigned DeclaredSpecialMembers : 6;
-
- /// Whether an implicit copy constructor could have a const-qualified
- /// parameter, for initializing virtual bases and for other subobjects.
- unsigned ImplicitCopyConstructorCanHaveConstParamForVBase : 1;
- unsigned ImplicitCopyConstructorCanHaveConstParamForNonVBase : 1;
-
- /// Whether an implicit copy assignment operator would have a
- /// const-qualified parameter.
- unsigned ImplicitCopyAssignmentHasConstParam : 1;
-
- /// Whether any declared copy constructor has a const-qualified
- /// parameter.
- unsigned HasDeclaredCopyConstructorWithConstParam : 1;
-
- /// Whether any declared copy assignment operator has either a
- /// const-qualified reference parameter or a non-reference parameter.
- unsigned HasDeclaredCopyAssignmentWithConstParam : 1;
+ #define FIELD(Name, Width, Merge) \
+ unsigned Name : Width;
+ #include "CXXRecordDeclDefinitionBits.def"
/// Whether this class describes a C++ lambda.
unsigned IsLambda : 1;
@@ -530,6 +287,10 @@ class CXXRecordDecl : public RecordDecl {
/// Whether we are currently parsing base specifiers.
unsigned IsParsingBaseSpecifiers : 1;
+ /// True when visible conversion functions are already computed
+ /// and are available.
+ unsigned ComputedVisibleConversions : 1;
+
unsigned HasODRHash : 1;
/// A hash of parts of the class to help in ODR checking.
@@ -628,9 +389,12 @@ class CXXRecordDecl : public RecordDecl {
/// The number of explicit captures in this lambda.
unsigned NumExplicitCaptures : 13;
+ /// Has known `internal` linkage.
+ unsigned HasKnownInternalLinkage : 1;
+
/// The number used to indicate this lambda expression for name
/// mangling in the Itanium C++ ABI.
- unsigned ManglingNumber = 0;
+ unsigned ManglingNumber : 31;
/// The declaration that provides context for this lambda, if the
/// actual DeclContext does not suffice. This is used for lambdas that
@@ -645,12 +409,12 @@ class CXXRecordDecl : public RecordDecl {
/// The type of the call method.
TypeSourceInfo *MethodTyInfo;
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
- bool Dependent, bool IsGeneric,
- LambdaCaptureDefault CaptureDefault)
- : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
- CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0),
- MethodTyInfo(Info) {
+ LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent,
+ bool IsGeneric, LambdaCaptureDefault CaptureDefault)
+ : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
+ CaptureDefault(CaptureDefault), NumCaptures(0),
+ NumExplicitCaptures(0), HasKnownInternalLinkage(0), ManglingNumber(0),
+ MethodTyInfo(Info) {
IsLambda = true;
// C++1z [expr.prim.lambda]p4:
@@ -1214,6 +978,10 @@ public:
/// if this is a closure type.
CXXMethodDecl *getLambdaCallOperator() const;
+ /// Retrieve the dependent lambda call operator of the closure type
+ /// if this is a templated closure type.
+ FunctionTemplateDecl *getDependentLambdaCallOperator() const;
+
/// Retrieve the lambda static invoker, the address of which
/// is returned by the conversion operator, and the body of which
/// is forwarded to the lambda call operator.
@@ -1398,7 +1166,8 @@ public:
/// would be constexpr.
bool defaultedDefaultConstructorIsConstexpr() const {
return data().DefaultedDefaultConstructorIsConstexpr &&
- (!isUnion() || hasInClassInitializer() || !hasVariantMembers());
+ (!isUnion() || hasInClassInitializer() || !hasVariantMembers() ||
+ getASTContext().getLangOpts().CPlusPlus2a);
}
/// Determine whether this class has a constexpr default constructor.
@@ -1486,6 +1255,16 @@ public:
!(data().HasTrivialSpecialMembers & SMF_MoveAssignment));
}
+ /// Determine whether a defaulted default constructor for this class
+ /// would be constexpr.
+ bool defaultedDestructorIsConstexpr() const {
+ return data().DefaultedDestructorIsConstexpr &&
+ getASTContext().getLangOpts().CPlusPlus2a;
+ }
+
+ /// Determine whether this class has a constexpr destructor.
+ bool hasConstexprDestructor() const;
+
/// Determine whether this class has a trivial destructor
/// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const {
@@ -1577,8 +1356,10 @@ public:
///
/// Only in C++17 and beyond, are lambdas literal types.
bool isLiteral() const {
- return hasTrivialDestructor() &&
- (!isLambda() || getASTContext().getLangOpts().CPlusPlus17) &&
+ ASTContext &Ctx = getASTContext();
+ return (Ctx.getLangOpts().CPlusPlus2a ? hasConstexprDestructor()
+ : hasTrivialDestructor()) &&
+ (!isLambda() || Ctx.getLangOpts().CPlusPlus17) &&
!hasNonLiteralTypeFieldsOrBases() &&
(isAggregate() || isLambda() ||
hasConstexprNonCopyMoveConstructor() ||
@@ -1927,6 +1708,13 @@ public:
return getLambdaData().ManglingNumber;
}
+ /// The lambda is known to has internal linkage no matter whether it has name
+ /// mangling number.
+ bool hasKnownLambdaInternalLinkage() const {
+ assert(isLambda() && "Not a lambda closure type!");
+ return getLambdaData().HasKnownInternalLinkage;
+ }
+
/// Retrieve the declaration that provides additional context for a
/// lambda, when the normal declaration context is not specific enough.
///
@@ -1940,9 +1728,12 @@ public:
/// Set the mangling number and context declaration for a lambda
/// class.
- void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl) {
+ void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl,
+ bool HasKnownInternalLinkage = false) {
+ assert(isLambda() && "Not a lambda closure type!");
getLambdaData().ManglingNumber = ManglingNumber;
getLambdaData().ContextDecl = ContextDecl;
+ getLambdaData().HasKnownInternalLinkage = HasKnownInternalLinkage;
}
/// Returns the inheritance model used for this record.
@@ -2265,7 +2056,7 @@ public:
const CXXRecordDecl *Decl);
Qualifiers getMethodQualifiers() const {
- return getType()->getAs<FunctionProtoType>()->getMethodQuals();
+ return getType()->castAs<FunctionProtoType>()->getMethodQuals();
}
/// Retrieve the ref-qualifier associated with this method.
@@ -2280,7 +2071,7 @@ public:
/// };
/// @endcode
RefQualifierKind getRefQualifier() const {
- return getType()->getAs<FunctionProtoType>()->getRefQualifier();
+ return getType()->castAs<FunctionProtoType>()->getRefQualifier();
}
bool hasInlineBody() const;
@@ -2600,9 +2391,9 @@ class CXXConstructorDecl final
ExplicitSpecifier getExplicitSpecifierInternal() const {
if (CXXConstructorDeclBits.HasTrailingExplicitSpecifier)
- return *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>();
+ return *getTrailingObjects<ExplicitSpecifier>();
return ExplicitSpecifier(
- nullptr, getCanonicalDecl()->CXXConstructorDeclBits.IsSimpleExplicit
+ nullptr, CXXConstructorDeclBits.IsSimpleExplicit
? ExplicitSpecKind::ResolvedTrue
: ExplicitSpecKind::ResolvedFalse);
}
@@ -2643,10 +2434,10 @@ public:
InheritedConstructor Inherited = InheritedConstructor());
ExplicitSpecifier getExplicitSpecifier() {
- return getExplicitSpecifierInternal();
+ return getCanonicalDecl()->getExplicitSpecifierInternal();
}
const ExplicitSpecifier getExplicitSpecifier() const {
- return getExplicitSpecifierInternal();
+ return getCanonicalDecl()->getExplicitSpecifierInternal();
}
/// Return true if the declartion is already resolved to be explicit.
@@ -2847,9 +2638,9 @@ class CXXDestructorDecl : public CXXMethodDecl {
CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, bool isInline,
- bool isImplicitlyDeclared)
+ bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind)
: CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, CSK_unspecified, SourceLocation()) {
+ SC_None, isInline, ConstexprKind, SourceLocation()) {
setImplicit(isImplicitlyDeclared);
}
@@ -2859,9 +2650,9 @@ public:
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo* TInfo,
- bool isInline,
- bool isImplicitlyDeclared);
+ QualType T, TypeSourceInfo *TInfo,
+ bool isInline, bool isImplicitlyDeclared,
+ ConstexprSpecKind ConstexprKind);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
@@ -2934,7 +2725,7 @@ public:
/// Returns the type that this conversion function is converting to.
QualType getConversionType() const {
- return getType()->getAs<FunctionType>()->getReturnType();
+ return getType()->castAs<FunctionType>()->getReturnType();
}
/// Determine whether this conversion function is a conversion from
@@ -2971,8 +2762,10 @@ public:
/// ensure a stable ABI for this, we choose the DW_LANG_ encodings
/// from the dwarf standard.
enum LanguageIDs {
- lang_c = /* DW_LANG_C */ 0x0002,
- lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
+ lang_c = llvm::dwarf::DW_LANG_C,
+ lang_cxx = llvm::dwarf::DW_LANG_C_plus_plus,
+ lang_cxx_11 = llvm::dwarf::DW_LANG_C_plus_plus_11,
+ lang_cxx_14 = llvm::dwarf::DW_LANG_C_plus_plus_14
};
private:
@@ -3469,12 +3262,6 @@ public:
return IsVirtual;
}
- /// Get the constructor or constructor template in the derived class
- /// correspnding to this using shadow declaration, if it has been implicitly
- /// declared already.
- CXXConstructorDecl *getConstructor() const;
- void setConstructor(NamedDecl *Ctor);
-
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ConstructorUsingShadow; }
};
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 235b31c1c312..ec14adc7de97 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -168,6 +168,16 @@ public:
return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
}
+ /// \brief All associated constraints derived from this template parameter
+ /// list, including the requires clause and any constraints derived from
+ /// constrained-parameters.
+ ///
+ /// The constraints in the resulting list are to be treated as if in a
+ /// conjunction ("and").
+ void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
+
+ bool hasAssociatedConstraints() const;
+
SourceLocation getTemplateLoc() const { return TemplateLoc; }
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
@@ -369,33 +379,7 @@ public:
// Kinds of Templates
//===----------------------------------------------------------------------===//
-/// Stores the template parameter list and associated constraints for
-/// \c TemplateDecl objects that track associated constraints.
-class ConstrainedTemplateDeclInfo {
- friend TemplateDecl;
-
-public:
- ConstrainedTemplateDeclInfo() = default;
-
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- Expr *getAssociatedConstraints() const { return AssociatedConstraints; }
-
-protected:
- void setTemplateParameters(TemplateParameterList *TParams) {
- TemplateParams = TParams;
- }
-
- void setAssociatedConstraints(Expr *AC) { AssociatedConstraints = AC; }
-
- TemplateParameterList *TemplateParams = nullptr;
- Expr *AssociatedConstraints = nullptr;
-};
-
-
-/// The base class of all kinds of template declarations (e.g.,
+/// \brief The base class of all kinds of template declarations (e.g.,
/// class, function, etc.).
///
/// The TemplateDecl class stores the list of template parameters and a
@@ -404,54 +388,32 @@ class TemplateDecl : public NamedDecl {
void anchor() override;
protected:
+ // Construct a template decl with name, parameters, and templated element.
+ TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl);
+
// Construct a template decl with the given name and parameters.
// Used when there is no templated element (e.g., for tt-params).
- TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
- TemplateParams(CTDI) {
- this->setTemplateParameters(Params);
- }
-
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params)
- : TemplateDecl(nullptr, DK, DC, L, Name, Params) {}
-
- // Construct a template decl with name, parameters, and templated element.
- TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
- TemplateParams(CTDI) {
- this->setTemplateParameters(Params);
- }
-
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(nullptr, DK, DC, L, Name, Params, Decl) {}
+ : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
- const auto *const CTDI =
- TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
- return CTDI ? CTDI->getTemplateParameters()
- : TemplateParams.get<TemplateParameterList *>();
+ return TemplateParams;
}
- /// Get the constraint-expression from the associated requires-clause (if any)
- const Expr *getRequiresClause() const {
- const TemplateParameterList *const TP = getTemplateParameters();
- return TP ? TP->getRequiresClause() : nullptr;
- }
+ /// \brief Get the total constraint-expression associated with this template,
+ /// including constraint-expressions derived from the requires-clause,
+ /// trailing requires-clause (for functions and methods) and constrained
+ /// template parameters.
+ void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
- Expr *getAssociatedConstraints() const {
- const auto *const C = cast<TemplateDecl>(getCanonicalDecl());
- const auto *const CTDI =
- C->TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
- return CTDI ? CTDI->getAssociatedConstraints() : nullptr;
- }
+ bool hasAssociatedConstraints() const;
/// Get the underlying, templated declaration.
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
@@ -470,29 +432,10 @@ public:
protected:
NamedDecl *TemplatedDecl;
-
- /// The template parameter list and optional requires-clause
- /// associated with this declaration; alternatively, a
- /// \c ConstrainedTemplateDeclInfo if the associated constraints of the
- /// template are being tracked by this particular declaration.
- llvm::PointerUnion<TemplateParameterList *,
- ConstrainedTemplateDeclInfo *>
- TemplateParams;
+ TemplateParameterList *TemplateParams;
void setTemplateParameters(TemplateParameterList *TParams) {
- if (auto *const CTDI =
- TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>()) {
- CTDI->setTemplateParameters(TParams);
- } else {
- TemplateParams = TParams;
- }
- }
-
- void setAssociatedConstraints(Expr *AC) {
- assert(isCanonicalDecl() &&
- "Attaching associated constraints to non-canonical Decl");
- TemplateParams.get<ConstrainedTemplateDeclInfo *>()
- ->setAssociatedConstraints(AC);
+ TemplateParams = TParams;
}
public:
@@ -889,17 +832,10 @@ protected:
virtual CommonBase *newCommon(ASTContext &C) const = 0;
// Construct a template decl with name, parameters, and templated element.
- RedeclarableTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK,
- ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C)
- {}
-
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(nullptr, DK, C, DC, L, Name, Params, Decl) {}
+ : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
public:
friend class ASTDeclReader;
@@ -2026,6 +1962,20 @@ public:
return TemplateParams;
}
+ /// \brief All associated constraints of this partial specialization,
+ /// including the requires clause and any constraints derived from
+ /// constrained-parameters.
+ ///
+ /// The constraints in the resulting list are to be treated as if in a
+ /// conjunction ("and").
+ void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
+ TemplateParams->getAssociatedConstraints(AC);
+ }
+
+ bool hasAssociatedConstraints() const {
+ return TemplateParams->hasAssociatedConstraints();
+ }
+
/// Get the template arguments as written.
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
return ArgsAsWritten;
@@ -2145,16 +2095,10 @@ protected:
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations();
- ClassTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, ASTContext &C,
- DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(CTDI, ClassTemplate, C, DC, L, Name, Params,
- Decl) {}
-
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params,
NamedDecl *Decl)
- : ClassTemplateDecl(nullptr, C, DC, L, Name, Params, Decl) {}
+ : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
CommonBase *newCommon(ASTContext &C) const override;
@@ -2180,14 +2124,12 @@ public:
return getTemplatedDecl()->isThisDeclarationADefinition();
}
- // FIXME: remove default argument for AssociatedConstraints
- /// Create a class template node.
+ /// \brief Create a class template node.
static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
- NamedDecl *Decl,
- Expr *AssociatedConstraints = nullptr);
+ NamedDecl *Decl);
/// Create an empty class template node.
static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2527,10 +2469,6 @@ public:
}
};
-/// Implementation of inline functions that require the template declarations
-inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
- : Function(FTD) {}
-
/// Represents a variable template specialization, which refers to
/// a variable template with a given set of template arguments.
///
@@ -2866,7 +2804,21 @@ public:
return ArgsAsWritten;
}
- /// Retrieve the member variable template partial specialization from
+ /// \brief All associated constraints of this partial specialization,
+ /// including the requires clause and any constraints derived from
+ /// constrained-parameters.
+ ///
+ /// The constraints in the resulting list are to be treated as if in a
+ /// conjunction ("and").
+ void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
+ TemplateParams->getAssociatedConstraints(AC);
+ }
+
+ bool hasAssociatedConstraints() const {
+ return TemplateParams->hasAssociatedConstraints();
+ }
+
+ /// \brief Retrieve the member variable template partial specialization from
/// which this particular variable template partial specialization was
/// instantiated.
///
@@ -3095,11 +3047,9 @@ 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),
+ ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, Expr *ConstraintExpr)
+ : TemplateDecl(Concept, DC, L, Name, Params),
ConstraintExpr(ConstraintExpr) {};
public:
static ConceptDecl *Create(ASTContext &C, DeclContext *DC,
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index d44a815c8699..ffa7d4db96a4 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -906,6 +906,11 @@ public:
return skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
}
+ /// Checks that the two Expr's will refer to the same value as a comparison
+ /// operand. The caller must ensure that the values referenced by the Expr's
+ /// are not modified between E1 and E2 or the result my be invalid.
+ static bool isSameComparisonOperand(const Expr* E1, const Expr* E2);
+
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
T->getStmtClass() <= lastExprConstant;
@@ -2619,9 +2624,8 @@ public:
/// + sizeof(Stmt *) bytes of storage, aligned to alignof(CallExpr):
///
/// \code{.cpp}
- /// llvm::AlignedCharArray<alignof(CallExpr),
- /// sizeof(CallExpr) + sizeof(Stmt *)> Buffer;
- /// CallExpr *TheCall = CallExpr::CreateTemporary(Buffer.buffer, etc);
+ /// alignas(CallExpr) char Buffer[sizeof(CallExpr) + sizeof(Stmt *)];
+ /// CallExpr *TheCall = CallExpr::CreateTemporary(Buffer, etc);
/// \endcode
static CallExpr *CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
ExprValueKind VK, SourceLocation RParenLoc,
@@ -4496,6 +4500,8 @@ public:
// Explicit InitListExpr's originate from source code (and have valid source
// locations). Implicit InitListExpr's are created by the semantic analyzer.
+ // FIXME: This is wrong; InitListExprs created by semantic analysis have
+ // valid source locations too!
bool isExplicit() const {
return LBraceLoc.isValid() && RBraceLoc.isValid();
}
@@ -4830,6 +4836,10 @@ public:
SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
void setEqualOrColonLoc(SourceLocation L) { EqualOrColonLoc = L; }
+ /// Whether this designated initializer should result in direct-initialization
+ /// of the designated subobject (eg, '{.foo{1, 2, 3}}').
+ bool isDirectInit() const { return EqualOrColonLoc.isInvalid(); }
+
/// Determines whether this designated initializer used the
/// deprecated GNU syntax for designated initializers.
bool usesGNUSyntax() const { return GNUSyntax; }
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 28ed6cdfde14..2152e108c7cb 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -17,6 +17,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
@@ -185,15 +186,20 @@ public:
static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
EmptyShell Empty);
- /// Retrieves the implicit object argument for the member call.
+ /// Retrieve the implicit object argument for the member call.
///
/// For example, in "x.f(5)", this returns the sub-expression "x".
Expr *getImplicitObjectArgument() const;
- /// Retrieves the declaration of the called method.
+ /// Retrieve the type of the object argument.
+ ///
+ /// Note that this always returns a non-pointer type.
+ QualType getObjectType() const;
+
+ /// Retrieve the declaration of the called method.
CXXMethodDecl *getMethodDecl() const;
- /// Retrieves the CXXRecordDecl for the underlying type of
+ /// Retrieve the CXXRecordDecl for the underlying type of
/// the implicit object argument.
///
/// Note that this is may not be the same declaration as that of the class
@@ -248,6 +254,96 @@ public:
}
};
+/// A rewritten comparison expression that was originally written using
+/// operator syntax.
+///
+/// In C++20, the following rewrites are performed:
+/// - <tt>a == b</tt> -> <tt>b == a</tt>
+/// - <tt>a != b</tt> -> <tt>!(a == b)</tt>
+/// - <tt>a != b</tt> -> <tt>!(b == a)</tt>
+/// - For \c \@ in \c <, \c <=, \c >, \c >=, \c <=>:
+/// - <tt>a @ b</tt> -> <tt>(a <=> b) @ 0</tt>
+/// - <tt>a @ b</tt> -> <tt>0 @ (b <=> a)</tt>
+///
+/// This expression provides access to both the original syntax and the
+/// rewritten expression.
+///
+/// Note that the rewritten calls to \c ==, \c <=>, and \c \@ are typically
+/// \c CXXOperatorCallExprs, but could theoretically be \c BinaryOperators.
+class CXXRewrittenBinaryOperator : public Expr {
+ friend class ASTStmtReader;
+
+ /// The rewritten semantic form.
+ Stmt *SemanticForm;
+
+public:
+ CXXRewrittenBinaryOperator(Expr *SemanticForm, bool IsReversed)
+ : Expr(CXXRewrittenBinaryOperatorClass, SemanticForm->getType(),
+ SemanticForm->getValueKind(), SemanticForm->getObjectKind(),
+ SemanticForm->isTypeDependent(), SemanticForm->isValueDependent(),
+ SemanticForm->isInstantiationDependent(),
+ SemanticForm->containsUnexpandedParameterPack()),
+ SemanticForm(SemanticForm) {
+ CXXRewrittenBinaryOperatorBits.IsReversed = IsReversed;
+ }
+ CXXRewrittenBinaryOperator(EmptyShell Empty)
+ : Expr(CXXRewrittenBinaryOperatorClass, Empty), SemanticForm() {}
+
+ /// Get an equivalent semantic form for this expression.
+ Expr *getSemanticForm() { return cast<Expr>(SemanticForm); }
+ const Expr *getSemanticForm() const { return cast<Expr>(SemanticForm); }
+
+ struct DecomposedForm {
+ /// The original opcode, prior to rewriting.
+ BinaryOperatorKind Opcode;
+ /// The original left-hand side.
+ const Expr *LHS;
+ /// The original right-hand side.
+ const Expr *RHS;
+ /// The inner \c == or \c <=> operator expression.
+ const Expr *InnerBinOp;
+ };
+
+ /// Decompose this operator into its syntactic form.
+ DecomposedForm getDecomposedForm() const LLVM_READONLY;
+
+ /// Determine whether this expression was rewritten in reverse form.
+ bool isReversed() const { return CXXRewrittenBinaryOperatorBits.IsReversed; }
+
+ BinaryOperatorKind getOperator() const { return getDecomposedForm().Opcode; }
+ const Expr *getLHS() const { return getDecomposedForm().LHS; }
+ const Expr *getRHS() const { return getDecomposedForm().RHS; }
+
+ SourceLocation getOperatorLoc() const LLVM_READONLY {
+ return getDecomposedForm().InnerBinOp->getExprLoc();
+ }
+ SourceLocation getExprLoc() const LLVM_READONLY { return getOperatorLoc(); }
+
+ /// Compute the begin and end locations from the decomposed form.
+ /// The locations of the semantic form are not reliable if this is
+ /// a reversed expression.
+ //@{
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ return getDecomposedForm().LHS->getBeginLoc();
+ }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getDecomposedForm().RHS->getEndLoc();
+ }
+ SourceRange getSourceRange() const LLVM_READONLY {
+ DecomposedForm DF = getDecomposedForm();
+ return SourceRange(DF.LHS->getBeginLoc(), DF.RHS->getEndLoc());
+ }
+ //@}
+
+ child_range children() {
+ return child_range(&SemanticForm, &SemanticForm + 1);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXRewrittenBinaryOperatorClass;
+ }
+};
+
/// Abstract class common to all of the C++ "named"/"keyword" casts.
///
/// This abstract class is inherited by all of the classes
@@ -1902,6 +1998,10 @@ public:
/// lambda expression.
CXXMethodDecl *getCallOperator() const;
+ /// Retrieve the function template call operator associated with this
+ /// lambda expression.
+ FunctionTemplateDecl *getDependentCallOperator() const;
+
/// If this is a generic lambda expression, retrieve the template
/// parameter list associated with it, or else return null.
TemplateParameterList *getTemplateParameterList() const;
@@ -2091,8 +2191,7 @@ public:
bool IsParenTypeId);
QualType getAllocatedType() const {
- assert(getType()->isPointerType());
- return getType()->getAs<PointerType>()->getPointeeType();
+ return getType()->castAs<PointerType>()->getPointeeType();
}
TypeSourceInfo *getAllocatedTypeSourceInfo() const {
@@ -2270,8 +2369,8 @@ public:
CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm,
bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize,
FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc)
- : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- Arg->isInstantiationDependent(),
+ : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary, false,
+ Arg->isValueDependent(), Arg->isInstantiationDependent(),
Arg->containsUnexpandedParameterPack()),
OperatorDelete(OperatorDelete), Argument(Arg) {
CXXDeleteExprBits.GlobalDelete = GlobalDelete;
@@ -4335,9 +4434,6 @@ private:
};
llvm::PointerUnion<Stmt *, ExtraState *> State;
- void initializeExtraState(const ValueDecl *ExtendedBy,
- unsigned ManglingNumber);
-
public:
MaterializeTemporaryExpr(QualType T, Expr *Temporary,
bool BoundToLvalueReference)
@@ -4745,6 +4841,125 @@ public:
}
};
+/// \brief Represents the specialization of a concept - evaluates to a prvalue
+/// of type bool.
+///
+/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
+/// specialization of a concept results in a prvalue of type bool.
+class ConceptSpecializationExpr final : public Expr,
+ private llvm::TrailingObjects<ConceptSpecializationExpr,
+ TemplateArgument> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
+ // \brief The optional nested name specifier used when naming the concept.
+ NestedNameSpecifierLoc NestedNameSpec;
+
+ /// \brief The location of the template keyword, if specified when naming the
+ /// concept.
+ SourceLocation TemplateKWLoc;
+
+ /// \brief The location of the concept name in the expression.
+ SourceLocation ConceptNameLoc;
+
+ /// \brief The declaration found by name lookup when the expression was
+ /// created.
+ /// Can differ from NamedConcept when, for example, the concept was found
+ /// through a UsingShadowDecl.
+ NamedDecl *FoundDecl;
+
+ /// \brief The concept named, and whether or not the concept with the given
+ /// arguments was satisfied when the expression was created.
+ /// If any of the template arguments are dependent (this expr would then be
+ /// isValueDependent()), this bit is to be ignored.
+ llvm::PointerIntPair<ConceptDecl *, 1, bool> NamedConcept;
+
+ /// \brief The template argument list source info used to specialize the
+ /// concept.
+ const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
+
+ /// \brief The number of template arguments in the tail-allocated list of
+ /// converted template arguments.
+ unsigned NumTemplateArgs;
+
+ ConceptSpecializationExpr(ASTContext &C, NestedNameSpecifierLoc NNS,
+ SourceLocation TemplateKWLoc,
+ SourceLocation ConceptNameLoc, NamedDecl *FoundDecl,
+ ConceptDecl *NamedConcept,
+ const ASTTemplateArgumentListInfo *ArgsAsWritten,
+ ArrayRef<TemplateArgument> ConvertedArgs,
+ Optional<bool> IsSatisfied);
+
+ ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
+
+public:
+
+ static ConceptSpecializationExpr *
+ Create(ASTContext &C, NestedNameSpecifierLoc NNS,
+ SourceLocation TemplateKWLoc, SourceLocation ConceptNameLoc,
+ NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+ const ASTTemplateArgumentListInfo *ArgsAsWritten,
+ ArrayRef<TemplateArgument> ConvertedArgs, Optional<bool> IsSatisfied);
+
+ static ConceptSpecializationExpr *
+ Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
+
+ const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
+ return NestedNameSpec;
+ }
+
+ NamedDecl *getFoundDecl() const {
+ return FoundDecl;
+ }
+
+ ConceptDecl *getNamedConcept() const {
+ return NamedConcept.getPointer();
+ }
+
+ ArrayRef<TemplateArgument> getTemplateArguments() const {
+ return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
+ NumTemplateArgs);
+ }
+
+ const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
+ return ArgsAsWritten;
+ }
+
+ /// \brief Set new template arguments for this concept specialization.
+ void setTemplateArguments(const ASTTemplateArgumentListInfo *ArgsAsWritten,
+ ArrayRef<TemplateArgument> Converted);
+
+ /// \brief Whether or not the concept with the given arguments was satisfied
+ /// when the expression was created. This method assumes that the expression
+ /// is not dependent!
+ bool isSatisfied() const {
+ assert(!isValueDependent()
+ && "isSatisfied called on a dependent ConceptSpecializationExpr");
+ return NamedConcept.getInt();
+ }
+
+ SourceLocation getConceptNameLoc() const { return ConceptNameLoc; }
+
+ SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ConceptSpecializationExprClass;
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return ConceptNameLoc; }
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return ArgsAsWritten->RAngleLoc;
+ }
+
+ // Iterators
+ 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());
+ }
+};
+
} // namespace clang
#endif // LLVM_CLANG_AST_EXPRCXX_H
diff --git a/include/clang/AST/ExternalASTMerger.h b/include/clang/AST/ExternalASTMerger.h
index d89189da04f0..0230495a5ef3 100644
--- a/include/clang/AST/ExternalASTMerger.h
+++ b/include/clang/AST/ExternalASTMerger.h
@@ -14,6 +14,7 @@
#define LLVM_CLANG_AST_EXTERNALASTMERGER_H
#include "clang/AST/ASTImporter.h"
+#include "clang/AST/ASTImporterSharedState.h"
#include "clang/AST/ExternalASTSource.h"
#include "llvm/Support/raw_ostream.h"
@@ -22,7 +23,7 @@ namespace clang {
/// ExternalASTSource implementation that merges information from several
/// ASTContexts.
///
-/// ExtermalASTMerger maintains a vector of ASTImporters that it uses to import
+/// ExternalASTMerger maintains a vector of ASTImporters that it uses to import
/// (potentially incomplete) Decls and DeclContexts from the source ASTContexts
/// in response to ExternalASTSource API calls.
///
@@ -36,7 +37,7 @@ namespace clang {
/// lookup. In this case, Origins contains an entry overriding lookup and
/// specifying the correct pair of DeclContext/ASTContext.
///
-/// - The DeclContext of origin was determined by another ExterenalASTMerger.
+/// - The DeclContext of origin was determined by another ExternalASTMerger.
/// (This is possible when the source ASTContext for one of the Importers has
/// its own ExternalASTMerger). The origin must be properly forwarded in this
/// case.
@@ -79,20 +80,47 @@ public:
/// import SourceLocations properly. Additionally, when import occurs for
/// a DeclContext whose origin has been overridden, then this
/// ExternalASTMerger must be able to determine that.
- struct ImporterSource {
+ class ImporterSource {
ASTContext &AST;
FileManager &FM;
const OriginMap &OM;
+ /// True iff the source only exists temporary, i.e., it will be removed from
+ /// the ExternalASTMerger during the life time of the ExternalASTMerger.
+ bool Temporary;
+ /// If the ASTContext of this source has an ExternalASTMerger that imports
+ /// into this source, then this will point to that other ExternalASTMerger.
+ ExternalASTMerger *Merger;
+
+ public:
+ ImporterSource(ASTContext &AST, FileManager &FM, const OriginMap &OM,
+ bool Temporary = false, ExternalASTMerger *Merger = nullptr)
+ : AST(AST), FM(FM), OM(OM), Temporary(Temporary), Merger(Merger) {}
+ ASTContext &getASTContext() const { return AST; }
+ FileManager &getFileManager() const { return FM; }
+ const OriginMap &getOriginMap() const { return OM; }
+ bool isTemporary() const { return Temporary; }
+ ExternalASTMerger *getMerger() const { return Merger; }
};
private:
- /// The target for this ExtenralASTMerger.
+ /// The target for this ExternalASTMerger.
ImporterTarget Target;
+ /// ExternalASTMerger has multiple ASTImporters that import into the same
+ /// TU. This is the shared state for all ASTImporters of this
+ /// ExternalASTMerger.
+ /// See also the CrossTranslationUnitContext that has a similar setup.
+ std::shared_ptr<ASTImporterSharedState> SharedState;
public:
ExternalASTMerger(const ImporterTarget &Target,
llvm::ArrayRef<ImporterSource> Sources);
+ /// Asks all connected ASTImporters if any of them imported the given
+ /// declaration. If any ASTImporter did import the given declaration,
+ /// then this function returns the declaration that D was imported from.
+ /// Returns nullptr if no ASTImporter did import import D.
+ Decl *FindOriginalDecl(Decl *D);
+
/// Add a set of ASTContexts as possible origins.
///
/// Usually the set will be initialized in the constructor, but long-lived
@@ -145,7 +173,7 @@ public:
/// OriginContext.
bool HasImporterForOrigin(ASTContext &OriginContext);
- /// Returns a reference to the ASTRImporter from Importers whose origin
+ /// Returns a reference to the ASTImporter from Importers whose origin
/// is OriginContext. This allows manual import of ASTs while preserving the
/// OriginMap correctly.
ASTImporter &ImporterForOrigin(ASTContext &OriginContext);
diff --git a/include/clang/AST/FormatString.h b/include/clang/AST/FormatString.h
index 643fb822f7f4..8c944451f796 100644
--- a/include/clang/AST/FormatString.h
+++ b/include/clang/AST/FormatString.h
@@ -251,7 +251,21 @@ public:
enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
AnyCharTy, CStrTy, WCStrTy, WIntTy };
- enum MatchKind { NoMatch = 0, Match = 1, NoMatchPedantic };
+ /// How well a given conversion specifier matches its argument.
+ enum MatchKind {
+ /// The conversion specifier and the argument types are incompatible. For
+ /// instance, "%d" and float.
+ NoMatch = 0,
+ /// The conversion specifier and the argument type are compatible. For
+ /// instance, "%d" and _Bool.
+ Match = 1,
+ /// The conversion specifier and the argument type are disallowed by the C
+ /// standard, but are in practice harmless. For instance, "%p" and int*.
+ NoMatchPedantic,
+ /// The conversion specifier and the argument type are compatible, but still
+ /// seems likely to be an error. For instance, "%hd" and _Bool.
+ NoMatchTypeConfusion,
+ };
private:
const Kind K;
@@ -748,6 +762,12 @@ bool ParseScanfString(FormatStringHandler &H,
const char *beg, const char *end, const LangOptions &LO,
const TargetInfo &Target);
+/// Return true if the given string has at least one formatting specifier.
+bool parseFormatStringHasFormattingSpecifiers(const char *Begin,
+ const char *End,
+ const LangOptions &LO,
+ const TargetInfo &Target);
+
} // end analyze_format_string namespace
} // end clang namespace
#endif
diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h
index 86fd0f6aa907..145e961a23a3 100644
--- a/include/clang/AST/GlobalDecl.h
+++ b/include/clang/AST/GlobalDecl.h
@@ -59,6 +59,7 @@ public:
GlobalDecl(const CapturedDecl *D) { Init(D); }
GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
+ GlobalDecl(const OMPDeclareMapperDecl *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)
diff --git a/include/clang/AST/JSONNodeDumper.h b/include/clang/AST/JSONNodeDumper.h
index 238e43aad78b..5f34440b8b56 100644
--- a/include/clang/AST/JSONNodeDumper.h
+++ b/include/clang/AST/JSONNodeDumper.h
@@ -141,6 +141,8 @@ class JSONNodeDumper
JOS.attribute(Key, Value);
}
+ void writeIncludeStack(PresumedLoc Loc, bool JustFirst = false);
+
// Writes the attributes of a SourceLocation object without.
void writeBareSourceLocation(SourceLocation Loc, bool IsSpelling);
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index b1fbe936136a..5db5c5b977da 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -56,7 +56,7 @@ private:
llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
- llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
+ llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
public:
ManglerKind getKind() const { return Kind; }
@@ -82,9 +82,9 @@ public:
return Result.first->second;
}
- uint64_t getAnonymousStructId(const TagDecl *TD) {
- std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
- Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
+ uint64_t getAnonymousStructId(const NamedDecl *D) {
+ std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
+ Result = AnonStructIds.insert(std::make_pair(D, AnonStructIds.size()));
return Result.first->second;
}
@@ -170,6 +170,8 @@ public:
virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
raw_ostream &) = 0;
+ virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
+
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Itanium;
}
@@ -248,8 +250,16 @@ class ASTNameGenerator {
public:
explicit ASTNameGenerator(ASTContext &Ctx);
~ASTNameGenerator();
+
+ /// Writes name for \p D to \p OS.
+ /// \returns true on failure, false on success.
bool writeName(const Decl *D, raw_ostream &OS);
+
+ /// \returns name for \p D
std::string getName(const Decl *D);
+
+ /// \returns all applicable mangled names.
+ /// For example C++ constructors/destructors can have multiple.
std::vector<std::string> getAllManglings(const Decl *D);
private:
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
index 21f0c5458d81..a8bd2d0f17e6 100644
--- a/include/clang/AST/NSAPI.h
+++ b/include/clang/AST/NSAPI.h
@@ -55,9 +55,6 @@ public:
/// The Objective-C NSString selectors.
Selector getNSStringSelector(NSStringMethodKind MK) const;
- /// Return NSStringMethodKind if \param Sel is such a selector.
- Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const;
-
/// Returns true if the expression \param E is a reference of
/// "NSUTF8StringEncoding" enum constant.
bool isNSUTF8StringEncodingConstant(const Expr *E) const {
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index eadcc62a3457..b2a2035dcb3c 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -519,7 +519,7 @@ public:
/// \endcode
/// In this example directive '#pragma omp task' has simple 'final'
/// clause with condition 'a > 5'.
-class OMPFinalClause : public OMPClause {
+class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
/// Location of '('.
@@ -534,18 +534,25 @@ class OMPFinalClause : public OMPClause {
public:
/// Build 'final' clause with condition \a Cond.
///
+ /// \param Cond Condition of the clause.
+ /// \param HelperCond Helper condition for the construct.
+ /// \param CaptureRegion Innermost OpenMP region where expressions in this
+ /// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
- /// \param Cond Condition of the clause.
/// \param EndLoc Ending location of the clause.
- OMPFinalClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Condition(Cond) {}
+ OMPFinalClause(Expr *Cond, Stmt *HelperCond,
+ OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_final, StartLoc, EndLoc), OMPClauseWithPreInit(this),
+ LParenLoc(LParenLoc), Condition(Cond) {
+ setPreInitStmt(HelperCond, CaptureRegion);
+ }
/// Build an empty clause.
OMPFinalClause()
- : OMPClause(OMPC_final, SourceLocation(), SourceLocation()) {}
+ : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
+ OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -562,11 +569,10 @@ public:
return const_child_range(&Condition, &Condition + 1);
}
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
+ child_range used_children();
const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ auto Children = const_cast<OMPFinalClause *>(this)->used_children();
+ return const_child_range(Children.begin(), Children.end());
}
static bool classof(const OMPClause *T) {
@@ -2099,10 +2105,12 @@ public:
}
child_range used_children() {
- return child_range(child_iterator(), child_iterator());
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
}
const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ auto Children = const_cast<OMPFirstprivateClause *>(this)->used_children();
+ return const_child_range(Children.begin(), Children.end());
}
static bool classof(const OMPClause *T) {
@@ -2616,10 +2624,12 @@ public:
}
child_range used_children() {
- return child_range(child_iterator(), child_iterator());
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
}
const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ auto Children = const_cast<OMPReductionClause *>(this)->used_children();
+ return const_child_range(Children.begin(), Children.end());
}
static bool classof(const OMPClause *T) {
@@ -3212,6 +3222,14 @@ class OMPLinearClause final
return llvm::makeArrayRef(getUpdates().end(), varlist_size());
}
+ /// Gets the list of used expressions for linear variables.
+ MutableArrayRef<Expr *> getUsedExprs() {
+ return MutableArrayRef<Expr *>(getFinals().end() + 2, varlist_size() + 1);
+ }
+ ArrayRef<const Expr *> getUsedExprs() const {
+ return llvm::makeArrayRef(getFinals().end() + 2, varlist_size() + 1);
+ }
+
/// Sets the list of the copies of original linear variables.
/// \param PL List of expressions.
void setPrivates(ArrayRef<Expr *> PL);
@@ -3291,6 +3309,9 @@ public:
/// \param FL List of expressions.
void setFinals(ArrayRef<Expr *> FL);
+ /// Sets the list of used expressions for the linear clause.
+ void setUsedExprs(ArrayRef<Expr *> UE);
+
using privates_iterator = MutableArrayRef<Expr *>::iterator;
using privates_const_iterator = ArrayRef<const Expr *>::iterator;
using privates_range = llvm::iterator_range<privates_iterator>;
@@ -3343,6 +3364,21 @@ public:
return finals_const_range(getFinals().begin(), getFinals().end());
}
+ using used_expressions_iterator = MutableArrayRef<Expr *>::iterator;
+ using used_expressions_const_iterator = ArrayRef<const Expr *>::iterator;
+ using used_expressions_range =
+ llvm::iterator_range<used_expressions_iterator>;
+ using used_expressions_const_range =
+ llvm::iterator_range<used_expressions_const_iterator>;
+
+ used_expressions_range used_expressions() {
+ return finals_range(getUsedExprs().begin(), getUsedExprs().end());
+ }
+
+ used_expressions_const_range used_expressions() const {
+ return finals_const_range(getUsedExprs().begin(), getUsedExprs().end());
+ }
+
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
@@ -3353,11 +3389,11 @@ public:
return const_child_range(Children.begin(), Children.end());
}
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
+ child_range used_children();
+
const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ auto Children = const_cast<OMPLinearClause *>(this)->used_children();
+ return const_child_range(Children.begin(), Children.end());
}
static bool classof(const OMPClause *T) {
@@ -4995,12 +5031,17 @@ public:
}
child_range used_children() {
+ if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_tofrom)
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
return child_range(child_iterator(), child_iterator());
}
const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ auto Children = const_cast<OMPMapClause *>(this)->used_children();
+ return const_child_range(Children.begin(), Children.end());
}
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_map;
}
@@ -5165,7 +5206,7 @@ public:
/// \endcode
/// In this example directive '#pragma omp teams' has clause 'priority' with
/// single expression 'n'.
-class OMPPriorityClause : public OMPClause {
+class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
/// Location of '('.
@@ -5182,18 +5223,25 @@ class OMPPriorityClause : public OMPClause {
public:
/// Build 'priority' clause.
///
- /// \param E Expression associated with this clause.
+ /// \param Priority Expression associated with this clause.
+ /// \param HelperPriority Helper priority for the construct.
+ /// \param CaptureRegion Innermost OpenMP region where expressions in this
+ /// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- OMPPriorityClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_priority, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Priority(E) {}
+ OMPPriorityClause(Expr *Priority, Stmt *HelperPriority,
+ OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_priority, StartLoc, EndLoc), OMPClauseWithPreInit(this),
+ LParenLoc(LParenLoc), Priority(Priority) {
+ setPreInitStmt(HelperPriority, CaptureRegion);
+ }
/// Build an empty clause.
OMPPriorityClause()
- : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()) {}
+ : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()),
+ OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -5213,11 +5261,10 @@ public:
return const_child_range(&Priority, &Priority + 1);
}
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
+ child_range used_children();
const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ auto Children = const_cast<OMPPriorityClause *>(this)->used_children();
+ return const_child_range(Children.begin(), Children.end());
}
static bool classof(const OMPClause *T) {
@@ -5233,7 +5280,7 @@ public:
/// \endcode
/// In this example directive '#pragma omp taskloop' has clause 'grainsize'
/// with single expression '4'.
-class OMPGrainsizeClause : public OMPClause {
+class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
/// Location of '('.
@@ -5249,16 +5296,23 @@ public:
/// Build 'grainsize' clause.
///
/// \param Size Expression associated with this clause.
+ /// \param HelperSize Helper grainsize for the construct.
+ /// \param CaptureRegion Innermost OpenMP region where expressions in this
+ /// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- OMPGrainsizeClause(Expr *Size, SourceLocation StartLoc,
+ OMPGrainsizeClause(Expr *Size, Stmt *HelperSize,
+ OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_grainsize, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Grainsize(Size) {}
+ : OMPClause(OMPC_grainsize, StartLoc, EndLoc), OMPClauseWithPreInit(this),
+ LParenLoc(LParenLoc), Grainsize(Size) {
+ setPreInitStmt(HelperSize, CaptureRegion);
+ }
/// Build an empty clause.
explicit OMPGrainsizeClause()
- : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()) {}
+ : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()),
+ OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -5275,11 +5329,10 @@ public:
return const_child_range(&Grainsize, &Grainsize + 1);
}
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
+ child_range used_children();
const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ auto Children = const_cast<OMPGrainsizeClause *>(this)->used_children();
+ return const_child_range(Children.begin(), Children.end());
}
static bool classof(const OMPClause *T) {
@@ -5334,7 +5387,7 @@ public:
/// \endcode
/// In this example directive '#pragma omp taskloop' has clause 'num_tasks'
/// with single expression '4'.
-class OMPNumTasksClause : public OMPClause {
+class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit {
friend class OMPClauseReader;
/// Location of '('.
@@ -5350,16 +5403,23 @@ public:
/// Build 'num_tasks' clause.
///
/// \param Size Expression associated with this clause.
+ /// \param HelperSize Helper grainsize for the construct.
+ /// \param CaptureRegion Innermost OpenMP region where expressions in this
+ /// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- OMPNumTasksClause(Expr *Size, SourceLocation StartLoc,
+ OMPNumTasksClause(Expr *Size, Stmt *HelperSize,
+ OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumTasks(Size) {}
+ : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), OMPClauseWithPreInit(this),
+ LParenLoc(LParenLoc), NumTasks(Size) {
+ setPreInitStmt(HelperSize, CaptureRegion);
+ }
/// Build an empty clause.
explicit OMPNumTasksClause()
- : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()) {}
+ : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()),
+ OMPClauseWithPreInit(this) {}
/// Sets the location of '('.
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
@@ -5376,11 +5436,10 @@ public:
return const_child_range(&NumTasks, &NumTasks + 1);
}
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
+ child_range used_children();
const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ auto Children = const_cast<OMPNumTasksClause *>(this)->used_children();
+ return const_child_range(Children.begin(), Children.end());
}
static bool classof(const OMPClause *T) {
diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def
index 9af92c1ae7ff..f29664e8eb33 100644
--- a/include/clang/AST/OperationKinds.def
+++ b/include/clang/AST/OperationKinds.def
@@ -66,8 +66,9 @@ 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.
+/// CK_LValueToRValueBitCast - A conversion that causes us to reinterpret the
+/// object representation of an lvalue as an rvalue. Created by
+/// __builtin_bit_cast.
CAST_OPERATION(LValueToRValueBitCast)
/// CK_LValueToRValue - A conversion which causes the extraction of
diff --git a/include/clang/AST/OptionalDiagnostic.h b/include/clang/AST/OptionalDiagnostic.h
new file mode 100644
index 000000000000..c57199f0fdf1
--- /dev/null
+++ b/include/clang/AST/OptionalDiagnostic.h
@@ -0,0 +1,78 @@
+//===- OptionalDiagnostic.h - An optional diagnostic ------------*- 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
+/// Implements a partial diagnostic which may not be emitted.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPTIONALDIAGNOSTIC_H
+#define LLVM_CLANG_AST_OPTIONALDIAGNOSTIC_H
+
+#include "clang/AST/APValue.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+/// A partial diagnostic which we might know in advance that we are not going
+/// to emit.
+class OptionalDiagnostic {
+ PartialDiagnostic *Diag;
+
+public:
+ explicit OptionalDiagnostic(PartialDiagnostic *Diag = nullptr) : Diag(Diag) {}
+
+ template <typename T> OptionalDiagnostic &operator<<(const T &v) {
+ if (Diag)
+ *Diag << v;
+ return *this;
+ }
+
+ OptionalDiagnostic &operator<<(const llvm::APSInt &I) {
+ if (Diag) {
+ SmallVector<char, 32> Buffer;
+ I.toString(Buffer);
+ *Diag << StringRef(Buffer.data(), Buffer.size());
+ }
+ return *this;
+ }
+
+ OptionalDiagnostic &operator<<(const llvm::APFloat &F) {
+ if (Diag) {
+ // FIXME: Force the precision of the source value down so we don't
+ // print digits which are usually useless (we don't really care here if
+ // we truncate a digit by accident in edge cases). Ideally,
+ // APFloat::toString would automatically print the shortest
+ // representation which rounds to the correct value, but it's a bit
+ // tricky to implement. Could use std::to_chars.
+ unsigned precision = llvm::APFloat::semanticsPrecision(F.getSemantics());
+ precision = (precision * 59 + 195) / 196;
+ SmallVector<char, 32> Buffer;
+ F.toString(Buffer, precision);
+ *Diag << StringRef(Buffer.data(), Buffer.size());
+ }
+ return *this;
+ }
+
+ OptionalDiagnostic &operator<<(const APFixedPoint &FX) {
+ if (Diag) {
+ SmallVector<char, 32> Buffer;
+ FX.toString(Buffer);
+ *Diag << StringRef(Buffer.data(), Buffer.size());
+ }
+ return *this;
+ }
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 5dc8694e77e9..1eea56dee622 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -10,8 +10,11 @@
#define LLVM_CLANG_AST_RAWCOMMENTLIST_H
#include "clang/Basic/CommentOptions.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include <map>
namespace clang {
@@ -196,17 +199,25 @@ public:
void addComment(const RawComment &RC, const CommentOptions &CommentOpts,
llvm::BumpPtrAllocator &Allocator);
- ArrayRef<RawComment *> getComments() const {
- return Comments;
- }
+ /// \returns A mapping from an offset of the start of the comment to the
+ /// comment itself, or nullptr in case there are no comments in \p File.
+ const std::map<unsigned, RawComment *> *getCommentsInFile(FileID File) const;
+
+ bool empty() const;
+
+ unsigned getCommentBeginLine(RawComment *C, FileID File,
+ unsigned Offset) const;
+ unsigned getCommentEndOffset(RawComment *C) const;
private:
SourceManager &SourceMgr;
- std::vector<RawComment *> Comments;
-
- void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments);
+ // mapping: FileId -> comment begin offset -> comment
+ llvm::DenseMap<FileID, std::map<unsigned, RawComment *>> OrderedComments;
+ mutable llvm::DenseMap<RawComment *, unsigned> CommentBeginLine;
+ mutable llvm::DenseMap<RawComment *, unsigned> CommentEndOffset;
friend class ASTReader;
+ friend class ASTWriter;
};
} // end namespace clang
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 698fba2f4ed1..5b58eab95d60 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -431,7 +431,7 @@ public:
// Declare Traverse*() for all concrete Type classes.
#define ABSTRACT_TYPE(CLASS, BASE)
#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
// The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Type classes.
@@ -444,7 +444,7 @@ public:
return true; \
} \
bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
// ---- Methods on TypeLocs ----
// FIXME: this currently just calls the matching Type methods
@@ -460,7 +460,7 @@ public:
bool VisitTypeLoc(TypeLoc TL) { return true; }
// QualifiedTypeLoc and UnqualTypeLoc are not declared in
- // TypeNodes.def and thus need to be handled specially.
+ // TypeNodes.inc and thus need to be handled specially.
bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
}
@@ -478,7 +478,7 @@ public:
return true; \
} \
bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
// ---- Methods on Decls ----
@@ -676,7 +676,7 @@ bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
#define TYPE(CLASS, BASE) \
case Type::CLASS: \
DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
}
return true;
@@ -722,12 +722,6 @@ bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
break;
#include "clang/AST/DeclNodes.inc"
}
-
- // Visit any attributes attached to this declaration.
- for (auto *I : D->attrs()) {
- if (!getDerived().TraverseAttr(I))
- return false;
- }
return true;
}
@@ -965,8 +959,11 @@ DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
-DEF_TRAVERSE_TYPE(ConstantArrayType,
- { TRY_TO(TraverseType(T->getElementType())); })
+DEF_TRAVERSE_TYPE(ConstantArrayType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(const_cast<Expr*>(T->getSizeExpr())));
+})
DEF_TRAVERSE_TYPE(IncompleteArrayType,
{ TRY_TO(TraverseType(T->getElementType())); })
@@ -1407,6 +1404,11 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
{ CODE; } \
if (ReturnValue && ShouldVisitChildren) \
TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
+ if (ReturnValue) { \
+ /* Visit any attributes attached to this declaration. */ \
+ for (auto *I : D->attrs()) \
+ TRY_TO(getDerived().TraverseAttr(I)); \
+ } \
if (ReturnValue && getDerived().shouldTraversePostOrder()) \
TRY_TO(WalkUpFrom##DECL(D)); \
return ReturnValue; \
@@ -1631,9 +1633,11 @@ template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
TemplateParameterList *TPL) {
if (TPL) {
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
+ for (NamedDecl *D : *TPL) {
+ TRY_TO(TraverseDecl(D));
+ }
+ if (Expr *RequiresClause = TPL->getRequiresClause()) {
+ TRY_TO(TraverseStmt(RequiresClause));
}
}
return true;
@@ -2023,11 +2027,18 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
// Constructor initializers.
for (auto *I : Ctor->inits()) {
- TRY_TO(TraverseConstructorInitializer(I));
+ if (I->isWritten() || getDerived().shouldVisitImplicitCode())
+ TRY_TO(TraverseConstructorInitializer(I));
}
}
- if (D->isThisDeclarationADefinition()) {
+ bool VisitBody = D->isThisDeclarationADefinition();
+ // If a method is set to default outside the class definition the compiler
+ // generates the method body and adds it to the AST.
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
+ VisitBody &= !MD->isDefaulted() || getDerived().shouldVisitImplicitCode();
+
+ if (VisitBody) {
TRY_TO(TraverseStmt(D->getBody())); // Function body.
}
return true;
@@ -2308,19 +2319,30 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
return true;
}
-// This method is called once for each pair of syntactic and semantic
-// InitListExpr, and it traverses the subtrees defined by the two forms. This
-// may cause some of the children to be visited twice, if they appear both in
-// the syntactic and the semantic form.
+// If shouldVisitImplicitCode() returns false, this method traverses only the
+// syntactic form of InitListExpr.
+// If shouldVisitImplicitCode() return true, this method is called once for
+// each pair of syntactic and semantic InitListExpr, and it traverses the
+// subtrees defined by the two forms. This may cause some of the children to be
+// visited twice, if they appear both in the syntactic and the semantic form.
//
// There is no guarantee about which form \p S takes when this method is called.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
InitListExpr *S, DataRecursionQueue *Queue) {
+ if (S->isSemanticForm() && S->isSyntacticForm()) {
+ // `S` does not have alternative forms, traverse only once.
+ TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
+ return true;
+ }
TRY_TO(TraverseSynOrSemInitListExpr(
S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
- TRY_TO(TraverseSynOrSemInitListExpr(
- S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
+ if (getDerived().shouldVisitImplicitCode()) {
+ // Only visit the semantic form if the clients are interested in implicit
+ // compiler-generated.
+ TRY_TO(TraverseSynOrSemInitListExpr(
+ S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
+ }
return true;
}
@@ -2584,6 +2606,15 @@ DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
+DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, {
+ if (!getDerived().shouldVisitImplicitCode()) {
+ CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
+ S->getDecomposedForm();
+ TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS)));
+ TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS)));
+ ShouldVisitChildren = false;
+ }
+})
DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
DEF_TRAVERSE_STMT(TypoExpr, {})
DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
@@ -2639,6 +2670,12 @@ DEF_TRAVERSE_STMT(CoyieldExpr, {
}
})
+DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ S->getTemplateArgsAsWritten()->getTemplateArgs(),
+ S->getTemplateArgsAsWritten()->NumTemplateArgs));
+})
+
// These literals (all of them) do not need any action.
DEF_TRAVERSE_STMT(IntegerLiteral, {})
DEF_TRAVERSE_STMT(FixedPointLiteral, {})
@@ -2768,6 +2805,15 @@ DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPDistributeDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2826,6 +2872,8 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
#include "clang/Basic/OpenMPKinds.def"
case OMPC_threadprivate:
case OMPC_uniform:
+ case OMPC_device_type:
+ case OMPC_match:
case OMPC_unknown:
break;
}
@@ -2870,6 +2918,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+ TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getCondition()));
return true;
}
@@ -3240,6 +3289,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause(
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause(
OMPPriorityClause *C) {
+ TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getPriority()));
return true;
}
@@ -3247,6 +3297,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause(
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause(
OMPGrainsizeClause *C) {
+ TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getGrainsize()));
return true;
}
@@ -3254,6 +3305,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause(
template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPNumTasksClause(
OMPNumTasksClause *C) {
+ TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getNumTasks()));
return true;
}
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 403b88ac3a3c..7aebbf2cb6a3 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -604,6 +604,15 @@ protected:
unsigned FPFeatures : 3;
};
+ class CXXRewrittenBinaryOperatorBitfields {
+ friend class ASTStmtReader;
+ friend class CXXRewrittenBinaryOperator;
+
+ unsigned : NumCallExprBits;
+
+ unsigned IsReversed : 1;
+ };
+
class CXXBoolLiteralExprBitfields {
friend class CXXBoolLiteralExpr;
@@ -978,6 +987,7 @@ protected:
// C++ Expressions
CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
+ CXXRewrittenBinaryOperatorBitfields CXXRewrittenBinaryOperatorBits;
CXXBoolLiteralExprBitfields CXXBoolLiteralExprBits;
CXXNullPtrLiteralExprBitfields CXXNullPtrLiteralExprBits;
CXXThisExprBitfields CXXThisExprBits;
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index e37f5b1e0004..ddfb3060b158 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -17,6 +17,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/SourceLocation.h"
@@ -448,7 +449,8 @@ class OMPLoopDirective : public OMPExecutableDirective {
PreInitsOffset = 8,
// The '...End' enumerators do not correspond to child expressions - they
// specify the offset to the end (and start of the following counters/
- // updates/finals arrays).
+ // updates/finals/dependent_counters/dependent_inits/finals_conditions
+ // arrays).
DefaultEnd = 9,
// The following 8 exprs are used by worksharing and distribute loops only.
IsLastIterVariableOffset = 9,
@@ -474,7 +476,8 @@ class OMPLoopDirective : public OMPExecutableDirective {
CombinedNextUpperBoundOffset = 27,
CombinedDistConditionOffset = 28,
CombinedParForInDistConditionOffset = 29,
- // Offset to the end (and start of the following counters/updates/finals
+ // Offset to the end (and start of the following
+ // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
// arrays) for combined distribute loop directives.
CombinedDistributeEnd = 30,
};
@@ -517,6 +520,30 @@ class OMPLoopDirective : public OMPExecutableDirective {
return MutableArrayRef<Expr *>(Storage, CollapsedNum);
}
+ /// Get the dependent counters storage.
+ MutableArrayRef<Expr *> getDependentCounters() {
+ Expr **Storage = reinterpret_cast<Expr **>(
+ &*std::next(child_begin(),
+ getArraysOffset(getDirectiveKind()) + 5 * CollapsedNum));
+ return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+ }
+
+ /// Get the dependent inits storage.
+ MutableArrayRef<Expr *> getDependentInits() {
+ Expr **Storage = reinterpret_cast<Expr **>(
+ &*std::next(child_begin(),
+ getArraysOffset(getDirectiveKind()) + 6 * CollapsedNum));
+ return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+ }
+
+ /// Get the finals conditions storage.
+ MutableArrayRef<Expr *> getFinalsConditions() {
+ Expr **Storage = reinterpret_cast<Expr **>(
+ &*std::next(child_begin(),
+ getArraysOffset(getDirectiveKind()) + 7 * CollapsedNum));
+ return MutableArrayRef<Expr *>(Storage, CollapsedNum);
+ }
+
protected:
/// Build instance of loop directive of class \a Kind.
///
@@ -551,9 +578,10 @@ protected:
/// Children number.
static unsigned numLoopChildren(unsigned CollapsedNum,
OpenMPDirectiveKind Kind) {
- return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
- // PrivateCounters, Inits,
- // Updates and Finals
+ return getArraysOffset(Kind) +
+ 8 * CollapsedNum; // Counters, PrivateCounters, Inits,
+ // Updates, Finals, DependentCounters,
+ // DependentInits, FinalsConditions.
}
void setIterationVariable(Expr *IV) {
@@ -703,6 +731,9 @@ protected:
void setInits(ArrayRef<Expr *> A);
void setUpdates(ArrayRef<Expr *> A);
void setFinals(ArrayRef<Expr *> A);
+ void setDependentCounters(ArrayRef<Expr *> A);
+ void setDependentInits(ArrayRef<Expr *> A);
+ void setFinalsConditions(ArrayRef<Expr *> A);
public:
/// The expressions built to support OpenMP loops in combined/composite
@@ -798,6 +829,15 @@ public:
SmallVector<Expr *, 4> Updates;
/// Final loop counter values for GodeGen.
SmallVector<Expr *, 4> Finals;
+ /// List of counters required for the generation of the non-rectangular
+ /// loops.
+ SmallVector<Expr *, 4> DependentCounters;
+ /// List of initializers required for the generation of the non-rectangular
+ /// loops.
+ SmallVector<Expr *, 4> DependentInits;
+ /// List of final conditions required for the generation of the
+ /// non-rectangular loops.
+ SmallVector<Expr *, 4> FinalsConditions;
/// Init statement for all captured expressions.
Stmt *PreInits;
@@ -813,7 +853,9 @@ public:
}
/// Initialize all the fields to null.
- /// \param Size Number of elements in the counters/finals/updates arrays.
+ /// \param Size Number of elements in the
+ /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
+ /// arrays.
void clear(unsigned Size) {
IterationVarRef = nullptr;
LastIteration = nullptr;
@@ -839,12 +881,18 @@ public:
Inits.resize(Size);
Updates.resize(Size);
Finals.resize(Size);
+ DependentCounters.resize(Size);
+ DependentInits.resize(Size);
+ FinalsConditions.resize(Size);
for (unsigned i = 0; i < Size; ++i) {
Counters[i] = nullptr;
PrivateCounters[i] = nullptr;
Inits[i] = nullptr;
Updates[i] = nullptr;
Finals[i] = nullptr;
+ DependentCounters[i] = nullptr;
+ DependentInits[i] = nullptr;
+ FinalsConditions[i] = nullptr;
}
PreInits = nullptr;
DistCombinedFields.LB = nullptr;
@@ -1040,10 +1088,22 @@ public:
// This relies on the loop form is already checked by Sema.
const Stmt *Body =
getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
- Body = cast<ForStmt>(Body)->getBody();
+ if (auto *For = dyn_cast<ForStmt>(Body)) {
+ Body = For->getBody();
+ } else {
+ assert(isa<CXXForRangeStmt>(Body) &&
+ "Expected canonical for loop or range-based for loop.");
+ Body = cast<CXXForRangeStmt>(Body)->getBody();
+ }
for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
Body = Body->IgnoreContainers();
- Body = cast<ForStmt>(Body)->getBody();
+ if (auto *For = dyn_cast<ForStmt>(Body)) {
+ Body = For->getBody();
+ } else {
+ assert(isa<CXXForRangeStmt>(Body) &&
+ "Expected canonical for loop or range-based for loop.");
+ Body = cast<CXXForRangeStmt>(Body)->getBody();
+ }
}
return Body;
}
@@ -1078,6 +1138,24 @@ public:
return const_cast<OMPLoopDirective *>(this)->getFinals();
}
+ ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
+
+ ArrayRef<Expr *> dependent_counters() const {
+ return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
+ }
+
+ ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
+
+ ArrayRef<Expr *> dependent_inits() const {
+ return const_cast<OMPLoopDirective *>(this)->getDependentInits();
+ }
+
+ ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
+
+ ArrayRef<Expr *> finals_conditions() const {
+ return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPSimdDirectiveClass ||
T->getStmtClass() == OMPForDirectiveClass ||
@@ -1086,6 +1164,9 @@ public:
T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
T->getStmtClass() == OMPTaskLoopDirectiveClass ||
T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
+ T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
+ T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
+ T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
T->getStmtClass() == OMPDistributeDirectiveClass ||
T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
@@ -3041,6 +3122,211 @@ public:
}
};
+/// This represents '#pragma omp master taskloop' directive.
+///
+/// \code
+/// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp master taskloop' has clauses
+/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
+/// and 'num_tasks' with expression 'num'.
+///
+class OMPMasterTaskLoopDirective : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass,
+ OMPD_master_taskloop, StartLoc, EndLoc, CollapsedNum,
+ NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass,
+ OMPD_master_taskloop, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPMasterTaskLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp master taskloop simd' directive.
+///
+/// \code
+/// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp master taskloop simd' has clauses
+/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
+/// and 'num_tasks' with expression 'num'.
+///
+class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPMasterTaskLoopSimdDirectiveClass,
+ OMPD_master_taskloop_simd, StartLoc, EndLoc,
+ CollapsedNum, NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPMasterTaskLoopSimdDirectiveClass,
+ OMPD_master_taskloop_simd, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPMasterTaskLoopSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place for \p NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp parallel master taskloop' directive.
+///
+/// \code
+/// #pragma omp parallel master taskloop private(a,b) grainsize(val)
+/// num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp parallel master taskloop' has clauses
+/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
+/// and 'num_tasks' with expression 'num'.
+///
+class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum, unsigned NumClauses)
+ : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass,
+ OMPD_parallel_master_taskloop, StartLoc, EndLoc,
+ CollapsedNum, NumClauses) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum,
+ unsigned NumClauses)
+ : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass,
+ OMPD_parallel_master_taskloop, SourceLocation(),
+ SourceLocation(), CollapsedNum, NumClauses) {}
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPParallelMasterTaskLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp distribute' directive.
///
/// \code
diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h
index 4c2d0710963b..0ff5a614a864 100644
--- a/include/clang/AST/TextNodeDumper.h
+++ b/include/clang/AST/TextNodeDumper.h
@@ -146,8 +146,6 @@ class TextNodeDumper
const comments::CommandTraits *Traits;
- const ASTContext *Context;
-
const char *getCommandName(unsigned CommandID);
public:
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 584655fe789e..c9238e952101 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -126,7 +126,7 @@ using CanQualType = CanQual<Type>;
// Provide forward declarations for all of the *Type classes.
#define TYPE(Class, Base) class Class##Type;
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
/// The collection of all-type qualifiers we support.
/// Clang supports five independent qualifiers:
@@ -972,6 +972,9 @@ public:
friend bool operator!=(const QualType &LHS, const QualType &RHS) {
return LHS.Value != RHS.Value;
}
+ friend bool operator<(const QualType &LHS, const QualType &RHS) {
+ return LHS.Value < RHS.Value;
+ }
static std::string getAsString(SplitQualType split,
const PrintingPolicy &Policy) {
@@ -1434,10 +1437,9 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
public:
enum TypeClass {
#define TYPE(Class, Base) Class,
-#define LAST_TYPE(Class) TypeLast = Class,
+#define LAST_TYPE(Class) TypeLast = Class
#define ABSTRACT_TYPE(Class, Base)
-#include "clang/AST/TypeNodes.def"
- TagFirst = Record, TagLast = Enum
+#include "clang/AST/TypeNodes.inc"
};
private:
@@ -1511,6 +1513,15 @@ protected:
unsigned SizeModifier : 3;
};
+ class ConstantArrayTypeBitfields {
+ friend class ConstantArrayType;
+
+ unsigned : NumTypeBits + 3 + 3;
+
+ /// Whether we have a stored size expression.
+ unsigned HasStoredSizeExpr : 1;
+ };
+
class BuiltinTypeBitfields {
friend class BuiltinType;
@@ -1732,6 +1743,7 @@ protected:
union {
TypeBitfields TypeBits;
ArrayTypeBitfields ArrayTypeBits;
+ ConstantArrayTypeBitfields ConstantArrayTypeBits;
AttributedTypeBitfields AttributedTypeBits;
AutoTypeBitfields AutoTypeBits;
BuiltinTypeBitfields BuiltinTypeBits;
@@ -2053,6 +2065,7 @@ public:
bool isCARCBridgableType() const;
bool isTemplateTypeParmType() const; // C++ template type parameter
bool isNullPtrType() const; // C++11 std::nullptr_t
+ bool isNothrowT() const; // C++ std::nothrow_t
bool isAlignValT() const; // C++17 std::align_val_t
bool isStdByteType() const; // C++17 std::byte
bool isAtomicType() const; // C11 _Atomic()
@@ -2416,7 +2429,7 @@ template <> inline const Class##Type *Type::getAs() const { \
template <> inline const Class##Type *Type::castAs() const { \
return cast<Class##Type>(CanonicalType); \
}
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
/// This class is used for builtin types like 'int'. Builtin
/// types are always canonical and have a literal name field.
@@ -2429,6 +2442,9 @@ public:
// OpenCL extension types
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id,
#include "clang/Basic/OpenCLExtensionTypes.def"
+// SVE Types
+#define SVE_TYPE(Name, Id, SingletonId) Id,
+#include "clang/Basic/AArch64SVEACLETypes.def"
// All other builtin types
#define BUILTIN_TYPE(Id, SingletonId) Id,
#define LAST_BUILTIN_TYPE(Id) LastKind = Id
@@ -2858,22 +2874,8 @@ private:
protected:
friend class ASTContext; // ASTContext creates these.
- // C++ [temp.dep.type]p1:
- // A type is dependent if it is...
- // - an array type constructed from any dependent type or whose
- // size is specified by a constant expression that is
- // value-dependent,
- ArrayType(TypeClass tc, QualType et, QualType can,
- ArraySizeModifier sm, unsigned tq,
- bool ContainsUnexpandedParameterPack)
- : Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
- et->isInstantiationDependentType() || tc == DependentSizedArray,
- (tc == VariableArray || et->isVariablyModifiedType()),
- ContainsUnexpandedParameterPack),
- ElementType(et) {
- ArrayTypeBits.IndexTypeQuals = tq;
- ArrayTypeBits.SizeModifier = sm;
- }
+ ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm,
+ unsigned tq, const Expr *sz = nullptr);
public:
QualType getElementType() const { return ElementType; }
@@ -2901,25 +2903,35 @@ public:
/// Represents the canonical version of C arrays with a specified constant size.
/// For example, the canonical type for 'int A[4 + 4*100]' is a
/// ConstantArrayType where the element type is 'int' and the size is 404.
-class ConstantArrayType : public ArrayType {
+class ConstantArrayType final
+ : public ArrayType,
+ private llvm::TrailingObjects<ConstantArrayType, const Expr *> {
+ friend class ASTContext; // ASTContext creates these.
+ friend TrailingObjects;
+
llvm::APInt Size; // Allows us to unique the type.
ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
- ArraySizeModifier sm, unsigned tq)
- : ArrayType(ConstantArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()),
- Size(size) {}
-
-protected:
- friend class ASTContext; // ASTContext creates these.
+ const Expr *sz, ArraySizeModifier sm, unsigned tq)
+ : ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) {
+ ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr;
+ if (ConstantArrayTypeBits.HasStoredSizeExpr) {
+ assert(!can.isNull() && "canonical constant array should not have size");
+ *getTrailingObjects<const Expr*>() = sz;
+ }
+ }
- ConstantArrayType(TypeClass tc, QualType et, QualType can,
- const llvm::APInt &size, ArraySizeModifier sm, unsigned tq)
- : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()),
- Size(size) {}
+ unsigned numTrailingObjects(OverloadToken<const Expr*>) const {
+ return ConstantArrayTypeBits.HasStoredSizeExpr;
+ }
public:
const llvm::APInt &getSize() const { return Size; }
+ const Expr *getSizeExpr() const {
+ return ConstantArrayTypeBits.HasStoredSizeExpr
+ ? *getTrailingObjects<const Expr *>()
+ : nullptr;
+ }
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -2933,19 +2945,15 @@ public:
/// can require, which limits the maximum size of the array.
static unsigned getMaxSizeBits(const ASTContext &Context);
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getSize(),
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
+ Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(),
getSizeModifier(), getIndexTypeCVRQualifiers());
}
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
- const llvm::APInt &ArraySize, ArraySizeModifier SizeMod,
- unsigned TypeQuals) {
- ID.AddPointer(ET.getAsOpaquePtr());
- ID.AddInteger(ArraySize.getZExtValue());
- ID.AddInteger(SizeMod);
- ID.AddInteger(TypeQuals);
- }
+ static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx,
+ QualType ET, const llvm::APInt &ArraySize,
+ const Expr *SizeExpr, ArraySizeModifier SizeMod,
+ unsigned TypeQuals);
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray;
@@ -2960,8 +2968,7 @@ class IncompleteArrayType : public ArrayType {
IncompleteArrayType(QualType et, QualType can,
ArraySizeModifier sm, unsigned tq)
- : ArrayType(IncompleteArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()) {}
+ : ArrayType(IncompleteArray, et, can, sm, tq) {}
public:
friend class StmtIteratorBase;
@@ -3013,8 +3020,7 @@ class VariableArrayType : public ArrayType {
VariableArrayType(QualType et, QualType can, Expr *e,
ArraySizeModifier sm, unsigned tq,
SourceRange brackets)
- : ArrayType(VariableArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()),
+ : ArrayType(VariableArray, et, can, sm, tq, e),
SizeExpr((Stmt*) e), Brackets(brackets) {}
public:
@@ -4429,7 +4435,7 @@ public:
bool isBeingDefined() const;
static bool classof(const Type *T) {
- return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
+ return T->getTypeClass() == Enum || T->getTypeClass() == Record;
}
};
@@ -5563,7 +5569,7 @@ class ObjCTypeParamType : public Type,
public:
bool isSugared() const { return true; }
- QualType desugar() const { return getCanonicalTypeInternal(); }
+ QualType desugar() const;
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCTypeParam;
@@ -6347,6 +6353,7 @@ inline bool QualType::isCForbiddenLValueType() const {
/// \returns True for types specified in C++0x [basic.fundamental].
inline bool Type::isFundamentalType() const {
return isVoidType() ||
+ isNullPtrType() ||
// FIXME: It's really annoying that we don't have an
// 'isArithmeticType()' which agrees with the standard definition.
(isArithmeticType() && !isEnumeralType());
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 40d17f991f1f..f305680d775c 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -106,7 +106,7 @@ public:
#define ABSTRACT_TYPE(Class, Base)
#define TYPE(Class, Base) \
Class = Type::Class,
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
Qualified
};
diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
index c0dfe150d6cc..81448c7e7ce5 100644
--- a/include/clang/AST/TypeLocNodes.def
+++ b/include/clang/AST/TypeLocNodes.def
@@ -31,7 +31,7 @@
TYPELOC(Qualified, TypeLoc)
#define TYPE(Class, Base) UNQUAL_TYPELOC(Class, Base##Loc)
#define ABSTRACT_TYPE(Class, Base) ABSTRACT_TYPELOC(Class, Base##Loc)
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
#undef DECLARATOR_TYPELOC
#undef TYPESPEC_TYPELOC
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
deleted file mode 100644
index 58a5f880cbe6..000000000000
--- a/include/clang/AST/TypeNodes.def
+++ /dev/null
@@ -1,135 +0,0 @@
-//===-- TypeNodes.def - Metadata about Type AST nodes -----------*- 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 defines the AST type info database. Each type node is
-// enumerated by providing its name (e.g., "Builtin" or "Enum") and
-// base class (e.g., "Type" or "TagType"). Depending on where in the
-// abstract syntax tree the type will show up, the enumeration uses
-// one of five different macros:
-//
-// TYPE(Class, Base) - A type that can show up anywhere in the AST,
-// and might be dependent, canonical, or non-canonical. All clients
-// will need to understand these types.
-//
-// ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
-// the type hierarchy but has no concrete instances.
-//
-// NON_CANONICAL_TYPE(Class, Base) - A type that can show up
-// anywhere in the AST but will never be a part of a canonical
-// type. Clients that only need to deal with canonical types
-// (ignoring, e.g., typedefs and other type aliases used for
-// pretty-printing) can ignore these types.
-//
-// DEPENDENT_TYPE(Class, Base) - A type that will only show up
-// within a C++ template that has not been instantiated, e.g., a
-// type that is always dependent. Clients that do not need to deal
-// with uninstantiated C++ templates can ignore these types.
-//
-// NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
-// is non-canonical unless it is dependent. Defaults to TYPE because
-// it is neither reliably dependent nor reliably non-canonical.
-//
-// There is a sixth macro, independent of the others. Most clients
-// will not need to use it.
-//
-// LEAF_TYPE(Class) - A type that never has inner types. Clients
-// which can operate on such types more efficiently may wish to do so.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ABSTRACT_TYPE
-# define ABSTRACT_TYPE(Class, Base) TYPE(Class, Base)
-#endif
-
-#ifndef NON_CANONICAL_TYPE
-# define NON_CANONICAL_TYPE(Class, Base) TYPE(Class, Base)
-#endif
-
-#ifndef DEPENDENT_TYPE
-# define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
-#endif
-
-#ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
-# define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
-#endif
-
-TYPE(Builtin, Type)
-TYPE(Complex, Type)
-TYPE(Pointer, Type)
-TYPE(BlockPointer, Type)
-ABSTRACT_TYPE(Reference, Type)
-TYPE(LValueReference, ReferenceType)
-TYPE(RValueReference, ReferenceType)
-TYPE(MemberPointer, Type)
-ABSTRACT_TYPE(Array, Type)
-TYPE(ConstantArray, ArrayType)
-TYPE(IncompleteArray, ArrayType)
-TYPE(VariableArray, ArrayType)
-DEPENDENT_TYPE(DependentSizedArray, ArrayType)
-DEPENDENT_TYPE(DependentSizedExtVector, Type)
-DEPENDENT_TYPE(DependentAddressSpace, Type)
-TYPE(Vector, Type)
-DEPENDENT_TYPE(DependentVector, Type)
-TYPE(ExtVector, VectorType)
-ABSTRACT_TYPE(Function, Type)
-TYPE(FunctionProto, FunctionType)
-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)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(UnaryTransform, Type)
-ABSTRACT_TYPE(Tag, Type)
-TYPE(Record, TagType)
-TYPE(Enum, TagType)
-NON_CANONICAL_TYPE(Elaborated, Type)
-NON_CANONICAL_TYPE(Attributed, Type)
-DEPENDENT_TYPE(TemplateTypeParm, Type)
-NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
-DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
-ABSTRACT_TYPE(Deduced, Type)
-TYPE(Auto, DeducedType)
-TYPE(DeducedTemplateSpecialization, DeducedType)
-DEPENDENT_TYPE(InjectedClassName, Type)
-DEPENDENT_TYPE(DependentName, Type)
-DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type)
-NON_CANONICAL_TYPE(ObjCTypeParam, Type)
-TYPE(ObjCObject, Type)
-TYPE(ObjCInterface, ObjCObjectType)
-TYPE(ObjCObjectPointer, Type)
-TYPE(Pipe, Type)
-TYPE(Atomic, Type)
-
-#ifdef LAST_TYPE
-LAST_TYPE(Atomic)
-#undef LAST_TYPE
-#endif
-
-// These types are always leaves in the type hierarchy.
-#ifdef LEAF_TYPE
-LEAF_TYPE(Enum)
-LEAF_TYPE(Builtin)
-LEAF_TYPE(Record)
-LEAF_TYPE(InjectedClassName)
-LEAF_TYPE(ObjCInterface)
-LEAF_TYPE(TemplateTypeParm)
-#undef LEAF_TYPE
-#endif
-
-#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
-#undef DEPENDENT_TYPE
-#undef NON_CANONICAL_TYPE
-#undef ABSTRACT_TYPE
-#undef TYPE
diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h
index 8930ec853949..17301835fb18 100644
--- a/include/clang/AST/TypeVisitor.h
+++ b/include/clang/AST/TypeVisitor.h
@@ -70,7 +70,7 @@ public:
switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, PARENT)
#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type);
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
}
llvm_unreachable("Unknown type class!");
}
@@ -80,7 +80,7 @@ public:
#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(const CLASS##Type *T) { \
DISPATCH(PARENT); \
}
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
/// Method called if \c ImpClass doesn't provide specific handler
/// for some type class.