summaryrefslogtreecommitdiffstats
path: root/include/clang/AST
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/APValue.h452
-rw-r--r--include/clang/AST/AST.h28
-rw-r--r--include/clang/AST/ASTConsumer.h159
-rw-r--r--include/clang/AST/ASTContext.h2672
-rw-r--r--include/clang/AST/ASTDiagnostic.h47
-rw-r--r--include/clang/AST/ASTFwd.h33
-rw-r--r--include/clang/AST/ASTImporter.h295
-rw-r--r--include/clang/AST/ASTLambda.h80
-rw-r--r--include/clang/AST/ASTMutationListener.h127
-rw-r--r--include/clang/AST/ASTTypeTraits.h509
-rw-r--r--include/clang/AST/ASTUnresolvedSet.h110
-rw-r--r--include/clang/AST/ASTVector.h405
-rw-r--r--include/clang/AST/Attr.h169
-rw-r--r--include/clang/AST/AttrIterator.h142
-rw-r--r--include/clang/AST/BaseSubobject.h87
-rw-r--r--include/clang/AST/BuiltinTypes.def261
-rw-r--r--include/clang/AST/CMakeLists.txt52
-rw-r--r--include/clang/AST/CXXInheritance.h365
-rw-r--r--include/clang/AST/CanonicalType.h665
-rw-r--r--include/clang/AST/CharUnits.h240
-rw-r--r--include/clang/AST/Comment.h1142
-rw-r--r--include/clang/AST/CommentBriefParser.h55
-rw-r--r--include/clang/AST/CommentCommandTraits.h189
-rw-r--r--include/clang/AST/CommentCommands.td241
-rw-r--r--include/clang/AST/CommentDiagnostic.h29
-rw-r--r--include/clang/AST/CommentHTMLNamedCharacterReferences.td177
-rw-r--r--include/clang/AST/CommentHTMLTags.td67
-rw-r--r--include/clang/AST/CommentLexer.h362
-rw-r--r--include/clang/AST/CommentParser.h123
-rw-r--r--include/clang/AST/CommentSema.h254
-rw-r--r--include/clang/AST/CommentVisitor.h70
-rw-r--r--include/clang/AST/Decl.h3801
-rw-r--r--include/clang/AST/DeclAccessPair.h72
-rw-r--r--include/clang/AST/DeclBase.h1904
-rw-r--r--include/clang/AST/DeclCXX.h3249
-rw-r--r--include/clang/AST/DeclContextInternals.h264
-rw-r--r--include/clang/AST/DeclFriend.h243
-rw-r--r--include/clang/AST/DeclGroup.h154
-rw-r--r--include/clang/AST/DeclLookups.h115
-rw-r--r--include/clang/AST/DeclObjC.h2742
-rw-r--r--include/clang/AST/DeclOpenMP.h91
-rw-r--r--include/clang/AST/DeclTemplate.h2927
-rw-r--r--include/clang/AST/DeclVisitor.h79
-rw-r--r--include/clang/AST/DeclarationName.h598
-rw-r--r--include/clang/AST/DependentDiagnostic.h189
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h129
-rw-r--r--include/clang/AST/Expr.h4941
-rw-r--r--include/clang/AST/ExprCXX.h4179
-rw-r--r--include/clang/AST/ExprObjC.h1568
-rw-r--r--include/clang/AST/ExprOpenMP.h129
-rw-r--r--include/clang/AST/ExternalASTSource.h578
-rw-r--r--include/clang/AST/GlobalDecl.h125
-rw-r--r--include/clang/AST/LambdaCapture.h128
-rw-r--r--include/clang/AST/Makefile79
-rw-r--r--include/clang/AST/Mangle.h243
-rw-r--r--include/clang/AST/MangleNumberingContext.h60
-rw-r--r--include/clang/AST/NSAPI.h262
-rw-r--r--include/clang/AST/NestedNameSpecifier.h516
-rw-r--r--include/clang/AST/OpenMPClause.h3198
-rw-r--r--include/clang/AST/OperationKinds.h356
-rw-r--r--include/clang/AST/ParentMap.h67
-rw-r--r--include/clang/AST/PrettyPrinter.h175
-rw-r--r--include/clang/AST/RawCommentList.h203
-rw-r--r--include/clang/AST/RecordLayout.h315
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h2805
-rw-r--r--include/clang/AST/Redeclarable.h285
-rw-r--r--include/clang/AST/SelectorLocationsKind.h83
-rw-r--r--include/clang/AST/Stmt.h2196
-rw-r--r--include/clang/AST/StmtCXX.h417
-rw-r--r--include/clang/AST/StmtGraphTraits.h83
-rw-r--r--include/clang/AST/StmtIterator.h144
-rw-r--r--include/clang/AST/StmtObjC.h375
-rw-r--r--include/clang/AST/StmtOpenMP.h2422
-rw-r--r--include/clang/AST/StmtVisitor.h227
-rw-r--r--include/clang/AST/TemplateBase.h661
-rw-r--r--include/clang/AST/TemplateName.h533
-rw-r--r--include/clang/AST/Type.h5683
-rw-r--r--include/clang/AST/TypeLoc.h2039
-rw-r--r--include/clang/AST/TypeLocNodes.def41
-rw-r--r--include/clang/AST/TypeLocVisitor.h62
-rw-r--r--include/clang/AST/TypeNodes.def129
-rw-r--r--include/clang/AST/TypeOrdering.h79
-rw-r--r--include/clang/AST/TypeVisitor.h95
-rw-r--r--include/clang/AST/UnresolvedSet.h140
-rw-r--r--include/clang/AST/VTTBuilder.h162
-rw-r--r--include/clang/AST/VTableBuilder.h566
86 files changed, 0 insertions, 62513 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
deleted file mode 100644
index e58c219..0000000
--- a/include/clang/AST/APValue.h
+++ /dev/null
@@ -1,452 +0,0 @@
-//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the APValue class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_APVALUE_H
-#define LLVM_CLANG_AST_APVALUE_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-
-namespace clang {
- class AddrLabelExpr;
- class ASTContext;
- class CharUnits;
- class DiagnosticBuilder;
- class Expr;
- class FieldDecl;
- class Decl;
- class ValueDecl;
- class CXXRecordDecl;
- class QualType;
-
-/// APValue - This class implements a discriminated union of [uninitialized]
-/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
-/// [Vector: N * APValue], [Array: N * APValue]
-class APValue {
- typedef llvm::APSInt APSInt;
- typedef llvm::APFloat APFloat;
-public:
- enum ValueKind {
- Uninitialized,
- Int,
- Float,
- ComplexInt,
- ComplexFloat,
- LValue,
- Vector,
- Array,
- Struct,
- Union,
- MemberPointer,
- AddrLabelDiff
- };
- typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
- typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
- union LValuePathEntry {
- /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
- /// in the path. An opaque value of type BaseOrMemberType.
- void *BaseOrMember;
- /// ArrayIndex - The array index of the next item in the path.
- uint64_t ArrayIndex;
- };
- struct NoLValuePath {};
- struct UninitArray {};
- struct UninitStruct {};
-private:
- ValueKind Kind;
-
- struct ComplexAPSInt {
- APSInt Real, Imag;
- ComplexAPSInt() : Real(1), Imag(1) {}
- };
- struct ComplexAPFloat {
- APFloat Real, Imag;
- ComplexAPFloat() : Real(0.0), Imag(0.0) {}
- };
- struct LV;
- struct Vec {
- APValue *Elts;
- unsigned NumElts;
- Vec() : Elts(nullptr), NumElts(0) {}
- ~Vec() { delete[] Elts; }
- };
- struct Arr {
- APValue *Elts;
- unsigned NumElts, ArrSize;
- Arr(unsigned NumElts, unsigned ArrSize);
- ~Arr();
- };
- struct StructData {
- APValue *Elts;
- unsigned NumBases;
- unsigned NumFields;
- StructData(unsigned NumBases, unsigned NumFields);
- ~StructData();
- };
- struct UnionData {
- const FieldDecl *Field;
- APValue *Value;
- UnionData();
- ~UnionData();
- };
- struct AddrLabelDiffData {
- const AddrLabelExpr* LHSExpr;
- const AddrLabelExpr* RHSExpr;
- };
- struct MemberPointerData;
-
- // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
- typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
- ComplexAPFloat, Vec, Arr, StructData,
- UnionData, AddrLabelDiffData> DataType;
- static const size_t DataSize = sizeof(DataType);
-
- DataType Data;
-
-public:
- APValue() : Kind(Uninitialized) {}
- explicit APValue(APSInt I) : Kind(Uninitialized) {
- MakeInt(); setInt(std::move(I));
- }
- explicit APValue(APFloat F) : Kind(Uninitialized) {
- MakeFloat(); setFloat(std::move(F));
- }
- explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
- MakeVector(); setVector(E, N);
- }
- APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
- MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
- }
- APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
- MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
- }
- APValue(const APValue &RHS);
- APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
- APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
- : Kind(Uninitialized) {
- MakeLValue(); setLValue(B, O, N, CallIndex);
- }
- APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
- bool OnePastTheEnd, unsigned CallIndex)
- : Kind(Uninitialized) {
- MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
- }
- APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
- MakeArray(InitElts, Size);
- }
- APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
- MakeStruct(B, M);
- }
- explicit APValue(const FieldDecl *D, const APValue &V = APValue())
- : Kind(Uninitialized) {
- MakeUnion(); setUnion(D, V);
- }
- APValue(const ValueDecl *Member, bool IsDerivedMember,
- ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
- MakeMemberPointer(Member, IsDerivedMember, Path);
- }
- APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
- : Kind(Uninitialized) {
- MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
- }
-
- ~APValue() {
- MakeUninit();
- }
-
- /// \brief Returns whether the object performed allocations.
- ///
- /// If APValues are constructed via placement new, \c needsCleanup()
- /// indicates whether the destructor must be called in order to correctly
- /// free all allocated memory.
- bool needsCleanup() const;
-
- /// \brief Swaps the contents of this and the given APValue.
- void swap(APValue &RHS);
-
- ValueKind getKind() const { return Kind; }
- bool isUninit() const { return Kind == Uninitialized; }
- bool isInt() const { return Kind == Int; }
- bool isFloat() const { return Kind == Float; }
- bool isComplexInt() const { return Kind == ComplexInt; }
- bool isComplexFloat() const { return Kind == ComplexFloat; }
- bool isLValue() const { return Kind == LValue; }
- bool isVector() const { return Kind == Vector; }
- bool isArray() const { return Kind == Array; }
- bool isStruct() const { return Kind == Struct; }
- bool isUnion() const { return Kind == Union; }
- bool isMemberPointer() const { return Kind == MemberPointer; }
- bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
-
- void dump() const;
- void dump(raw_ostream &OS) const;
-
- void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
- std::string getAsString(ASTContext &Ctx, QualType Ty) const;
-
- APSInt &getInt() {
- assert(isInt() && "Invalid accessor");
- return *(APSInt*)(char*)Data.buffer;
- }
- const APSInt &getInt() const {
- return const_cast<APValue*>(this)->getInt();
- }
-
- APFloat &getFloat() {
- assert(isFloat() && "Invalid accessor");
- return *(APFloat*)(char*)Data.buffer;
- }
- const APFloat &getFloat() const {
- return const_cast<APValue*>(this)->getFloat();
- }
-
- APSInt &getComplexIntReal() {
- assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
- }
- const APSInt &getComplexIntReal() const {
- return const_cast<APValue*>(this)->getComplexIntReal();
- }
-
- APSInt &getComplexIntImag() {
- assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
- }
- const APSInt &getComplexIntImag() const {
- return const_cast<APValue*>(this)->getComplexIntImag();
- }
-
- APFloat &getComplexFloatReal() {
- assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
- }
- const APFloat &getComplexFloatReal() const {
- return const_cast<APValue*>(this)->getComplexFloatReal();
- }
-
- APFloat &getComplexFloatImag() {
- assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
- }
- const APFloat &getComplexFloatImag() const {
- return const_cast<APValue*>(this)->getComplexFloatImag();
- }
-
- const LValueBase getLValueBase() const;
- CharUnits &getLValueOffset();
- const CharUnits &getLValueOffset() const {
- return const_cast<APValue*>(this)->getLValueOffset();
- }
- bool isLValueOnePastTheEnd() const;
- bool hasLValuePath() const;
- ArrayRef<LValuePathEntry> getLValuePath() const;
- unsigned getLValueCallIndex() const;
-
- APValue &getVectorElt(unsigned I) {
- assert(isVector() && "Invalid accessor");
- assert(I < getVectorLength() && "Index out of range");
- return ((Vec*)(char*)Data.buffer)->Elts[I];
- }
- const APValue &getVectorElt(unsigned I) const {
- return const_cast<APValue*>(this)->getVectorElt(I);
- }
- unsigned getVectorLength() const {
- assert(isVector() && "Invalid accessor");
- return ((const Vec*)(const void *)Data.buffer)->NumElts;
- }
-
- APValue &getArrayInitializedElt(unsigned I) {
- assert(isArray() && "Invalid accessor");
- assert(I < getArrayInitializedElts() && "Index out of range");
- return ((Arr*)(char*)Data.buffer)->Elts[I];
- }
- const APValue &getArrayInitializedElt(unsigned I) const {
- return const_cast<APValue*>(this)->getArrayInitializedElt(I);
- }
- bool hasArrayFiller() const {
- return getArrayInitializedElts() != getArraySize();
- }
- APValue &getArrayFiller() {
- assert(isArray() && "Invalid accessor");
- assert(hasArrayFiller() && "No array filler");
- return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
- }
- const APValue &getArrayFiller() const {
- return const_cast<APValue*>(this)->getArrayFiller();
- }
- unsigned getArrayInitializedElts() const {
- assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data.buffer)->NumElts;
- }
- unsigned getArraySize() const {
- assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data.buffer)->ArrSize;
- }
-
- unsigned getStructNumBases() const {
- assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data.buffer)->NumBases;
- }
- unsigned getStructNumFields() const {
- assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data.buffer)->NumFields;
- }
- APValue &getStructBase(unsigned i) {
- assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data.buffer)->Elts[i];
- }
- APValue &getStructField(unsigned i) {
- assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
- }
- const APValue &getStructBase(unsigned i) const {
- return const_cast<APValue*>(this)->getStructBase(i);
- }
- const APValue &getStructField(unsigned i) const {
- return const_cast<APValue*>(this)->getStructField(i);
- }
-
- const FieldDecl *getUnionField() const {
- assert(isUnion() && "Invalid accessor");
- return ((const UnionData*)(const char*)Data.buffer)->Field;
- }
- APValue &getUnionValue() {
- assert(isUnion() && "Invalid accessor");
- return *((UnionData*)(char*)Data.buffer)->Value;
- }
- const APValue &getUnionValue() const {
- return const_cast<APValue*>(this)->getUnionValue();
- }
-
- const ValueDecl *getMemberPointerDecl() const;
- bool isMemberPointerToDerivedMember() const;
- ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
-
- const AddrLabelExpr* getAddrLabelDiffLHS() const {
- assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
- }
- const AddrLabelExpr* getAddrLabelDiffRHS() const {
- assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
- }
-
- void setInt(APSInt I) {
- assert(isInt() && "Invalid accessor");
- *(APSInt *)(char *)Data.buffer = std::move(I);
- }
- void setFloat(APFloat F) {
- assert(isFloat() && "Invalid accessor");
- *(APFloat *)(char *)Data.buffer = std::move(F);
- }
- void setVector(const APValue *E, unsigned N) {
- assert(isVector() && "Invalid accessor");
- ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
- ((Vec*)(char*)Data.buffer)->NumElts = N;
- for (unsigned i = 0; i != N; ++i)
- ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
- }
- void setComplexInt(APSInt R, APSInt I) {
- assert(R.getBitWidth() == I.getBitWidth() &&
- "Invalid complex int (type mismatch).");
- assert(isComplexInt() && "Invalid accessor");
- ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
- ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
- }
- void setComplexFloat(APFloat R, APFloat I) {
- assert(&R.getSemantics() == &I.getSemantics() &&
- "Invalid complex float (type mismatch).");
- assert(isComplexFloat() && "Invalid accessor");
- ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
- ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
- }
- void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
- unsigned CallIndex);
- void setLValue(LValueBase B, const CharUnits &O,
- ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
- unsigned CallIndex);
- void setUnion(const FieldDecl *Field, const APValue &Value) {
- assert(isUnion() && "Invalid accessor");
- ((UnionData*)(char*)Data.buffer)->Field = Field;
- *((UnionData*)(char*)Data.buffer)->Value = Value;
- }
- void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
- const AddrLabelExpr* RHSExpr) {
- ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
- ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
- }
-
- /// Assign by swapping from a copy of the RHS.
- APValue &operator=(APValue RHS) {
- swap(RHS);
- return *this;
- }
-
-private:
- void DestroyDataAndMakeUninit();
- void MakeUninit() {
- if (Kind != Uninitialized)
- DestroyDataAndMakeUninit();
- }
- void MakeInt() {
- assert(isUninit() && "Bad state change");
- new ((void*)Data.buffer) APSInt(1);
- Kind = Int;
- }
- void MakeFloat() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) APFloat(0.0);
- Kind = Float;
- }
- void MakeVector() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) Vec();
- Kind = Vector;
- }
- void MakeComplexInt() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) ComplexAPSInt();
- Kind = ComplexInt;
- }
- void MakeComplexFloat() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) ComplexAPFloat();
- Kind = ComplexFloat;
- }
- void MakeLValue();
- void MakeArray(unsigned InitElts, unsigned Size);
- void MakeStruct(unsigned B, unsigned M) {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) StructData(B, M);
- Kind = Struct;
- }
- void MakeUnion() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) UnionData();
- Kind = Union;
- }
- void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
- ArrayRef<const CXXRecordDecl*> Path);
- void MakeAddrLabelDiff() {
- assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data.buffer) AddrLabelDiffData();
- Kind = AddrLabelDiff;
- }
-};
-
-} // end namespace clang.
-
-#endif
diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h
deleted file mode 100644
index 6db351d..0000000
--- a/include/clang/AST/AST.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- AST.h - "Umbrella" header for AST library --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface to the AST classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_AST_H
-#define LLVM_CLANG_AST_AST_H
-
-// This header exports all AST interfaces.
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/Type.h"
-
-#endif
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
deleted file mode 100644
index b2730e4..0000000
--- a/include/clang/AST/ASTConsumer.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ASTConsumer class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTCONSUMER_H
-#define LLVM_CLANG_AST_ASTCONSUMER_H
-
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
- class ASTContext;
- class CXXMethodDecl;
- class CXXRecordDecl;
- class Decl;
- class DeclGroupRef;
- class ASTMutationListener;
- class ASTDeserializationListener; // layering violation because void* is ugly
- class SemaConsumer; // layering violation required for safe SemaConsumer
- class TagDecl;
- class VarDecl;
- class FunctionDecl;
- class ImportDecl;
-
-/// ASTConsumer - This is an abstract interface that should be implemented by
-/// clients that read ASTs. This abstraction layer allows the client to be
-/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
-class ASTConsumer {
- /// \brief Whether this AST consumer also requires information about
- /// semantic analysis.
- bool SemaConsumer;
-
- friend class SemaConsumer;
-
-public:
- ASTConsumer() : SemaConsumer(false) { }
-
- virtual ~ASTConsumer() {}
-
- /// Initialize - This is called to initialize the consumer, providing the
- /// ASTContext.
- virtual void Initialize(ASTContext &Context) {}
-
- /// HandleTopLevelDecl - Handle the specified top-level declaration. This is
- /// called by the parser to process every top-level Decl*.
- ///
- /// \returns true to continue parsing, or false to abort parsing.
- virtual bool HandleTopLevelDecl(DeclGroupRef D);
-
- /// \brief This callback is invoked each time an inline method definition is
- /// completed.
- virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {}
-
- /// HandleInterestingDecl - Handle the specified interesting declaration. This
- /// is called by the AST reader when deserializing things that might interest
- /// the consumer. The default implementation forwards to HandleTopLevelDecl.
- virtual void HandleInterestingDecl(DeclGroupRef D);
-
- /// HandleTranslationUnit - This method is called when the ASTs for entire
- /// translation unit have been parsed.
- virtual void HandleTranslationUnit(ASTContext &Ctx) {}
-
- /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
- /// (e.g. struct, union, enum, class) is completed. This allows the client to
- /// hack on the type, which can occur at any point in the file (because these
- /// can be defined in declspecs).
- virtual void HandleTagDeclDefinition(TagDecl *D) {}
-
- /// \brief This callback is invoked the first time each TagDecl is required to
- /// be complete.
- virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
-
- /// \brief Invoked when a function is implicitly instantiated.
- /// Note that at this point point it does not have a body, its body is
- /// instantiated at the end of the translation unit and passed to
- /// HandleTopLevelDecl.
- virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
-
- /// \brief Handle the specified top-level declaration that occurred inside
- /// and ObjC container.
- /// The default implementation ignored them.
- virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
-
- /// \brief Handle an ImportDecl that was implicitly created due to an
- /// inclusion directive.
- /// The default implementation passes it to HandleTopLevelDecl.
- virtual void HandleImplicitImportDecl(ImportDecl *D);
-
- /// \brief Handle a pragma that appends to Linker Options. Currently this
- /// only exists to support Microsoft's #pragma comment(linker, "/foo").
- virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {}
-
- /// \brief Handle a pragma that emits a mismatch identifier and value to the
- /// object file for the linker to work with. Currently, this only exists to
- /// support Microsoft's #pragma detect_mismatch.
- virtual void HandleDetectMismatch(llvm::StringRef Name,
- llvm::StringRef Value) {}
-
- /// \brief Handle a dependent library created by a pragma in the source.
- /// Currently this only exists to support Microsoft's
- /// #pragma comment(lib, "/foo").
- virtual void HandleDependentLibrary(llvm::StringRef Lib) {}
-
- /// CompleteTentativeDefinition - Callback invoked at the end of a translation
- /// unit to notify the consumer that the given tentative definition should be
- /// completed.
- ///
- /// The variable declaration itself will be a tentative
- /// definition. If it had an incomplete array type, its type will
- /// have already been changed to an array of size 1. However, the
- /// declaration remains a tentative definition and has not been
- /// modified by the introduction of an implicit zero initializer.
- virtual void CompleteTentativeDefinition(VarDecl *D) {}
-
- /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
- // variable has been instantiated.
- virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
-
- /// \brief Callback involved at the end of a translation unit to
- /// notify the consumer that a vtable for the given C++ class is
- /// required.
- ///
- /// \param RD The class whose vtable was used.
- virtual void HandleVTable(CXXRecordDecl *RD) {}
-
- /// \brief If the consumer is interested in entities getting modified after
- /// their initial creation, it should return a pointer to
- /// an ASTMutationListener here.
- virtual ASTMutationListener *GetASTMutationListener() { return nullptr; }
-
- /// \brief If the consumer is interested in entities being deserialized from
- /// AST files, it should return a pointer to a ASTDeserializationListener here
- virtual ASTDeserializationListener *GetASTDeserializationListener() {
- return nullptr;
- }
-
- /// PrintStats - If desired, print any statistics.
- virtual void PrintStats() {}
-
- /// \brief This callback is called for each function if the Parser was
- /// initialized with \c SkipFunctionBodies set to \c true.
- ///
- /// \return \c true if the function's body should be skipped. The function
- /// body may be parsed anyway if it is needed (for instance, if it contains
- /// the code completion point or is constexpr).
- virtual bool shouldSkipFunctionBody(Decl *D) { return true; }
-};
-
-} // end namespace clang.
-
-#endif
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
deleted file mode 100644
index b66009e..0000000
--- a/include/clang/AST/ASTContext.h
+++ /dev/null
@@ -1,2672 +0,0 @@
-//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the clang::ASTContext interface.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
-#define LLVM_CLANG_AST_ASTCONTEXT_H
-
-#include "clang/AST/ASTTypeTraits.h"
-#include "clang/AST/CanonicalType.h"
-#include "clang/AST/CommentCommandTraits.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/RawCommentList.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/Module.h"
-#include "clang/Basic/OperatorKinds.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/SanitizerBlacklist.h"
-#include "clang/Basic/VersionTuple.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Support/Allocator.h"
-#include <memory>
-#include <vector>
-
-namespace llvm {
- struct fltSemantics;
-}
-
-namespace clang {
- class FileManager;
- class AtomicExpr;
- class ASTRecordLayout;
- class BlockExpr;
- class CharUnits;
- class DiagnosticsEngine;
- class Expr;
- class ASTMutationListener;
- class IdentifierTable;
- class MaterializeTemporaryExpr;
- class SelectorTable;
- class TargetInfo;
- class CXXABI;
- class MangleNumberingContext;
- // Decls
- class MangleContext;
- class ObjCIvarDecl;
- class ObjCPropertyDecl;
- class UnresolvedSetIterator;
- class UsingDecl;
- class UsingShadowDecl;
- class VTableContextBase;
-
- namespace Builtin { class Context; }
- enum BuiltinTemplateKind : int;
-
- namespace comments {
- class FullComment;
- }
-
- struct TypeInfo {
- uint64_t Width;
- unsigned Align;
- bool AlignIsRequired : 1;
- TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
- TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
- : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
- };
-
-/// \brief Holds long-lived AST nodes (such as types and decls) that can be
-/// referred to throughout the semantic analysis of a file.
-class ASTContext : public RefCountedBase<ASTContext> {
- ASTContext &this_() { return *this; }
-
- mutable SmallVector<Type *, 0> Types;
- mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
- mutable llvm::FoldingSet<ComplexType> ComplexTypes;
- mutable llvm::FoldingSet<PointerType> PointerTypes;
- mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
- mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
- mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
- mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
- mutable llvm::FoldingSet<MemberPointerType> MemberPointerTypes;
- mutable llvm::FoldingSet<ConstantArrayType> ConstantArrayTypes;
- mutable llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
- mutable std::vector<VariableArrayType*> VariableArrayTypes;
- mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
- mutable llvm::FoldingSet<DependentSizedExtVectorType>
- DependentSizedExtVectorTypes;
- mutable llvm::FoldingSet<VectorType> VectorTypes;
- mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
- mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
- FunctionProtoTypes;
- mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
- mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
- mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
- mutable llvm::FoldingSet<SubstTemplateTypeParmType>
- SubstTemplateTypeParmTypes;
- mutable llvm::FoldingSet<SubstTemplateTypeParmPackType>
- SubstTemplateTypeParmPackTypes;
- mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
- TemplateSpecializationTypes;
- mutable llvm::FoldingSet<ParenType> ParenTypes;
- mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
- mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
- mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
- ASTContext&>
- DependentTemplateSpecializationTypes;
- llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
- mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
- mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
- mutable llvm::FoldingSet<AutoType> AutoTypes;
- mutable llvm::FoldingSet<AtomicType> AtomicTypes;
- llvm::FoldingSet<AttributedType> AttributedTypes;
-
- mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
- mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
- mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage>
- SubstTemplateTemplateParms;
- mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage,
- ASTContext&>
- SubstTemplateTemplateParmPacks;
-
- /// \brief The set of nested name specifiers.
- ///
- /// This set is managed by the NestedNameSpecifier class.
- mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
- mutable NestedNameSpecifier *GlobalNestedNameSpecifier;
- friend class NestedNameSpecifier;
-
- /// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
- ///
- /// This is lazily created. This is intentionally not serialized.
- mutable llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>
- ASTRecordLayouts;
- mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>
- ObjCLayouts;
-
- /// \brief A cache from types to size and alignment information.
- typedef llvm::DenseMap<const Type *, struct TypeInfo> TypeInfoMap;
- mutable TypeInfoMap MemoizedTypeInfo;
-
- /// \brief A cache mapping from CXXRecordDecls to key functions.
- llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions;
-
- /// \brief Mapping from ObjCContainers to their ObjCImplementations.
- llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
-
- /// \brief Mapping from ObjCMethod to its duplicate declaration in the same
- /// interface.
- llvm::DenseMap<const ObjCMethodDecl*,const ObjCMethodDecl*> ObjCMethodRedecls;
-
- /// \brief Mapping from __block VarDecls to their copy initialization expr.
- llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
-
- /// \brief Mapping from class scope functions specialization to their
- /// template patterns.
- llvm::DenseMap<const FunctionDecl*, FunctionDecl*>
- ClassScopeSpecializationPattern;
-
- /// \brief Mapping from materialized temporaries with static storage duration
- /// that appear in constant initializers to their evaluated values. These are
- /// allocated in a std::map because their address must be stable.
- llvm::DenseMap<const MaterializeTemporaryExpr *, APValue *>
- MaterializedTemporaryValues;
-
- /// \brief Representation of a "canonical" template template parameter that
- /// is used in canonical template names.
- class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
- TemplateTemplateParmDecl *Parm;
-
- public:
- CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
- : Parm(Parm) { }
-
- TemplateTemplateParmDecl *getParam() const { return Parm; }
-
- void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); }
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- TemplateTemplateParmDecl *Parm);
- };
- mutable llvm::FoldingSet<CanonicalTemplateTemplateParm>
- CanonTemplateTemplateParms;
-
- TemplateTemplateParmDecl *
- getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
-
- /// \brief The typedef for the __int128_t type.
- mutable TypedefDecl *Int128Decl;
-
- /// \brief The typedef for the __uint128_t type.
- mutable TypedefDecl *UInt128Decl;
-
- /// \brief The typedef for the __float128 stub type.
- mutable TypeDecl *Float128StubDecl;
-
- /// \brief The typedef for the target specific predefined
- /// __builtin_va_list type.
- mutable TypedefDecl *BuiltinVaListDecl;
-
- /// The typedef for the predefined \c __builtin_ms_va_list type.
- mutable TypedefDecl *BuiltinMSVaListDecl;
-
- /// \brief The typedef for the predefined \c id type.
- mutable TypedefDecl *ObjCIdDecl;
-
- /// \brief The typedef for the predefined \c SEL type.
- mutable TypedefDecl *ObjCSelDecl;
-
- /// \brief The typedef for the predefined \c Class type.
- mutable TypedefDecl *ObjCClassDecl;
-
- /// \brief The typedef for the predefined \c Protocol class in Objective-C.
- mutable ObjCInterfaceDecl *ObjCProtocolClassDecl;
-
- /// \brief The typedef for the predefined 'BOOL' type.
- mutable TypedefDecl *BOOLDecl;
-
- // Typedefs which may be provided defining the structure of Objective-C
- // pseudo-builtins
- QualType ObjCIdRedefinitionType;
- QualType ObjCClassRedefinitionType;
- QualType ObjCSelRedefinitionType;
-
- /// The identifier 'NSObject'.
- IdentifierInfo *NSObjectName = nullptr;
-
- /// The identifier 'NSCopying'.
- IdentifierInfo *NSCopyingName = nullptr;
-
- /// The identifier '__make_integer_seq'.
- mutable IdentifierInfo *MakeIntegerSeqName = nullptr;
-
- QualType ObjCConstantStringType;
- mutable RecordDecl *CFConstantStringTypeDecl;
-
- mutable QualType ObjCSuperType;
-
- QualType ObjCNSStringType;
-
- /// \brief The typedef declaration for the Objective-C "instancetype" type.
- TypedefDecl *ObjCInstanceTypeDecl;
-
- /// \brief The type for the C FILE type.
- TypeDecl *FILEDecl;
-
- /// \brief The type for the C jmp_buf type.
- TypeDecl *jmp_bufDecl;
-
- /// \brief The type for the C sigjmp_buf type.
- TypeDecl *sigjmp_bufDecl;
-
- /// \brief The type for the C ucontext_t type.
- TypeDecl *ucontext_tDecl;
-
- /// \brief Type for the Block descriptor for Blocks CodeGen.
- ///
- /// Since this is only used for generation of debug info, it is not
- /// serialized.
- mutable RecordDecl *BlockDescriptorType;
-
- /// \brief Type for the Block descriptor for Blocks CodeGen.
- ///
- /// Since this is only used for generation of debug info, it is not
- /// serialized.
- mutable RecordDecl *BlockDescriptorExtendedType;
-
- /// \brief Declaration for the CUDA cudaConfigureCall function.
- FunctionDecl *cudaConfigureCallDecl;
-
- /// \brief Keeps track of all declaration attributes.
- ///
- /// Since so few decls have attrs, we keep them in a hash map instead of
- /// wasting space in the Decl class.
- llvm::DenseMap<const Decl*, AttrVec*> DeclAttrs;
-
- /// \brief A mapping from non-redeclarable declarations in modules that were
- /// merged with other declarations to the canonical declaration that they were
- /// merged into.
- llvm::DenseMap<Decl*, Decl*> MergedDecls;
-
- /// \brief A mapping from a defining declaration to a list of modules (other
- /// than the owning module of the declaration) that contain merged
- /// definitions of that entity.
- llvm::DenseMap<NamedDecl*, llvm::TinyPtrVector<Module*>> MergedDefModules;
-
-public:
- /// \brief A type synonym for the TemplateOrInstantiation mapping.
- typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
- TemplateOrSpecializationInfo;
-
-private:
-
- /// \brief A mapping to contain the template or declaration that
- /// a variable declaration describes or was instantiated from,
- /// respectively.
- ///
- /// For non-templates, this value will be NULL. For variable
- /// declarations that describe a variable template, this will be a
- /// pointer to a VarTemplateDecl. For static data members
- /// of class template specializations, this will be the
- /// MemberSpecializationInfo referring to the member variable that was
- /// instantiated or specialized. Thus, the mapping will keep track of
- /// the static data member templates from which static data members of
- /// class template specializations were instantiated.
- ///
- /// Given the following example:
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// static T value;
- /// };
- ///
- /// template<typename T>
- /// T X<T>::value = T(17);
- ///
- /// int *x = &X<int>::value;
- /// \endcode
- ///
- /// This mapping will contain an entry that maps from the VarDecl for
- /// X<int>::value to the corresponding VarDecl for X<T>::value (within the
- /// class template X) and will be marked TSK_ImplicitInstantiation.
- llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
- TemplateOrInstantiation;
-
- /// \brief Keeps track of the declaration from which a UsingDecl was
- /// created during instantiation.
- ///
- /// The source declaration is always a UsingDecl, an UnresolvedUsingValueDecl,
- /// or an UnresolvedUsingTypenameDecl.
- ///
- /// For example:
- /// \code
- /// template<typename T>
- /// struct A {
- /// void f();
- /// };
- ///
- /// template<typename T>
- /// struct B : A<T> {
- /// using A<T>::f;
- /// };
- ///
- /// template struct B<int>;
- /// \endcode
- ///
- /// This mapping will contain an entry that maps from the UsingDecl in
- /// B<int> to the UnresolvedUsingDecl in B<T>.
- llvm::DenseMap<UsingDecl *, NamedDecl *> InstantiatedFromUsingDecl;
-
- llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>
- InstantiatedFromUsingShadowDecl;
-
- llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
-
- /// \brief Mapping that stores the methods overridden by a given C++
- /// member function.
- ///
- /// Since most C++ member functions aren't virtual and therefore
- /// don't override anything, we store the overridden functions in
- /// this map on the side rather than within the CXXMethodDecl structure.
- typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
- llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
-
- /// \brief Mapping from each declaration context to its corresponding
- /// mangling numbering context (used for constructs like lambdas which
- /// need to be consistently numbered for the mangler).
- llvm::DenseMap<const DeclContext *, MangleNumberingContext *>
- MangleNumberingContexts;
-
- /// \brief Side-table of mangling numbers for declarations which rarely
- /// need them (like static local vars).
- llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers;
- llvm::DenseMap<const VarDecl *, unsigned> StaticLocalNumbers;
-
- /// \brief Mapping that stores parameterIndex values for ParmVarDecls when
- /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
- typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable;
- ParameterIndexTable ParamIndices;
-
- ImportDecl *FirstLocalImport;
- ImportDecl *LastLocalImport;
-
- TranslationUnitDecl *TUDecl;
- mutable ExternCContextDecl *ExternCContext;
- mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
-
- /// \brief The associated SourceManager object.a
- SourceManager &SourceMgr;
-
- /// \brief The language options used to create the AST associated with
- /// this ASTContext object.
- LangOptions &LangOpts;
-
- /// \brief Blacklist object that is used by sanitizers to decide which
- /// entities should not be instrumented.
- std::unique_ptr<SanitizerBlacklist> SanitizerBL;
-
- /// \brief The allocator used to create AST objects.
- ///
- /// AST objects are never destructed; rather, all memory associated with the
- /// AST objects will be released when the ASTContext itself is destroyed.
- mutable llvm::BumpPtrAllocator BumpAlloc;
-
- /// \brief Allocator for partial diagnostics.
- PartialDiagnostic::StorageAllocator DiagAllocator;
-
- /// \brief The current C++ ABI.
- std::unique_ptr<CXXABI> ABI;
- CXXABI *createCXXABI(const TargetInfo &T);
-
- /// \brief The logical -> physical address space map.
- const LangAS::Map *AddrSpaceMap;
-
- /// \brief Address space map mangling must be used with language specific
- /// address spaces (e.g. OpenCL/CUDA)
- bool AddrSpaceMapMangling;
-
- friend class ASTDeclReader;
- friend class ASTReader;
- friend class ASTWriter;
- friend class CXXRecordDecl;
-
- const TargetInfo *Target;
- const TargetInfo *AuxTarget;
- clang::PrintingPolicy PrintingPolicy;
-
-public:
- IdentifierTable &Idents;
- SelectorTable &Selectors;
- Builtin::Context &BuiltinInfo;
- mutable DeclarationNameTable DeclarationNames;
- IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
- ASTMutationListener *Listener;
-
- /// \brief Contains parents of a node.
- typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector;
-
- /// \brief Maps from a node to its parents. This is used for nodes that have
- /// pointer identity only, which are more common and we can save space by
- /// only storing a unique pointer to them.
- typedef llvm::DenseMap<const void *,
- llvm::PointerUnion4<const Decl *, const Stmt *,
- ast_type_traits::DynTypedNode *,
- ParentVector *>> ParentMapPointers;
-
- /// Parent map for nodes without pointer identity. We store a full
- /// DynTypedNode for all keys.
- typedef llvm::DenseMap<
- ast_type_traits::DynTypedNode,
- llvm::PointerUnion4<const Decl *, const Stmt *,
- ast_type_traits::DynTypedNode *, ParentVector *>>
- ParentMapOtherNodes;
-
- /// Container for either a single DynTypedNode or for an ArrayRef to
- /// DynTypedNode. For use with ParentMap.
- class DynTypedNodeList {
- typedef ast_type_traits::DynTypedNode DynTypedNode;
- llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode,
- ArrayRef<DynTypedNode>> Storage;
- bool IsSingleNode;
-
- public:
- DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
- new (Storage.buffer) DynTypedNode(N);
- }
- DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
- new (Storage.buffer) ArrayRef<DynTypedNode>(A);
- }
-
- const ast_type_traits::DynTypedNode *begin() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
- ->begin();
- return reinterpret_cast<const DynTypedNode *>(Storage.buffer);
- }
-
- const ast_type_traits::DynTypedNode *end() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
- ->end();
- return reinterpret_cast<const DynTypedNode *>(Storage.buffer) + 1;
- }
-
- size_t size() const { return end() - begin(); }
- bool empty() const { return begin() == end(); }
- const DynTypedNode &operator[](size_t N) const {
- assert(N < size() && "Out of bounds!");
- return *(begin() + N);
- }
- };
-
- /// \brief Returns the parents of the given node.
- ///
- /// Note that this will lazily compute the parents of all nodes
- /// and store them for later retrieval. Thus, the first call is O(n)
- /// in the number of AST nodes.
- ///
- /// Caveats and FIXMEs:
- /// Calculating the parent map over all AST nodes will need to load the
- /// full AST. This can be undesirable in the case where the full AST is
- /// expensive to create (for example, when using precompiled header
- /// preambles). Thus, there are good opportunities for optimization here.
- /// One idea is to walk the given node downwards, looking for references
- /// to declaration contexts - once a declaration context is found, compute
- /// the parent map for the declaration context; if that can satisfy the
- /// request, loading the whole AST can be avoided. Note that this is made
- /// more complex by statements in templates having multiple parents - those
- /// problems can be solved by building closure over the templated parts of
- /// the AST, which also avoids touching large parts of the AST.
- /// Additionally, we will want to add an interface to already give a hint
- /// where to search for the parents, for example when looking at a statement
- /// inside a certain function.
- ///
- /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
- /// NestedNameSpecifier or NestedNameSpecifierLoc.
- template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node) {
- return getParents(ast_type_traits::DynTypedNode::create(Node));
- }
-
- DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node);
-
- const clang::PrintingPolicy &getPrintingPolicy() const {
- return PrintingPolicy;
- }
-
- void setPrintingPolicy(const clang::PrintingPolicy &Policy) {
- PrintingPolicy = Policy;
- }
-
- SourceManager& getSourceManager() { return SourceMgr; }
- const SourceManager& getSourceManager() const { return SourceMgr; }
-
- llvm::BumpPtrAllocator &getAllocator() const {
- return BumpAlloc;
- }
-
- void *Allocate(size_t Size, unsigned Align = 8) const {
- return BumpAlloc.Allocate(Size, Align);
- }
- template <typename T> T *Allocate(size_t Num = 1) const {
- return static_cast<T *>(Allocate(Num * sizeof(T), llvm::alignOf<T>()));
- }
- void Deallocate(void *Ptr) const { }
-
- /// Return the total amount of physical memory allocated for representing
- /// AST nodes and type information.
- size_t getASTAllocatedMemory() const {
- return BumpAlloc.getTotalMemory();
- }
- /// Return the total memory used for various side tables.
- size_t getSideTableAllocatedMemory() const;
-
- PartialDiagnostic::StorageAllocator &getDiagAllocator() {
- return DiagAllocator;
- }
-
- const TargetInfo &getTargetInfo() const { return *Target; }
- const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
-
- /// getIntTypeForBitwidth -
- /// sets integer QualTy according to specified details:
- /// bitwidth, signed/unsigned.
- /// Returns empty type if there is no appropriate target types.
- QualType getIntTypeForBitwidth(unsigned DestWidth,
- unsigned Signed) const;
- /// getRealTypeForBitwidth -
- /// sets floating point QualTy according to specified bitwidth.
- /// Returns empty type if there is no appropriate target types.
- QualType getRealTypeForBitwidth(unsigned DestWidth) const;
-
- bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
-
- const LangOptions& getLangOpts() const { return LangOpts; }
-
- const SanitizerBlacklist &getSanitizerBlacklist() const {
- return *SanitizerBL;
- }
-
- DiagnosticsEngine &getDiagnostics() const;
-
- FullSourceLoc getFullLoc(SourceLocation Loc) const {
- return FullSourceLoc(Loc,SourceMgr);
- }
-
- /// \brief All comments in this translation unit.
- RawCommentList Comments;
-
- /// \brief True if comments are already loaded from ExternalASTSource.
- mutable bool CommentsLoaded;
-
- 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;
- };
-
- /// \brief Mapping from declarations to comments attached to any
- /// redeclaration.
- ///
- /// Raw comments are owned by Comments list. This mapping is populated
- /// lazily.
- mutable llvm::DenseMap<const Decl *, RawCommentAndCacheFlags> RedeclComments;
-
- /// \brief Mapping from declarations to parsed comments attached to any
- /// redeclaration.
- mutable llvm::DenseMap<const Decl *, comments::FullComment *> ParsedComments;
-
- /// \brief Return the documentation comment attached to a given declaration,
- /// without looking into cache.
- RawComment *getRawCommentForDeclNoCache(const Decl *D) const;
-
-public:
- RawCommentList &getRawCommentList() {
- return Comments;
- }
-
- void addComment(const RawComment &RC) {
- assert(LangOpts.RetainCommentsFromSystemHeaders ||
- !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin()));
- Comments.addComment(RC, BumpAlloc);
- }
-
- /// \brief Return the documentation comment attached to a given declaration.
- /// Returns NULL if no comment is attached.
- ///
- /// \param OriginalDecl if not NULL, is set to declaration AST node that had
- /// the comment, if the comment we found comes from a redeclaration.
- const RawComment *
- getRawCommentForAnyRedecl(const Decl *D,
- const Decl **OriginalDecl = nullptr) const;
-
- /// Return parsed documentation comment attached to a given declaration.
- /// Returns NULL if no comment is attached.
- ///
- /// \param PP the Preprocessor used with this TU. Could be NULL if
- /// preprocessor is not available.
- comments::FullComment *getCommentForDecl(const Decl *D,
- const Preprocessor *PP) const;
-
- /// Return parsed documentation comment attached to a given declaration.
- /// Returns NULL if no comment is attached. Does not look at any
- /// redeclarations of the declaration.
- comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const;
-
- comments::FullComment *cloneFullComment(comments::FullComment *FC,
- const Decl *D) const;
-
-private:
- mutable comments::CommandTraits CommentCommandTraits;
-
- /// \brief Iterator that visits import declarations.
- class import_iterator {
- ImportDecl *Import;
-
- public:
- typedef ImportDecl *value_type;
- typedef ImportDecl *reference;
- typedef ImportDecl *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- import_iterator() : Import() {}
- explicit import_iterator(ImportDecl *Import) : Import(Import) {}
-
- reference operator*() const { return Import; }
- pointer operator->() const { return Import; }
-
- import_iterator &operator++() {
- Import = ASTContext::getNextLocalImport(Import);
- return *this;
- }
-
- import_iterator operator++(int) {
- import_iterator Other(*this);
- ++(*this);
- return Other;
- }
-
- friend bool operator==(import_iterator X, import_iterator Y) {
- return X.Import == Y.Import;
- }
-
- friend bool operator!=(import_iterator X, import_iterator Y) {
- return X.Import != Y.Import;
- }
- };
-
-public:
- comments::CommandTraits &getCommentCommandTraits() const {
- return CommentCommandTraits;
- }
-
- /// \brief Retrieve the attributes for the given declaration.
- AttrVec& getDeclAttrs(const Decl *D);
-
- /// \brief Erase the attributes corresponding to the given declaration.
- void eraseDeclAttrs(const Decl *D);
-
- /// \brief If this variable is an instantiated static data member of a
- /// class template specialization, returns the templated static data member
- /// from which it was instantiated.
- // FIXME: Remove ?
- MemberSpecializationInfo *getInstantiatedFromStaticDataMember(
- const VarDecl *Var);
-
- TemplateOrSpecializationInfo
- getTemplateOrSpecializationInfo(const VarDecl *Var);
-
- FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD);
-
- void setClassScopeSpecializationPattern(FunctionDecl *FD,
- FunctionDecl *Pattern);
-
- /// \brief Note that the static data member \p Inst is an instantiation of
- /// the static data member template \p Tmpl of a class template.
- void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
- TemplateSpecializationKind TSK,
- SourceLocation PointOfInstantiation = SourceLocation());
-
- void setTemplateOrSpecializationInfo(VarDecl *Inst,
- TemplateOrSpecializationInfo TSI);
-
- /// \brief If the given using decl \p Inst is an instantiation of a
- /// (possibly unresolved) using decl from a template instantiation,
- /// return it.
- NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst);
-
- /// \brief Remember that the using decl \p Inst is an instantiation
- /// of the using decl \p Pattern of a class template.
- void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern);
-
- void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
- UsingShadowDecl *Pattern);
- UsingShadowDecl *getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst);
-
- FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
-
- void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
-
- // Access to the set of methods overridden by the given C++ method.
- typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator;
- overridden_cxx_method_iterator
- overridden_methods_begin(const CXXMethodDecl *Method) const;
-
- overridden_cxx_method_iterator
- overridden_methods_end(const CXXMethodDecl *Method) const;
-
- unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
-
- /// \brief Note that the given C++ \p Method overrides the given \p
- /// Overridden method.
- void addOverriddenMethod(const CXXMethodDecl *Method,
- const CXXMethodDecl *Overridden);
-
- /// \brief Return C++ or ObjC overridden methods for the given \p Method.
- ///
- /// An ObjC method is considered to override any method in the class's
- /// base classes, its protocols, or its categories' protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- void getOverriddenMethods(
- const NamedDecl *Method,
- SmallVectorImpl<const NamedDecl *> &Overridden) const;
-
- /// \brief Notify the AST context that a new import declaration has been
- /// parsed or implicitly created within this translation unit.
- void addedLocalImportDecl(ImportDecl *Import);
-
- static ImportDecl *getNextLocalImport(ImportDecl *Import) {
- return Import->NextLocalImport;
- }
-
- typedef llvm::iterator_range<import_iterator> import_range;
- import_range local_imports() const {
- return import_range(import_iterator(FirstLocalImport), import_iterator());
- }
-
- Decl *getPrimaryMergedDecl(Decl *D) {
- Decl *Result = MergedDecls.lookup(D);
- return Result ? Result : D;
- }
- void setPrimaryMergedDecl(Decl *D, Decl *Primary) {
- MergedDecls[D] = Primary;
- }
-
- /// \brief Note that the definition \p ND has been merged into module \p M,
- /// and should be visible whenever \p M is visible.
- void mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
- bool NotifyListeners = true);
- /// \brief Clean up the merged definition list. Call this if you might have
- /// added duplicates into the list.
- void deduplicateMergedDefinitonsFor(NamedDecl *ND);
-
- /// \brief Get the additional modules in which the definition \p Def has
- /// been merged.
- ArrayRef<Module*> getModulesWithMergedDefinition(NamedDecl *Def) {
- auto MergedIt = MergedDefModules.find(Def);
- if (MergedIt == MergedDefModules.end())
- return None;
- return MergedIt->second;
- }
-
- TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
-
- ExternCContextDecl *getExternCContextDecl() const;
- BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
-
- // Builtin Types.
- CanQualType VoidTy;
- CanQualType BoolTy;
- CanQualType CharTy;
- CanQualType WCharTy; // [C++ 3.9.1p5].
- CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99.
- CanQualType WIntTy; // [C99 7.24.1], integer type unchanged by default promotions.
- CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
- CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
- CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
- CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
- CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
- CanQualType FloatTy, DoubleTy, LongDoubleTy;
- CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
- CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
- CanQualType VoidPtrTy, NullPtrTy;
- CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
- CanQualType BuiltinFnTy;
- CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
- CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
- CanQualType ObjCBuiltinBoolTy;
- CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy;
- CanQualType OCLImage2dTy, OCLImage2dArrayTy, OCLImage2dDepthTy;
- CanQualType OCLImage2dArrayDepthTy, OCLImage2dMSAATy, OCLImage2dArrayMSAATy;
- CanQualType OCLImage2dMSAADepthTy, OCLImage2dArrayMSAADepthTy;
- CanQualType OCLImage3dTy;
- CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
- CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy;
- CanQualType OMPArraySectionTy;
-
- // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
- mutable QualType AutoDeductTy; // Deduction against 'auto'.
- mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'.
-
- // Decl used to help define __builtin_va_list for some targets.
- // The decl is built when constructing 'BuiltinVaListDecl'.
- mutable Decl *VaListTagDecl;
-
- ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
- SelectorTable &sels, Builtin::Context &builtins);
-
- ~ASTContext();
-
- /// \brief Attach an external AST source to the AST context.
- ///
- /// The external AST source provides the ability to load parts of
- /// the abstract syntax tree as needed from some external storage,
- /// e.g., a precompiled header.
- void setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source);
-
- /// \brief Retrieve a pointer to the external AST source associated
- /// with this AST context, if any.
- ExternalASTSource *getExternalSource() const {
- return ExternalSource.get();
- }
-
- /// \brief Attach an AST mutation listener to the AST context.
- ///
- /// The AST mutation listener provides the ability to track modifications to
- /// the abstract syntax tree entities committed after they were initially
- /// created.
- void setASTMutationListener(ASTMutationListener *Listener) {
- this->Listener = Listener;
- }
-
- /// \brief Retrieve a pointer to the AST mutation listener associated
- /// with this AST context, if any.
- ASTMutationListener *getASTMutationListener() const { return Listener; }
-
- void PrintStats() const;
- const SmallVectorImpl<Type *>& getTypes() const { return Types; }
-
- BuiltinTemplateDecl *buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
- const IdentifierInfo *II) const;
-
- /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl
- /// declaration.
- RecordDecl *buildImplicitRecord(StringRef Name,
- RecordDecl::TagKind TK = TTK_Struct) const;
-
- /// \brief Create a new implicit TU-level typedef declaration.
- TypedefDecl *buildImplicitTypedef(QualType T, StringRef Name) const;
-
- /// \brief Retrieve the declaration for the 128-bit signed integer type.
- TypedefDecl *getInt128Decl() const;
-
- /// \brief Retrieve the declaration for the 128-bit unsigned integer type.
- TypedefDecl *getUInt128Decl() const;
-
- /// \brief Retrieve the declaration for a 128-bit float stub type.
- TypeDecl *getFloat128StubType() const;
-
- //===--------------------------------------------------------------------===//
- // Type Constructors
- //===--------------------------------------------------------------------===//
-
-private:
- /// \brief Return a type with extended qualifiers.
- QualType getExtQualType(const Type *Base, Qualifiers Quals) const;
-
- QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;
-
-public:
- /// \brief Return the uniqued reference to the type for an address space
- /// qualified type with the specified type and address space.
- ///
- /// The resulting type has a union of the qualifiers from T and the address
- /// space. If T already has an address space specifier, it is silently
- /// replaced.
- QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
-
- /// \brief Return the uniqued reference to the type for an Objective-C
- /// gc-qualified type.
- ///
- /// The retulting type has a union of the qualifiers from T and the gc
- /// attribute.
- QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const;
-
- /// \brief Return the uniqued reference to the type for a \c restrict
- /// qualified type.
- ///
- /// The resulting type has a union of the qualifiers from \p T and
- /// \c restrict.
- QualType getRestrictType(QualType T) const {
- return T.withFastQualifiers(Qualifiers::Restrict);
- }
-
- /// \brief Return the uniqued reference to the type for a \c volatile
- /// qualified type.
- ///
- /// The resulting type has a union of the qualifiers from \p T and
- /// \c volatile.
- QualType getVolatileType(QualType T) const {
- return T.withFastQualifiers(Qualifiers::Volatile);
- }
-
- /// \brief Return the uniqued reference to the type for a \c const
- /// qualified type.
- ///
- /// The resulting type has a union of the qualifiers from \p T and \c const.
- ///
- /// It can be reasonably expected that this will always be equivalent to
- /// calling T.withConst().
- QualType getConstType(QualType T) const { return T.withConst(); }
-
- /// \brief Change the ExtInfo on a function type.
- const FunctionType *adjustFunctionType(const FunctionType *Fn,
- FunctionType::ExtInfo EInfo);
-
- /// Adjust the given function result type.
- CanQualType getCanonicalFunctionResultType(QualType ResultType) const;
-
- /// \brief Change the result type of a function type once it is deduced.
- void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
-
- /// \brief Change the exception specification on a function once it is
- /// delay-parsed, instantiated, or computed.
- void adjustExceptionSpec(FunctionDecl *FD,
- const FunctionProtoType::ExceptionSpecInfo &ESI,
- bool AsWritten = false);
-
- /// \brief Return the uniqued reference to the type for a complex
- /// number with the specified element type.
- QualType getComplexType(QualType T) const;
- CanQualType getComplexType(CanQualType T) const {
- return CanQualType::CreateUnsafe(getComplexType((QualType) T));
- }
-
- /// \brief Return the uniqued reference to the type for a pointer to
- /// the specified type.
- QualType getPointerType(QualType T) const;
- CanQualType getPointerType(CanQualType T) const {
- return CanQualType::CreateUnsafe(getPointerType((QualType) T));
- }
-
- /// \brief Return the uniqued reference to a type adjusted from the original
- /// type to a new type.
- QualType getAdjustedType(QualType Orig, QualType New) const;
- CanQualType getAdjustedType(CanQualType Orig, CanQualType New) const {
- return CanQualType::CreateUnsafe(
- getAdjustedType((QualType)Orig, (QualType)New));
- }
-
- /// \brief Return the uniqued reference to the decayed version of the given
- /// type. Can only be called on array and function types which decay to
- /// pointer types.
- QualType getDecayedType(QualType T) const;
- CanQualType getDecayedType(CanQualType T) const {
- return CanQualType::CreateUnsafe(getDecayedType((QualType) T));
- }
-
- /// \brief Return the uniqued reference to the atomic type for the specified
- /// type.
- QualType getAtomicType(QualType T) const;
-
- /// \brief Return the uniqued reference to the type for a block of the
- /// specified type.
- QualType getBlockPointerType(QualType T) const;
-
- /// Gets the struct used to keep track of the descriptor for pointer to
- /// blocks.
- QualType getBlockDescriptorType() const;
-
- /// Gets the struct used to keep track of the extended descriptor for
- /// pointer to blocks.
- QualType getBlockDescriptorExtendedType() const;
-
- void setcudaConfigureCallDecl(FunctionDecl *FD) {
- cudaConfigureCallDecl = FD;
- }
- FunctionDecl *getcudaConfigureCallDecl() {
- return cudaConfigureCallDecl;
- }
-
- /// Returns true iff we need copy/dispose helpers for the given type.
- bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
-
-
- /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
- /// to false in this case. If HasByrefExtendedLayout returns true, byref variable
- /// has extended lifetime.
- bool getByrefLifetime(QualType Ty,
- Qualifiers::ObjCLifetime &Lifetime,
- bool &HasByrefExtendedLayout) const;
-
- /// \brief Return the uniqued reference to the type for an lvalue reference
- /// to the specified type.
- QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true)
- const;
-
- /// \brief Return the uniqued reference to the type for an rvalue reference
- /// to the specified type.
- QualType getRValueReferenceType(QualType T) const;
-
- /// \brief Return the uniqued reference to the type for a member pointer to
- /// the specified type in the specified class.
- ///
- /// The class \p Cls is a \c Type because it could be a dependent name.
- QualType getMemberPointerType(QualType T, const Type *Cls) const;
-
- /// \brief Return a non-unique reference to the type for a variable array of
- /// the specified element type.
- QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
- ArrayType::ArraySizeModifier ASM,
- unsigned IndexTypeQuals,
- SourceRange Brackets) const;
-
- /// \brief Return a non-unique reference to the type for a dependently-sized
- /// array of the specified element type.
- ///
- /// FIXME: We will need these to be uniqued, or at least comparable, at some
- /// point.
- QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
- ArrayType::ArraySizeModifier ASM,
- unsigned IndexTypeQuals,
- SourceRange Brackets) const;
-
- /// \brief Return a unique reference to the type for an incomplete array of
- /// the specified element type.
- QualType getIncompleteArrayType(QualType EltTy,
- ArrayType::ArraySizeModifier ASM,
- unsigned IndexTypeQuals) const;
-
- /// \brief Return the unique reference to the type for a constant array of
- /// the specified element type.
- QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
- ArrayType::ArraySizeModifier ASM,
- unsigned IndexTypeQuals) const;
-
- /// \brief Returns a vla type where known sizes are replaced with [*].
- QualType getVariableArrayDecayedType(QualType Ty) const;
-
- /// \brief Return the unique reference to a vector type of the specified
- /// element type and size.
- ///
- /// \pre \p VectorType must be a built-in type.
- QualType getVectorType(QualType VectorType, unsigned NumElts,
- VectorType::VectorKind VecKind) const;
-
- /// \brief Return the unique reference to an extended vector type
- /// of the specified element type and size.
- ///
- /// \pre \p VectorType must be a built-in type.
- QualType getExtVectorType(QualType VectorType, unsigned NumElts) const;
-
- /// \pre Return a non-unique reference to the type for a dependently-sized
- /// vector of the specified element type.
- ///
- /// FIXME: We will need these to be uniqued, or at least comparable, at some
- /// point.
- QualType getDependentSizedExtVectorType(QualType VectorType,
- Expr *SizeExpr,
- SourceLocation AttrLoc) const;
-
- /// \brief Return a K&R style C function type like 'int()'.
- QualType getFunctionNoProtoType(QualType ResultTy,
- const FunctionType::ExtInfo &Info) const;
-
- QualType getFunctionNoProtoType(QualType ResultTy) const {
- return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo());
- }
-
- /// \brief Return a normal function type with a typed argument list.
- QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
- const FunctionProtoType::ExtProtoInfo &EPI) const;
-
- /// \brief Return the unique reference to the type for the specified type
- /// declaration.
- QualType getTypeDeclType(const TypeDecl *Decl,
- const TypeDecl *PrevDecl = nullptr) const {
- assert(Decl && "Passed null for Decl param");
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
-
- if (PrevDecl) {
- assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
- Decl->TypeForDecl = PrevDecl->TypeForDecl;
- return QualType(PrevDecl->TypeForDecl, 0);
- }
-
- return getTypeDeclTypeSlow(Decl);
- }
-
- /// \brief Return the unique reference to the type for the specified
- /// typedef-name decl.
- QualType getTypedefType(const TypedefNameDecl *Decl,
- QualType Canon = QualType()) const;
-
- QualType getRecordType(const RecordDecl *Decl) const;
-
- QualType getEnumType(const EnumDecl *Decl) const;
-
- QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
-
- QualType getAttributedType(AttributedType::Kind attrKind,
- QualType modifiedType,
- QualType equivalentType);
-
- QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
- QualType Replacement) const;
- QualType getSubstTemplateTypeParmPackType(
- const TemplateTypeParmType *Replaced,
- const TemplateArgument &ArgPack);
-
- QualType
- getTemplateTypeParmType(unsigned Depth, unsigned Index,
- bool ParameterPack,
- TemplateTypeParmDecl *ParmDecl = nullptr) const;
-
- QualType getTemplateSpecializationType(TemplateName T,
- const TemplateArgument *Args,
- unsigned NumArgs,
- QualType Canon = QualType()) const;
-
- QualType getCanonicalTemplateSpecializationType(TemplateName T,
- const TemplateArgument *Args,
- unsigned NumArgs) const;
-
- QualType getTemplateSpecializationType(TemplateName T,
- const TemplateArgumentListInfo &Args,
- QualType Canon = QualType()) const;
-
- TypeSourceInfo *
- getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
- const TemplateArgumentListInfo &Args,
- QualType Canon = QualType()) const;
-
- QualType getParenType(QualType NamedType) const;
-
- QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- QualType NamedType) const;
- QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- QualType Canon = QualType()) const;
-
- QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- const TemplateArgumentListInfo &Args) const;
- QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- unsigned NumArgs,
- const TemplateArgument *Args) const;
-
- QualType getPackExpansionType(QualType Pattern,
- Optional<unsigned> NumExpansions);
-
- QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
- ObjCInterfaceDecl *PrevDecl = nullptr) const;
-
- /// Legacy interface: cannot provide type arguments or __kindof.
- QualType getObjCObjectType(QualType Base,
- ObjCProtocolDecl * const *Protocols,
- unsigned NumProtocols) const;
-
- QualType getObjCObjectType(QualType Base,
- ArrayRef<QualType> typeArgs,
- ArrayRef<ObjCProtocolDecl *> protocols,
- bool isKindOf) const;
-
- bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
- /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
- /// QT's qualified-id protocol list adopt all protocols in IDecl's list
- /// of protocols.
- bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
- ObjCInterfaceDecl *IDecl);
-
- /// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType.
- QualType getObjCObjectPointerType(QualType OIT) const;
-
- /// \brief GCC extension.
- QualType getTypeOfExprType(Expr *e) const;
- QualType getTypeOfType(QualType t) const;
-
- /// \brief C++11 decltype.
- QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;
-
- /// \brief Unary type transforms
- QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
- UnaryTransformType::UTTKind UKind) const;
-
- /// \brief C++11 deduced auto type.
- QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
- bool IsDependent) const;
-
- /// \brief C++11 deduction pattern for 'auto' type.
- QualType getAutoDeductType() const;
-
- /// \brief C++11 deduction pattern for 'auto &&' type.
- QualType getAutoRRefDeductType() const;
-
- /// \brief Return the unique reference to the type for the specified TagDecl
- /// (struct/union/class/enum) decl.
- QualType getTagDeclType(const TagDecl *Decl) const;
-
- /// \brief Return the unique type for "size_t" (C99 7.17), defined in
- /// <stddef.h>.
- ///
- /// The sizeof operator requires this (C99 6.5.3.4p4).
- CanQualType getSizeType() const;
-
- /// \brief Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
- /// <stdint.h>.
- CanQualType getIntMaxType() const;
-
- /// \brief Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in
- /// <stdint.h>.
- CanQualType getUIntMaxType() const;
-
- /// \brief Return the unique wchar_t type available in C++ (and available as
- /// __wchar_t as a Microsoft extension).
- QualType getWCharType() const { return WCharTy; }
-
- /// \brief Return the type of wide characters. In C++, this returns the
- /// unique wchar_t type. In C99, this returns a type compatible with the type
- /// defined in <stddef.h> as defined by the target.
- QualType getWideCharType() const { return WideCharTy; }
-
- /// \brief Return the type of "signed wchar_t".
- ///
- /// Used when in C++, as a GCC extension.
- QualType getSignedWCharType() const;
-
- /// \brief Return the type of "unsigned wchar_t".
- ///
- /// Used when in C++, as a GCC extension.
- QualType getUnsignedWCharType() const;
-
- /// \brief In C99, this returns a type compatible with the type
- /// defined in <stddef.h> as defined by the target.
- QualType getWIntType() const { return WIntTy; }
-
- /// \brief Return a type compatible with "intptr_t" (C99 7.18.1.4),
- /// as defined by the target.
- QualType getIntPtrType() const;
-
- /// \brief Return a type compatible with "uintptr_t" (C99 7.18.1.4),
- /// as defined by the target.
- QualType getUIntPtrType() const;
-
- /// \brief Return the unique type for "ptrdiff_t" (C99 7.17) defined in
- /// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
- QualType getPointerDiffType() const;
-
- /// \brief Return the unique type for "pid_t" defined in
- /// <sys/types.h>. We need this to compute the correct type for vfork().
- QualType getProcessIDType() const;
-
- /// \brief Return the C structure type used to represent constant CFStrings.
- QualType getCFConstantStringType() const;
-
- /// \brief Returns the C struct type for objc_super
- QualType getObjCSuperType() const;
- void setObjCSuperType(QualType ST) { ObjCSuperType = ST; }
-
- /// Get the structure type used to representation CFStrings, or NULL
- /// if it hasn't yet been built.
- QualType getRawCFConstantStringType() const {
- if (CFConstantStringTypeDecl)
- return getTagDeclType(CFConstantStringTypeDecl);
- return QualType();
- }
- void setCFConstantStringType(QualType T);
-
- // This setter/getter represents the ObjC type for an NSConstantString.
- void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
- QualType getObjCConstantStringInterface() const {
- return ObjCConstantStringType;
- }
-
- QualType getObjCNSStringType() const {
- return ObjCNSStringType;
- }
-
- void setObjCNSStringType(QualType T) {
- ObjCNSStringType = T;
- }
-
- /// \brief Retrieve the type that \c id has been defined to, which may be
- /// different from the built-in \c id if \c id has been typedef'd.
- QualType getObjCIdRedefinitionType() const {
- if (ObjCIdRedefinitionType.isNull())
- return getObjCIdType();
- return ObjCIdRedefinitionType;
- }
-
- /// \brief Set the user-written type that redefines \c id.
- void setObjCIdRedefinitionType(QualType RedefType) {
- ObjCIdRedefinitionType = RedefType;
- }
-
- /// \brief Retrieve the type that \c Class has been defined to, which may be
- /// different from the built-in \c Class if \c Class has been typedef'd.
- QualType getObjCClassRedefinitionType() const {
- if (ObjCClassRedefinitionType.isNull())
- return getObjCClassType();
- return ObjCClassRedefinitionType;
- }
-
- /// \brief Set the user-written type that redefines 'SEL'.
- void setObjCClassRedefinitionType(QualType RedefType) {
- ObjCClassRedefinitionType = RedefType;
- }
-
- /// \brief Retrieve the type that 'SEL' has been defined to, which may be
- /// different from the built-in 'SEL' if 'SEL' has been typedef'd.
- QualType getObjCSelRedefinitionType() const {
- if (ObjCSelRedefinitionType.isNull())
- return getObjCSelType();
- return ObjCSelRedefinitionType;
- }
-
-
- /// \brief Set the user-written type that redefines 'SEL'.
- void setObjCSelRedefinitionType(QualType RedefType) {
- ObjCSelRedefinitionType = RedefType;
- }
-
- /// Retrieve the identifier 'NSObject'.
- IdentifierInfo *getNSObjectName() {
- if (!NSObjectName) {
- NSObjectName = &Idents.get("NSObject");
- }
-
- return NSObjectName;
- }
-
- /// Retrieve the identifier 'NSCopying'.
- IdentifierInfo *getNSCopyingName() {
- if (!NSCopyingName) {
- NSCopyingName = &Idents.get("NSCopying");
- }
-
- return NSCopyingName;
- }
-
- IdentifierInfo *getMakeIntegerSeqName() const {
- if (!MakeIntegerSeqName)
- MakeIntegerSeqName = &Idents.get("__make_integer_seq");
- return MakeIntegerSeqName;
- }
-
- /// \brief Retrieve the Objective-C "instancetype" type, if already known;
- /// otherwise, returns a NULL type;
- QualType getObjCInstanceType() {
- return getTypeDeclType(getObjCInstanceTypeDecl());
- }
-
- /// \brief Retrieve the typedef declaration corresponding to the Objective-C
- /// "instancetype" type.
- TypedefDecl *getObjCInstanceTypeDecl();
-
- /// \brief Set the type for the C FILE type.
- void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }
-
- /// \brief Retrieve the C FILE type.
- QualType getFILEType() const {
- if (FILEDecl)
- return getTypeDeclType(FILEDecl);
- return QualType();
- }
-
- /// \brief Set the type for the C jmp_buf type.
- void setjmp_bufDecl(TypeDecl *jmp_bufDecl) {
- this->jmp_bufDecl = jmp_bufDecl;
- }
-
- /// \brief Retrieve the C jmp_buf type.
- QualType getjmp_bufType() const {
- if (jmp_bufDecl)
- return getTypeDeclType(jmp_bufDecl);
- return QualType();
- }
-
- /// \brief Set the type for the C sigjmp_buf type.
- void setsigjmp_bufDecl(TypeDecl *sigjmp_bufDecl) {
- this->sigjmp_bufDecl = sigjmp_bufDecl;
- }
-
- /// \brief Retrieve the C sigjmp_buf type.
- QualType getsigjmp_bufType() const {
- if (sigjmp_bufDecl)
- return getTypeDeclType(sigjmp_bufDecl);
- return QualType();
- }
-
- /// \brief Set the type for the C ucontext_t type.
- void setucontext_tDecl(TypeDecl *ucontext_tDecl) {
- this->ucontext_tDecl = ucontext_tDecl;
- }
-
- /// \brief Retrieve the C ucontext_t type.
- QualType getucontext_tType() const {
- if (ucontext_tDecl)
- return getTypeDeclType(ucontext_tDecl);
- return QualType();
- }
-
- /// \brief The result type of logical operations, '<', '>', '!=', etc.
- QualType getLogicalOperationType() const {
- return getLangOpts().CPlusPlus ? BoolTy : IntTy;
- }
-
- /// \brief Emit the Objective-CC type encoding for the given type \p T into
- /// \p S.
- ///
- /// If \p Field is specified then record field names are also encoded.
- void getObjCEncodingForType(QualType T, std::string &S,
- const FieldDecl *Field=nullptr,
- QualType *NotEncodedT=nullptr) const;
-
- /// \brief Emit the Objective-C property type encoding for the given
- /// type \p T into \p S.
- void getObjCEncodingForPropertyType(QualType T, std::string &S) const;
-
- void getLegacyIntegralTypeEncoding(QualType &t) const;
-
- /// \brief Put the string version of the type qualifiers \p QT into \p S.
- void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
- std::string &S) const;
-
- /// \brief Emit the encoded type for the function \p Decl into \p S.
- ///
- /// This is in the same format as Objective-C method encodings.
- ///
- /// \returns true if an error occurred (e.g., because one of the parameter
- /// types is incomplete), false otherwise.
- bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S);
-
- /// \brief Emit the encoded type for the method declaration \p Decl into
- /// \p S.
- ///
- /// \returns true if an error occurred (e.g., because one of the parameter
- /// types is incomplete), false otherwise.
- bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S,
- bool Extended = false)
- const;
-
- /// \brief Return the encoded type for this block declaration.
- std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;
-
- /// getObjCEncodingForPropertyDecl - Return the encoded type for
- /// this method declaration. If non-NULL, Container must be either
- /// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
- /// only be NULL when getting encodings for protocol properties.
- void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
- const Decl *Container,
- std::string &S) const;
-
- bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
- ObjCProtocolDecl *rProto) const;
-
- ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
- const ObjCPropertyDecl *PD,
- const Decl *Container) const;
-
- /// \brief Return the size of type \p T for Objective-C encoding purpose,
- /// in characters.
- CharUnits getObjCEncodingTypeSize(QualType T) const;
-
- /// \brief Retrieve the typedef corresponding to the predefined \c id type
- /// in Objective-C.
- TypedefDecl *getObjCIdDecl() const;
-
- /// \brief Represents the Objective-CC \c id type.
- ///
- /// This is set up lazily, by Sema. \c id is always a (typedef for a)
- /// pointer type, a pointer to a struct.
- QualType getObjCIdType() const {
- return getTypeDeclType(getObjCIdDecl());
- }
-
- /// \brief Retrieve the typedef corresponding to the predefined 'SEL' type
- /// in Objective-C.
- TypedefDecl *getObjCSelDecl() const;
-
- /// \brief Retrieve the type that corresponds to the predefined Objective-C
- /// 'SEL' type.
- QualType getObjCSelType() const {
- return getTypeDeclType(getObjCSelDecl());
- }
-
- /// \brief Retrieve the typedef declaration corresponding to the predefined
- /// Objective-C 'Class' type.
- TypedefDecl *getObjCClassDecl() const;
-
- /// \brief Represents the Objective-C \c Class type.
- ///
- /// This is set up lazily, by Sema. \c Class is always a (typedef for a)
- /// pointer type, a pointer to a struct.
- QualType getObjCClassType() const {
- return getTypeDeclType(getObjCClassDecl());
- }
-
- /// \brief Retrieve the Objective-C class declaration corresponding to
- /// the predefined \c Protocol class.
- ObjCInterfaceDecl *getObjCProtocolDecl() const;
-
- /// \brief Retrieve declaration of 'BOOL' typedef
- TypedefDecl *getBOOLDecl() const {
- return BOOLDecl;
- }
-
- /// \brief Save declaration of 'BOOL' typedef
- void setBOOLDecl(TypedefDecl *TD) {
- BOOLDecl = TD;
- }
-
- /// \brief type of 'BOOL' type.
- QualType getBOOLType() const {
- return getTypeDeclType(getBOOLDecl());
- }
-
- /// \brief Retrieve the type of the Objective-C \c Protocol class.
- QualType getObjCProtoType() const {
- return getObjCInterfaceType(getObjCProtocolDecl());
- }
-
- /// \brief Retrieve the C type declaration corresponding to the predefined
- /// \c __builtin_va_list type.
- TypedefDecl *getBuiltinVaListDecl() const;
-
- /// \brief Retrieve the type of the \c __builtin_va_list type.
- QualType getBuiltinVaListType() const {
- return getTypeDeclType(getBuiltinVaListDecl());
- }
-
- /// \brief Retrieve the C type declaration corresponding to the predefined
- /// \c __va_list_tag type used to help define the \c __builtin_va_list type
- /// for some targets.
- Decl *getVaListTagDecl() const;
-
- /// Retrieve the C type declaration corresponding to the predefined
- /// \c __builtin_ms_va_list type.
- TypedefDecl *getBuiltinMSVaListDecl() const;
-
- /// Retrieve the type of the \c __builtin_ms_va_list type.
- QualType getBuiltinMSVaListType() const {
- return getTypeDeclType(getBuiltinMSVaListDecl());
- }
-
- /// \brief Return a type with additional \c const, \c volatile, or
- /// \c restrict qualifiers.
- QualType getCVRQualifiedType(QualType T, unsigned CVR) const {
- return getQualifiedType(T, Qualifiers::fromCVRMask(CVR));
- }
-
- /// \brief Un-split a SplitQualType.
- QualType getQualifiedType(SplitQualType split) const {
- return getQualifiedType(split.Ty, split.Quals);
- }
-
- /// \brief Return a type with additional qualifiers.
- QualType getQualifiedType(QualType T, Qualifiers Qs) const {
- if (!Qs.hasNonFastQualifiers())
- return T.withFastQualifiers(Qs.getFastQualifiers());
- QualifierCollector Qc(Qs);
- const Type *Ptr = Qc.strip(T);
- return getExtQualType(Ptr, Qc);
- }
-
- /// \brief Return a type with additional qualifiers.
- QualType getQualifiedType(const Type *T, Qualifiers Qs) const {
- if (!Qs.hasNonFastQualifiers())
- return QualType(T, Qs.getFastQualifiers());
- return getExtQualType(T, Qs);
- }
-
- /// \brief Return a type with the given lifetime qualifier.
- ///
- /// \pre Neither type.ObjCLifetime() nor \p lifetime may be \c OCL_None.
- QualType getLifetimeQualifiedType(QualType type,
- Qualifiers::ObjCLifetime lifetime) {
- assert(type.getObjCLifetime() == Qualifiers::OCL_None);
- assert(lifetime != Qualifiers::OCL_None);
-
- Qualifiers qs;
- qs.addObjCLifetime(lifetime);
- return getQualifiedType(type, qs);
- }
-
- /// getUnqualifiedObjCPointerType - Returns version of
- /// Objective-C pointer type with lifetime qualifier removed.
- QualType getUnqualifiedObjCPointerType(QualType type) const {
- if (!type.getTypePtr()->isObjCObjectPointerType() ||
- !type.getQualifiers().hasObjCLifetime())
- return type;
- Qualifiers Qs = type.getQualifiers();
- Qs.removeObjCLifetime();
- return getQualifiedType(type.getUnqualifiedType(), Qs);
- }
-
- DeclarationNameInfo getNameForTemplate(TemplateName Name,
- SourceLocation NameLoc) const;
-
- TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) const;
-
- TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
- bool TemplateKeyword,
- TemplateDecl *Template) const;
-
- TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
- const IdentifierInfo *Name) const;
- TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
- OverloadedOperatorKind Operator) const;
- TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
- TemplateName replacement) const;
- TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
- const TemplateArgument &ArgPack) const;
-
- enum GetBuiltinTypeError {
- GE_None, ///< No error
- GE_Missing_stdio, ///< Missing a type from <stdio.h>
- GE_Missing_setjmp, ///< Missing a type from <setjmp.h>
- GE_Missing_ucontext ///< Missing a type from <ucontext.h>
- };
-
- /// \brief Return the type for the specified builtin.
- ///
- /// If \p IntegerConstantArgs is non-null, it is filled in with a bitmask of
- /// arguments to the builtin that are required to be integer constant
- /// expressions.
- QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
- unsigned *IntegerConstantArgs = nullptr) const;
-
-private:
- CanQualType getFromTargetType(unsigned Type) const;
- TypeInfo getTypeInfoImpl(const Type *T) const;
-
- //===--------------------------------------------------------------------===//
- // Type Predicates.
- //===--------------------------------------------------------------------===//
-
-public:
- /// \brief Return one of the GCNone, Weak or Strong Objective-C garbage
- /// collection attributes.
- Qualifiers::GC getObjCGCAttrKind(QualType Ty) const;
-
- /// \brief Return true if the given vector types are of the same unqualified
- /// type or if they are equivalent to the same GCC vector type.
- ///
- /// \note This ignores whether they are target-specific (AltiVec or Neon)
- /// types.
- bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);
-
- /// \brief Return true if this is an \c NSObject object with its \c NSObject
- /// attribute set.
- static bool isObjCNSObjectType(QualType Ty) {
- return Ty->isObjCNSObjectType();
- }
-
- //===--------------------------------------------------------------------===//
- // Type Sizing and Analysis
- //===--------------------------------------------------------------------===//
-
- /// \brief Return the APFloat 'semantics' for the specified scalar floating
- /// point type.
- const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
-
- /// \brief Get the size and alignment of the specified complete type in bits.
- TypeInfo getTypeInfo(const Type *T) const;
- TypeInfo getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); }
-
- /// \brief Get default simd alignment of the specified complete type in bits.
- unsigned getOpenMPDefaultSimdAlign(QualType T) const;
-
- /// \brief Return the size of the specified (complete) type \p T, in bits.
- uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).Width; }
- uint64_t getTypeSize(const Type *T) const { return getTypeInfo(T).Width; }
-
- /// \brief Return the size of the character type, in bits.
- uint64_t getCharWidth() const {
- return getTypeSize(CharTy);
- }
-
- /// \brief Convert a size in bits to a size in characters.
- CharUnits toCharUnitsFromBits(int64_t BitSize) const;
-
- /// \brief Convert a size in characters to a size in bits.
- int64_t toBits(CharUnits CharSize) const;
-
- /// \brief Return the size of the specified (complete) type \p T, in
- /// characters.
- CharUnits getTypeSizeInChars(QualType T) const;
- CharUnits getTypeSizeInChars(const Type *T) const;
-
- /// \brief Return the ABI-specified alignment of a (complete) type \p T, in
- /// bits.
- unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }
- unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).Align; }
-
- /// \brief Return the ABI-specified alignment of a (complete) type \p T, in
- /// characters.
- CharUnits getTypeAlignInChars(QualType T) const;
- CharUnits getTypeAlignInChars(const Type *T) const;
-
- // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
- // type is a record, its data size is returned.
- std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const;
-
- std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const;
- std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const;
-
- /// \brief Determine if the alignment the type has was required using an
- /// alignment attribute.
- bool isAlignmentRequired(const Type *T) const;
- bool isAlignmentRequired(QualType T) const;
-
- /// \brief Return the "preferred" alignment of the specified type \p T for
- /// the current target, in bits.
- ///
- /// This can be different than the ABI alignment in cases where it is
- /// beneficial for performance to overalign a data type.
- unsigned getPreferredTypeAlign(const Type *T) const;
-
- /// \brief Return the default alignment for __attribute__((aligned)) on
- /// this target, to be used if no alignment value is specified.
- unsigned getTargetDefaultAlignForAttributeAligned(void) const;
-
- /// \brief Return the alignment in bits that should be given to a
- /// global variable with type \p T.
- unsigned getAlignOfGlobalVar(QualType T) const;
-
- /// \brief Return the alignment in characters that should be given to a
- /// global variable with type \p T.
- CharUnits getAlignOfGlobalVarInChars(QualType T) const;
-
- /// \brief Return a conservative estimate of the alignment of the specified
- /// decl \p D.
- ///
- /// \pre \p D must not be a bitfield type, as bitfields do not have a valid
- /// alignment.
- ///
- /// If \p ForAlignof, references are treated like their underlying type
- /// and large arrays don't get any special treatment. If not \p ForAlignof
- /// it computes the value expected by CodeGen: references are treated like
- /// pointers and large arrays get extra alignment.
- CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const;
-
- /// \brief Get or compute information about the layout of the specified
- /// record (struct/union/class) \p D, which indicates its size and field
- /// position information.
- const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const;
-
- /// \brief Get or compute information about the layout of the specified
- /// Objective-C interface.
- const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D)
- const;
-
- void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS,
- bool Simple = false) const;
-
- /// \brief Get or compute information about the layout of the specified
- /// Objective-C implementation.
- ///
- /// This may differ from the interface if synthesized ivars are present.
- const ASTRecordLayout &
- getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;
-
- /// \brief Get our current best idea for the key function of the
- /// given record decl, or NULL if there isn't one.
- ///
- /// The key function is, according to the Itanium C++ ABI section 5.2.3:
- /// ...the first non-pure virtual function that is not inline at the
- /// point of class definition.
- ///
- /// Other ABIs use the same idea. However, the ARM C++ ABI ignores
- /// virtual functions that are defined 'inline', which means that
- /// the result of this computation can change.
- const CXXMethodDecl *getCurrentKeyFunction(const CXXRecordDecl *RD);
-
- /// \brief Observe that the given method cannot be a key function.
- /// Checks the key-function cache for the method's class and clears it
- /// if matches the given declaration.
- ///
- /// This is used in ABIs where out-of-line definitions marked
- /// inline are not considered to be key functions.
- ///
- /// \param method should be the declaration from the class definition
- void setNonKeyFunction(const CXXMethodDecl *method);
-
- /// Loading virtual member pointers using the virtual inheritance model
- /// always results in an adjustment using the vbtable even if the index is
- /// zero.
- ///
- /// This is usually OK because the first slot in the vbtable points
- /// backwards to the top of the MDC. However, the MDC might be reusing a
- /// vbptr from an nv-base. In this case, the first slot in the vbtable
- /// points to the start of the nv-base which introduced the vbptr and *not*
- /// the MDC. Modify the NonVirtualBaseAdjustment to account for this.
- CharUnits getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const;
-
- /// Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
- uint64_t getFieldOffset(const ValueDecl *FD) const;
-
- bool isNearlyEmpty(const CXXRecordDecl *RD) const;
-
- VTableContextBase *getVTableContext();
-
- MangleContext *createMangleContext();
-
- void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
- SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const;
-
- unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const;
- void CollectInheritedProtocols(const Decl *CDecl,
- llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
-
- //===--------------------------------------------------------------------===//
- // Type Operators
- //===--------------------------------------------------------------------===//
-
- /// \brief Return the canonical (structural) type corresponding to the
- /// specified potentially non-canonical type \p T.
- ///
- /// The non-canonical version of a type may have many "decorated" versions of
- /// types. Decorators can include typedefs, 'typeof' operators, etc. The
- /// returned type is guaranteed to be free of any of these, allowing two
- /// canonical types to be compared for exact equality with a simple pointer
- /// comparison.
- CanQualType getCanonicalType(QualType T) const {
- return CanQualType::CreateUnsafe(T.getCanonicalType());
- }
-
- const Type *getCanonicalType(const Type *T) const {
- return T->getCanonicalTypeInternal().getTypePtr();
- }
-
- /// \brief Return the canonical parameter type corresponding to the specific
- /// potentially non-canonical one.
- ///
- /// Qualifiers are stripped off, functions are turned into function
- /// pointers, and arrays decay one level into pointers.
- CanQualType getCanonicalParamType(QualType T) const;
-
- /// \brief Determine whether the given types \p T1 and \p T2 are equivalent.
- bool hasSameType(QualType T1, QualType T2) const {
- return getCanonicalType(T1) == getCanonicalType(T2);
- }
-
- bool hasSameType(const Type *T1, const Type *T2) const {
- return getCanonicalType(T1) == getCanonicalType(T2);
- }
-
- /// \brief Return this type as a completely-unqualified array type,
- /// capturing the qualifiers in \p Quals.
- ///
- /// This will remove the minimal amount of sugaring from the types, similar
- /// to the behavior of QualType::getUnqualifiedType().
- ///
- /// \param T is the qualified type, which may be an ArrayType
- ///
- /// \param Quals will receive the full set of qualifiers that were
- /// applied to the array.
- ///
- /// \returns if this is an array type, the completely unqualified array type
- /// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
- QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals);
-
- /// \brief Determine whether the given types are equivalent after
- /// cvr-qualifiers have been removed.
- bool hasSameUnqualifiedType(QualType T1, QualType T2) const {
- return getCanonicalType(T1).getTypePtr() ==
- getCanonicalType(T2).getTypePtr();
- }
-
- bool hasSameNullabilityTypeQualifier(QualType SubT, QualType SuperT,
- bool IsParam) const {
- auto SubTnullability = SubT->getNullability(*this);
- auto SuperTnullability = SuperT->getNullability(*this);
- if (SubTnullability.hasValue() == SuperTnullability.hasValue()) {
- // Neither has nullability; return true
- if (!SubTnullability)
- return true;
- // Both have nullability qualifier.
- if (*SubTnullability == *SuperTnullability ||
- *SubTnullability == NullabilityKind::Unspecified ||
- *SuperTnullability == NullabilityKind::Unspecified)
- return true;
-
- if (IsParam) {
- // Ok for the superclass method parameter to be "nonnull" and the subclass
- // method parameter to be "nullable"
- return (*SuperTnullability == NullabilityKind::NonNull &&
- *SubTnullability == NullabilityKind::Nullable);
- }
- else {
- // For the return type, it's okay for the superclass method to specify
- // "nullable" and the subclass method specify "nonnull"
- return (*SuperTnullability == NullabilityKind::Nullable &&
- *SubTnullability == NullabilityKind::NonNull);
- }
- }
- return true;
- }
-
- bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
- const ObjCMethodDecl *MethodImp);
-
- bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
-
- /// \brief Retrieves the "canonical" nested name specifier for a
- /// given nested name specifier.
- ///
- /// The canonical nested name specifier is a nested name specifier
- /// that uniquely identifies a type or namespace within the type
- /// system. For example, given:
- ///
- /// \code
- /// namespace N {
- /// struct S {
- /// template<typename T> struct X { typename T* type; };
- /// };
- /// }
- ///
- /// template<typename T> struct Y {
- /// typename N::S::X<T>::type member;
- /// };
- /// \endcode
- ///
- /// Here, the nested-name-specifier for N::S::X<T>:: will be
- /// S::X<template-param-0-0>, since 'S' and 'X' are uniquely defined
- /// by declarations in the type system and the canonical type for
- /// the template type parameter 'T' is template-param-0-0.
- NestedNameSpecifier *
- getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
-
- /// \brief Retrieves the default calling convention for the current target.
- CallingConv getDefaultCallingConvention(bool isVariadic,
- bool IsCXXMethod) const;
-
- /// \brief Retrieves the "canonical" template name that refers to a
- /// given template.
- ///
- /// The canonical template name is the simplest expression that can
- /// be used to refer to a given template. For most templates, this
- /// expression is just the template declaration itself. For example,
- /// the template std::vector can be referred to via a variety of
- /// names---std::vector, \::std::vector, vector (if vector is in
- /// scope), etc.---but all of these names map down to the same
- /// TemplateDecl, which is used to form the canonical template name.
- ///
- /// Dependent template names are more interesting. Here, the
- /// template name could be something like T::template apply or
- /// std::allocator<T>::template rebind, where the nested name
- /// specifier itself is dependent. In this case, the canonical
- /// template name uses the shortest form of the dependent
- /// nested-name-specifier, which itself contains all canonical
- /// types, values, and templates.
- TemplateName getCanonicalTemplateName(TemplateName Name) const;
-
- /// \brief Determine whether the given template names refer to the same
- /// template.
- bool hasSameTemplateName(TemplateName X, TemplateName Y);
-
- /// \brief Retrieve the "canonical" template argument.
- ///
- /// The canonical template argument is the simplest template argument
- /// (which may be a type, value, expression, or declaration) that
- /// expresses the value of the argument.
- TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg)
- const;
-
- /// Type Query functions. If the type is an instance of the specified class,
- /// return the Type pointer for the underlying maximally pretty type. This
- /// is a member of ASTContext because this may need to do some amount of
- /// canonicalization, e.g. to move type qualifiers into the element type.
- const ArrayType *getAsArrayType(QualType T) const;
- const ConstantArrayType *getAsConstantArrayType(QualType T) const {
- return dyn_cast_or_null<ConstantArrayType>(getAsArrayType(T));
- }
- const VariableArrayType *getAsVariableArrayType(QualType T) const {
- return dyn_cast_or_null<VariableArrayType>(getAsArrayType(T));
- }
- const IncompleteArrayType *getAsIncompleteArrayType(QualType T) const {
- return dyn_cast_or_null<IncompleteArrayType>(getAsArrayType(T));
- }
- const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T)
- const {
- return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
- }
-
- /// \brief Return the innermost element type of an array type.
- ///
- /// For example, will return "int" for int[m][n]
- QualType getBaseElementType(const ArrayType *VAT) const;
-
- /// \brief Return the innermost element type of a type (which needn't
- /// actually be an array type).
- QualType getBaseElementType(QualType QT) const;
-
- /// \brief Return number of constant array elements.
- uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
-
- /// \brief Perform adjustment on the parameter type of a function.
- ///
- /// This routine adjusts the given parameter type @p T to the actual
- /// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
- /// C++ [dcl.fct]p3). The adjusted parameter type is returned.
- QualType getAdjustedParameterType(QualType T) const;
-
- /// \brief Retrieve the parameter type as adjusted for use in the signature
- /// of a function, decaying array and function types and removing top-level
- /// cv-qualifiers.
- QualType getSignatureParameterType(QualType T) const;
-
- QualType getExceptionObjectType(QualType T) const;
-
- /// \brief Return the properly qualified result of decaying the specified
- /// array type to a pointer.
- ///
- /// This operation is non-trivial when handling typedefs etc. The canonical
- /// type of \p T must be an array type, this returns a pointer to a properly
- /// qualified element of the array.
- ///
- /// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
- QualType getArrayDecayedType(QualType T) const;
-
- /// \brief Return the type that \p PromotableType will promote to: C99
- /// 6.3.1.1p2, assuming that \p PromotableType is a promotable integer type.
- QualType getPromotedIntegerType(QualType PromotableType) const;
-
- /// \brief Recurses in pointer/array types until it finds an Objective-C
- /// retainable type and returns its ownership.
- Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const;
-
- /// \brief Whether this is a promotable bitfield reference according
- /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
- ///
- /// \returns the type this bit-field will promote to, or NULL if no
- /// promotion occurs.
- QualType isPromotableBitField(Expr *E) const;
-
- /// \brief Return the highest ranked integer type, see C99 6.3.1.8p1.
- ///
- /// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If
- /// \p LHS < \p RHS, return -1.
- int getIntegerTypeOrder(QualType LHS, QualType RHS) const;
-
- /// \brief Compare the rank of the two specified floating point types,
- /// ignoring the domain of the type (i.e. 'double' == '_Complex double').
- ///
- /// If \p LHS > \p RHS, returns 1. If \p LHS == \p RHS, returns 0. If
- /// \p LHS < \p RHS, return -1.
- int getFloatingTypeOrder(QualType LHS, QualType RHS) const;
-
- /// \brief Return a real floating point or a complex type (based on
- /// \p typeDomain/\p typeSize).
- ///
- /// \param typeDomain a real floating point or complex type.
- /// \param typeSize a real floating point or complex type.
- QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
- QualType typeDomain) const;
-
- unsigned getTargetAddressSpace(QualType T) const {
- return getTargetAddressSpace(T.getQualifiers());
- }
-
- unsigned getTargetAddressSpace(Qualifiers Q) const {
- return getTargetAddressSpace(Q.getAddressSpace());
- }
-
- unsigned getTargetAddressSpace(unsigned AS) const {
- if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
- return AS;
- else
- return (*AddrSpaceMap)[AS - LangAS::Offset];
- }
-
- bool addressSpaceMapManglingFor(unsigned AS) const {
- return AddrSpaceMapMangling ||
- AS < LangAS::Offset ||
- AS >= LangAS::Offset + LangAS::Count;
- }
-
-private:
- // Helper for integer ordering
- unsigned getIntegerRank(const Type *T) const;
-
-public:
-
- //===--------------------------------------------------------------------===//
- // Type Compatibility Predicates
- //===--------------------------------------------------------------------===//
-
- /// Compatibility predicates used to check assignment expressions.
- bool typesAreCompatible(QualType T1, QualType T2,
- bool CompareUnqualified = false); // C99 6.2.7p1
-
- bool propertyTypesAreCompatible(QualType, QualType);
- bool typesAreBlockPointerCompatible(QualType, QualType);
-
- bool isObjCIdType(QualType T) const {
- return T == getObjCIdType();
- }
- bool isObjCClassType(QualType T) const {
- return T == getObjCClassType();
- }
- bool isObjCSelType(QualType T) const {
- return T == getObjCSelType();
- }
- bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
- bool ForCompare);
-
- bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS);
-
- // Check the safety of assignment from LHS to RHS
- bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
- const ObjCObjectPointerType *RHSOPT);
- bool canAssignObjCInterfaces(const ObjCObjectType *LHS,
- const ObjCObjectType *RHS);
- bool canAssignObjCInterfacesInBlockPointer(
- const ObjCObjectPointerType *LHSOPT,
- const ObjCObjectPointerType *RHSOPT,
- bool BlockReturnType);
- bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
- QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
- const ObjCObjectPointerType *RHSOPT);
- bool canBindObjCObjectType(QualType To, QualType From);
-
- // Functions for calculating composite types
- QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false, bool BlockReturnType = false);
- QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false);
- QualType mergeFunctionParameterTypes(QualType, QualType,
- bool OfBlockPointer = false,
- bool Unqualified = false);
- QualType mergeTransparentUnionType(QualType, QualType,
- bool OfBlockPointer=false,
- bool Unqualified = false);
-
- QualType mergeObjCGCQualifiers(QualType, QualType);
-
- bool FunctionTypesMatchOnNSConsumedAttrs(
- const FunctionProtoType *FromFunctionType,
- const FunctionProtoType *ToFunctionType);
-
- void ResetObjCLayout(const ObjCContainerDecl *CD);
-
- //===--------------------------------------------------------------------===//
- // Integer Predicates
- //===--------------------------------------------------------------------===//
-
- // The width of an integer, as defined in C99 6.2.6.2. This is the number
- // of bits in an integer type excluding any padding bits.
- unsigned getIntWidth(QualType T) const;
-
- // Per C99 6.2.5p6, for every signed integer type, there is a corresponding
- // unsigned integer type. This method takes a signed type, and returns the
- // corresponding unsigned integer type.
- QualType getCorrespondingUnsignedType(QualType T) const;
-
- //===--------------------------------------------------------------------===//
- // Integer Values
- //===--------------------------------------------------------------------===//
-
- /// \brief Make an APSInt of the appropriate width and signedness for the
- /// given \p Value and integer \p Type.
- llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const {
- llvm::APSInt Res(getIntWidth(Type),
- !Type->isSignedIntegerOrEnumerationType());
- Res = Value;
- return Res;
- }
-
- bool isSentinelNullExpr(const Expr *E);
-
- /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if
- /// none exists.
- ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
- /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if
- /// none exists.
- ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
-
- /// \brief Return true if there is at least one \@implementation in the TU.
- bool AnyObjCImplementation() {
- return !ObjCImpls.empty();
- }
-
- /// \brief Set the implementation of ObjCInterfaceDecl.
- void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
- ObjCImplementationDecl *ImplD);
- /// \brief Set the implementation of ObjCCategoryDecl.
- void setObjCImplementation(ObjCCategoryDecl *CatD,
- ObjCCategoryImplDecl *ImplD);
-
- /// \brief Get the duplicate declaration of a ObjCMethod in the same
- /// interface, or null if none exists.
- const ObjCMethodDecl *
- getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const;
-
- void setObjCMethodRedeclaration(const ObjCMethodDecl *MD,
- const ObjCMethodDecl *Redecl);
-
- /// \brief Returns the Objective-C interface that \p ND belongs to if it is
- /// an Objective-C method/property/ivar etc. that is part of an interface,
- /// otherwise returns null.
- const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;
-
- /// \brief Set the copy inialization expression of a block var decl.
- void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
- /// \brief Get the copy initialization expression of the VarDecl \p VD, or
- /// NULL if none exists.
- Expr *getBlockVarCopyInits(const VarDecl* VD);
-
- /// \brief Allocate an uninitialized TypeSourceInfo.
- ///
- /// The caller should initialize the memory held by TypeSourceInfo using
- /// the TypeLoc wrappers.
- ///
- /// \param T the type that will be the basis for type source info. This type
- /// should refer to how the declarator was written in source code, not to
- /// what type semantic analysis resolved the declarator to.
- ///
- /// \param Size the size of the type info to create, or 0 if the size
- /// should be calculated based on the type.
- TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0) const;
-
- /// \brief Allocate a TypeSourceInfo where all locations have been
- /// initialized to a given location, which defaults to the empty
- /// location.
- TypeSourceInfo *
- getTrivialTypeSourceInfo(QualType T,
- SourceLocation Loc = SourceLocation()) const;
-
- /// \brief Add a deallocation callback that will be invoked when the
- /// ASTContext is destroyed.
- ///
- /// \param Callback A callback function that will be invoked on destruction.
- ///
- /// \param Data Pointer data that will be provided to the callback function
- /// when it is called.
- void AddDeallocation(void (*Callback)(void*), void *Data);
-
- GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
- GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
-
- /// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH
- /// lazily, only when used; this is only relevant for function or file scoped
- /// var definitions.
- ///
- /// \returns true if the function/var must be CodeGen'ed/deserialized even if
- /// it is not used.
- bool DeclMustBeEmitted(const Decl *D);
-
- const CXXConstructorDecl *
- getCopyConstructorForExceptionObject(CXXRecordDecl *RD);
-
- void addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
- CXXConstructorDecl *CD);
-
- void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
- unsigned ParmIdx, Expr *DAE);
-
- Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD,
- unsigned ParmIdx);
-
- void addTypedefNameForUnnamedTagDecl(TagDecl *TD, TypedefNameDecl *TND);
-
- TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD);
-
- void addDeclaratorForUnnamedTagDecl(TagDecl *TD, DeclaratorDecl *DD);
-
- DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD);
-
- void setManglingNumber(const NamedDecl *ND, unsigned Number);
- unsigned getManglingNumber(const NamedDecl *ND) const;
-
- void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
- unsigned getStaticLocalNumber(const VarDecl *VD) const;
-
- /// \brief Retrieve the context for computing mangling numbers in the given
- /// DeclContext.
- MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
-
- MangleNumberingContext *createMangleNumberingContext() const;
-
- /// \brief Used by ParmVarDecl to store on the side the
- /// index of the parameter when it exceeds the size of the normal bitfield.
- void setParameterIndex(const ParmVarDecl *D, unsigned index);
-
- /// \brief Used by ParmVarDecl to retrieve on the side the
- /// index of the parameter when it exceeds the size of the normal bitfield.
- unsigned getParameterIndex(const ParmVarDecl *D) const;
-
- /// \brief Get the storage for the constant value of a materialized temporary
- /// of static storage duration.
- APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
- bool MayCreate);
-
- //===--------------------------------------------------------------------===//
- // Statistics
- //===--------------------------------------------------------------------===//
-
- /// \brief The number of implicitly-declared default constructors.
- static unsigned NumImplicitDefaultConstructors;
-
- /// \brief The number of implicitly-declared default constructors for
- /// which declarations were built.
- static unsigned NumImplicitDefaultConstructorsDeclared;
-
- /// \brief The number of implicitly-declared copy constructors.
- static unsigned NumImplicitCopyConstructors;
-
- /// \brief The number of implicitly-declared copy constructors for
- /// which declarations were built.
- static unsigned NumImplicitCopyConstructorsDeclared;
-
- /// \brief The number of implicitly-declared move constructors.
- static unsigned NumImplicitMoveConstructors;
-
- /// \brief The number of implicitly-declared move constructors for
- /// which declarations were built.
- static unsigned NumImplicitMoveConstructorsDeclared;
-
- /// \brief The number of implicitly-declared copy assignment operators.
- static unsigned NumImplicitCopyAssignmentOperators;
-
- /// \brief The number of implicitly-declared copy assignment operators for
- /// which declarations were built.
- static unsigned NumImplicitCopyAssignmentOperatorsDeclared;
-
- /// \brief The number of implicitly-declared move assignment operators.
- static unsigned NumImplicitMoveAssignmentOperators;
-
- /// \brief The number of implicitly-declared move assignment operators for
- /// which declarations were built.
- static unsigned NumImplicitMoveAssignmentOperatorsDeclared;
-
- /// \brief The number of implicitly-declared destructors.
- static unsigned NumImplicitDestructors;
-
- /// \brief The number of implicitly-declared destructors for which
- /// declarations were built.
- static unsigned NumImplicitDestructorsDeclared;
-
-private:
- ASTContext(const ASTContext &) = delete;
- void operator=(const ASTContext &) = delete;
-
-public:
- /// \brief Initialize built-in types.
- ///
- /// This routine may only be invoked once for a given ASTContext object.
- /// It is normally invoked after ASTContext construction.
- ///
- /// \param Target The target
- void InitBuiltinTypes(const TargetInfo &Target,
- const TargetInfo *AuxTarget = nullptr);
-
-private:
- void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);
-
- // Return the Objective-C type encoding for a given type.
- void getObjCEncodingForTypeImpl(QualType t, std::string &S,
- bool ExpandPointedToStructures,
- bool ExpandStructures,
- const FieldDecl *Field,
- bool OutermostType = false,
- bool EncodingProperty = false,
- bool StructField = false,
- bool EncodeBlockParameters = false,
- bool EncodeClassNames = false,
- bool EncodePointerToObjCTypedef = false,
- QualType *NotEncodedT=nullptr) const;
-
- // Adds the encoding of the structure's members.
- void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
- const FieldDecl *Field,
- bool includeVBases = true,
- QualType *NotEncodedT=nullptr) const;
-public:
- // Adds the encoding of a method parameter or return type.
- void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
- QualType T, std::string& S,
- bool Extended) const;
-
- /// \brief Returns true if this is an inline-initialized static data member
- /// which is treated as a definition for MSVC compatibility.
- bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
-
-private:
- const ASTRecordLayout &
- getObjCLayout(const ObjCInterfaceDecl *D,
- const ObjCImplementationDecl *Impl) const;
-
- /// \brief A set of deallocations that should be performed when the
- /// ASTContext is destroyed.
- // FIXME: We really should have a better mechanism in the ASTContext to
- // manage running destructors for types which do variable sized allocation
- // within the AST. In some places we thread the AST bump pointer allocator
- // into the datastructures which avoids this mess during deallocation but is
- // wasteful of memory, and here we require a lot of error prone book keeping
- // in order to track and run destructors while we're tearing things down.
- typedef llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>
- DeallocationFunctionsAndArguments;
- DeallocationFunctionsAndArguments Deallocations;
-
- // FIXME: This currently contains the set of StoredDeclMaps used
- // by DeclContext objects. This probably should not be in ASTContext,
- // but we include it here so that ASTContext can quickly deallocate them.
- llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
-
- friend class DeclContext;
- friend class DeclarationNameTable;
- void ReleaseDeclContextMaps();
- void ReleaseParentMapEntries();
-
- std::unique_ptr<ParentMapPointers> PointerParents;
- std::unique_ptr<ParentMapOtherNodes> OtherParents;
-
- std::unique_ptr<VTableContextBase> VTContext;
-
-public:
- enum PragmaSectionFlag : unsigned {
- PSF_None = 0,
- PSF_Read = 0x1,
- PSF_Write = 0x2,
- PSF_Execute = 0x4,
- PSF_Implicit = 0x8,
- PSF_Invalid = 0x80000000U,
- };
-
- struct SectionInfo {
- DeclaratorDecl *Decl;
- SourceLocation PragmaSectionLocation;
- int SectionFlags;
- SectionInfo() {}
- SectionInfo(DeclaratorDecl *Decl,
- SourceLocation PragmaSectionLocation,
- int SectionFlags)
- : Decl(Decl),
- PragmaSectionLocation(PragmaSectionLocation),
- SectionFlags(SectionFlags) {}
- };
-
- llvm::StringMap<SectionInfo> SectionInfos;
-};
-
-/// \brief Utility function for constructing a nullary selector.
-static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) {
- IdentifierInfo* II = &Ctx.Idents.get(name);
- return Ctx.Selectors.getSelector(0, &II);
-}
-
-/// \brief Utility function for constructing an unary selector.
-static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
- IdentifierInfo* II = &Ctx.Idents.get(name);
- return Ctx.Selectors.getSelector(1, &II);
-}
-
-} // end namespace clang
-
-// operator new and delete aren't allowed inside namespaces.
-
-/// @brief Placement new for using the ASTContext's allocator.
-///
-/// This placement form of operator new uses the ASTContext's allocator for
-/// obtaining memory.
-///
-/// IMPORTANT: These are also declared in clang/AST/AttrIterator.h! Any changes
-/// here need to also be made there.
-///
-/// We intentionally avoid using a nothrow specification here so that the calls
-/// to this operator will not perform a null check on the result -- the
-/// underlying allocator never returns null pointers.
-///
-/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
-/// @code
-/// // Default alignment (8)
-/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
-/// // Specific alignment
-/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments);
-/// @endcode
-/// Memory allocated through this placement new operator does not need to be
-/// explicitly freed, as ASTContext will free all of this memory when it gets
-/// destroyed. Please note that you cannot use delete on the pointer.
-///
-/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
-/// @param C The ASTContext that provides the allocator.
-/// @param Alignment The alignment of the allocated memory (if the underlying
-/// allocator supports it).
-/// @return The allocated memory. Could be NULL.
-inline void *operator new(size_t Bytes, const clang::ASTContext &C,
- size_t Alignment) {
- return C.Allocate(Bytes, Alignment);
-}
-/// @brief Placement delete companion to the new above.
-///
-/// This operator is just a companion to the new above. There is no way of
-/// invoking it directly; see the new operator for more details. This operator
-/// is called implicitly by the compiler if a placement new expression using
-/// the ASTContext throws in the object constructor.
-inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
- C.Deallocate(Ptr);
-}
-
-/// This placement form of operator new[] uses the ASTContext's allocator for
-/// obtaining memory.
-///
-/// We intentionally avoid using a nothrow specification here so that the calls
-/// to this operator will not perform a null check on the result -- the
-/// underlying allocator never returns null pointers.
-///
-/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
-/// @code
-/// // Default alignment (8)
-/// char *data = new (Context) char[10];
-/// // Specific alignment
-/// char *data = new (Context, 4) char[10];
-/// @endcode
-/// Memory allocated through this placement new[] operator does not need to be
-/// explicitly freed, as ASTContext will free all of this memory when it gets
-/// destroyed. Please note that you cannot use delete on the pointer.
-///
-/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
-/// @param C The ASTContext that provides the allocator.
-/// @param Alignment The alignment of the allocated memory (if the underlying
-/// allocator supports it).
-/// @return The allocated memory. Could be NULL.
-inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
- size_t Alignment = 8) {
- return C.Allocate(Bytes, Alignment);
-}
-
-/// @brief Placement delete[] companion to the new[] above.
-///
-/// This operator is just a companion to the new[] above. There is no way of
-/// invoking it directly; see the new[] operator for more details. This operator
-/// is called implicitly by the compiler if a placement new[] expression using
-/// the ASTContext throws in the object constructor.
-inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) {
- C.Deallocate(Ptr);
-}
-
-/// \brief Create the representation of a LazyGenerationalUpdatePtr.
-template <typename Owner, typename T,
- void (clang::ExternalASTSource::*Update)(Owner)>
-typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
- clang::LazyGenerationalUpdatePtr<Owner, T, Update>::makeValue(
- const clang::ASTContext &Ctx, T Value) {
- // Note, this is implemented here so that ExternalASTSource.h doesn't need to
- // include ASTContext.h. We explicitly instantiate it for all relevant types
- // in ASTContext.cpp.
- if (auto *Source = Ctx.getExternalSource())
- return new (Ctx) LazyData(Source, Value);
- return Value;
-}
-
-#endif
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
deleted file mode 100644
index 27c85e6..0000000
--- a/include/clang/AST/ASTDiagnostic.h
+++ /dev/null
@@ -1,47 +0,0 @@
-//===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTDIAGNOSTIC_H
-#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define ASTSTART
-#include "clang/Basic/DiagnosticASTKinds.inc"
-#undef DIAG
- NUM_BUILTIN_AST_DIAGNOSTICS
- };
- } // end namespace diag
-
- /// \brief DiagnosticsEngine argument formatting function for diagnostics that
- /// involve AST nodes.
- ///
- /// This function formats diagnostic arguments for various AST nodes,
- /// including types, declaration names, nested name specifiers, and
- /// declaration contexts, into strings that can be printed as part of
- /// diagnostics. It is meant to be used as the argument to
- /// \c DiagnosticsEngine::SetArgToStringFn(), where the cookie is an \c
- /// ASTContext pointer.
- void FormatASTNodeDiagnosticArgument(
- DiagnosticsEngine::ArgumentKind Kind,
- intptr_t Val,
- StringRef Modifier,
- StringRef Argument,
- ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
- SmallVectorImpl<char> &Output,
- void *Cookie,
- ArrayRef<intptr_t> QualTypeVals);
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h
deleted file mode 100644
index 003d489..0000000
--- a/include/clang/AST/ASTFwd.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===--- ASTFwd.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--------------------------------------------------------------===//
-///
-/// \file
-/// \brief Forward declaration of all AST node types.
-///
-//===-------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTFWD_H
-#define LLVM_CLANG_AST_ASTFWD_H
-
-namespace clang {
-
-class Decl;
-#define DECL(DERIVED, BASE) class DERIVED##Decl;
-#include "clang/AST/DeclNodes.inc"
-class Stmt;
-#define STMT(DERIVED, BASE) class DERIVED;
-#include "clang/AST/StmtNodes.inc"
-class Type;
-#define TYPE(DERIVED, BASE) class DERIVED##Type;
-#include "clang/AST/TypeNodes.def"
-class CXXCtorInitializer;
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
deleted file mode 100644
index ee48955..0000000
--- a/include/clang/AST/ASTImporter.h
+++ /dev/null
@@ -1,295 +0,0 @@
-//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ASTImporter class which imports AST nodes from one
-// context into another context.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
-#define LLVM_CLANG_AST_ASTIMPORTER_H
-
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
- class ASTContext;
- class Decl;
- class DeclContext;
- class DiagnosticsEngine;
- class Expr;
- class FileManager;
- class IdentifierInfo;
- class NestedNameSpecifier;
- class Stmt;
- class TypeSourceInfo;
-
- /// \brief Imports selected nodes from one AST context into another context,
- /// merging AST nodes where appropriate.
- class ASTImporter {
- public:
- typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
-
- private:
- /// \brief The contexts we're importing to and from.
- ASTContext &ToContext, &FromContext;
-
- /// \brief The file managers we're importing to and from.
- FileManager &ToFileManager, &FromFileManager;
-
- /// \brief Whether to perform a minimal import.
- bool Minimal;
-
- /// \brief Whether the last diagnostic came from the "from" context.
- bool LastDiagFromFrom;
-
- /// \brief Mapping from the already-imported types in the "from" context
- /// to the corresponding types in the "to" context.
- llvm::DenseMap<const Type *, const Type *> ImportedTypes;
-
- /// \brief Mapping from the already-imported declarations in the "from"
- /// context to the corresponding declarations in the "to" context.
- llvm::DenseMap<Decl *, Decl *> ImportedDecls;
-
- /// \brief Mapping from the already-imported statements in the "from"
- /// context to the corresponding statements in the "to" context.
- llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
-
- /// \brief Mapping from the already-imported FileIDs in the "from" source
- /// manager to the corresponding FileIDs in the "to" source manager.
- llvm::DenseMap<FileID, FileID> ImportedFileIDs;
-
- /// \brief Imported, anonymous tag declarations that are missing their
- /// corresponding typedefs.
- SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
-
- /// \brief Declaration (from, to) pairs that are known not to be equivalent
- /// (which we have already complained about).
- NonEquivalentDeclSet NonEquivalentDecls;
-
- public:
- /// \brief Create a new AST importer.
- ///
- /// \param ToContext The context we'll be importing into.
- ///
- /// \param ToFileManager The file manager we'll be importing into.
- ///
- /// \param FromContext The context we'll be importing from.
- ///
- /// \param FromFileManager The file manager we'll be importing into.
- ///
- /// \param MinimalImport If true, the importer will attempt to import
- /// as little as it can, e.g., by importing declarations as forward
- /// declarations that can be completed at a later point.
- ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
- ASTContext &FromContext, FileManager &FromFileManager,
- bool MinimalImport);
-
- virtual ~ASTImporter();
-
- /// \brief Whether the importer will perform a minimal import, creating
- /// to-be-completed forward declarations when possible.
- bool isMinimalImport() const { return Minimal; }
-
- /// \brief Import the given type from the "from" context into the "to"
- /// context.
- ///
- /// \returns the equivalent type in the "to" context, or a NULL type if
- /// an error occurred.
- QualType Import(QualType FromT);
-
- /// \brief Import the given type source information from the
- /// "from" context into the "to" context.
- ///
- /// \returns the equivalent type source information in the "to"
- /// context, or NULL if an error occurred.
- TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
-
- /// \brief Import the given declaration from the "from" context into the
- /// "to" context.
- ///
- /// \returns the equivalent declaration in the "to" context, or a NULL type
- /// if an error occurred.
- Decl *Import(Decl *FromD);
-
- /// \brief Return the copy of the given declaration in the "to" context if
- /// it has already been imported from the "from" context. Otherwise return
- /// NULL.
- Decl *GetAlreadyImportedOrNull(Decl *FromD);
-
- /// \brief Import the given declaration context from the "from"
- /// AST context into the "to" AST context.
- ///
- /// \returns the equivalent declaration context in the "to"
- /// context, or a NULL type if an error occurred.
- DeclContext *ImportContext(DeclContext *FromDC);
-
- /// \brief Import the given expression from the "from" context into the
- /// "to" context.
- ///
- /// \returns the equivalent expression in the "to" context, or NULL if
- /// an error occurred.
- Expr *Import(Expr *FromE);
-
- /// \brief Import the given statement from the "from" context into the
- /// "to" context.
- ///
- /// \returns the equivalent statement in the "to" context, or NULL if
- /// an error occurred.
- Stmt *Import(Stmt *FromS);
-
- /// \brief Import the given nested-name-specifier from the "from"
- /// context into the "to" context.
- ///
- /// \returns the equivalent nested-name-specifier in the "to"
- /// context, or NULL if an error occurred.
- NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
-
- /// \brief Import the given nested-name-specifier from the "from"
- /// context into the "to" context.
- ///
- /// \returns the equivalent nested-name-specifier in the "to"
- /// context.
- NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS);
-
- /// \brief Import the goven template name from the "from" context into the
- /// "to" context.
- TemplateName Import(TemplateName From);
-
- /// \brief Import the given source location from the "from" context into
- /// the "to" context.
- ///
- /// \returns the equivalent source location in the "to" context, or an
- /// invalid source location if an error occurred.
- SourceLocation Import(SourceLocation FromLoc);
-
- /// \brief Import the given source range from the "from" context into
- /// the "to" context.
- ///
- /// \returns the equivalent source range in the "to" context, or an
- /// invalid source location if an error occurred.
- SourceRange Import(SourceRange FromRange);
-
- /// \brief Import the given declaration name from the "from"
- /// context into the "to" context.
- ///
- /// \returns the equivalent declaration name in the "to" context,
- /// or an empty declaration name if an error occurred.
- DeclarationName Import(DeclarationName FromName);
-
- /// \brief Import the given identifier from the "from" context
- /// into the "to" context.
- ///
- /// \returns the equivalent identifier in the "to" context.
- IdentifierInfo *Import(const IdentifierInfo *FromId);
-
- /// \brief Import the given Objective-C selector from the "from"
- /// context into the "to" context.
- ///
- /// \returns the equivalent selector in the "to" context.
- Selector Import(Selector FromSel);
-
- /// \brief Import the given file ID from the "from" context into the
- /// "to" context.
- ///
- /// \returns the equivalent file ID in the source manager of the "to"
- /// context.
- FileID Import(FileID);
-
- /// \brief Import the definition of the given declaration, including all of
- /// the declarations it contains.
- ///
- /// This routine is intended to be used
- void ImportDefinition(Decl *From);
-
- /// \brief Cope with a name conflict when importing a declaration into the
- /// given context.
- ///
- /// This routine is invoked whenever there is a name conflict while
- /// importing a declaration. The returned name will become the name of the
- /// imported declaration. By default, the returned name is the same as the
- /// original name, leaving the conflict unresolve such that name lookup
- /// for this name is likely to find an ambiguity later.
- ///
- /// Subclasses may override this routine to resolve the conflict, e.g., by
- /// renaming the declaration being imported.
- ///
- /// \param Name the name of the declaration being imported, which conflicts
- /// with other declarations.
- ///
- /// \param DC the declaration context (in the "to" AST context) in which
- /// the name is being imported.
- ///
- /// \param IDNS the identifier namespace in which the name will be found.
- ///
- /// \param Decls the set of declarations with the same name as the
- /// declaration being imported.
- ///
- /// \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);
-
- /// \brief Retrieve the context that AST nodes are being imported into.
- ASTContext &getToContext() const { return ToContext; }
-
- /// \brief Retrieve the context that AST nodes are being imported from.
- ASTContext &getFromContext() const { return FromContext; }
-
- /// \brief Retrieve the file manager that AST nodes are being imported into.
- FileManager &getToFileManager() const { return ToFileManager; }
-
- /// \brief Retrieve the file manager that AST nodes are being imported from.
- FileManager &getFromFileManager() const { return FromFileManager; }
-
- /// \brief Report a diagnostic in the "to" context.
- DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
-
- /// \brief Report a diagnostic in the "from" context.
- DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
-
- /// \brief Return the set of declarations that we know are not equivalent.
- NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
-
- /// \brief Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
- /// Mark the Decl as complete, filling it in as much as possible.
- ///
- /// \param D A declaration in the "to" context.
- virtual void CompleteDecl(Decl* D);
-
- /// \brief Note that we have imported the "from" declaration by mapping it
- /// to the (potentially-newly-created) "to" declaration.
- ///
- /// Subclasses can override this function to observe all of the \c From ->
- /// \c To declaration mappings as they are imported.
- virtual Decl *Imported(Decl *From, Decl *To);
-
- /// \brief Called by StructuralEquivalenceContext. If a RecordDecl is
- /// being compared to another RecordDecl as part of import, completing the
- /// other RecordDecl may trigger importation of the first RecordDecl. This
- /// happens especially for anonymous structs. If the original of the second
- /// RecordDecl can be found, we can complete it without the need for
- /// importation, eliminating this loop.
- virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
-
- /// \brief Determine whether the given types are structurally
- /// equivalent.
- bool IsStructurallyEquivalent(QualType From, QualType To,
- bool Complain = true);
- };
-}
-
-#endif // LLVM_CLANG_AST_ASTIMPORTER_H
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
deleted file mode 100644
index 69df2d8..0000000
--- a/include/clang/AST/ASTLambda.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file provides some common utility functions for processing
-/// Lambda related AST Constructs.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTLAMBDA_H
-#define LLVM_CLANG_AST_ASTLAMBDA_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
-
-namespace clang {
-inline StringRef getLambdaStaticInvokerName() {
- return "__invoke";
-}
-// This function returns true if M is a specialization, a template,
-// or a non-generic lambda call operator.
-inline bool isLambdaCallOperator(const CXXMethodDecl *MD) {
- const CXXRecordDecl *LambdaClass = MD->getParent();
- if (!LambdaClass || !LambdaClass->isLambda()) return false;
- return MD->getOverloadedOperator() == OO_Call;
-}
-
-inline bool isLambdaCallOperator(const DeclContext *DC) {
- if (!DC || !isa<CXXMethodDecl>(DC)) return false;
- return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
-}
-
-inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {
- if (!MD) return false;
- const CXXRecordDecl *LambdaClass = MD->getParent();
- if (LambdaClass && LambdaClass->isGenericLambda())
- return isLambdaCallOperator(MD) &&
- MD->isFunctionTemplateSpecialization();
- return false;
-}
-
-inline bool isLambdaConversionOperator(CXXConversionDecl *C) {
- return C ? C->getParent()->isLambda() : false;
-}
-
-inline bool isLambdaConversionOperator(Decl *D) {
- if (!D) return false;
- if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D))
- return isLambdaConversionOperator(Conv);
- if (FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(D))
- if (CXXConversionDecl *Conv =
- dyn_cast_or_null<CXXConversionDecl>(F->getTemplatedDecl()))
- return isLambdaConversionOperator(Conv);
- return false;
-}
-
-inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) {
- return isGenericLambdaCallOperatorSpecialization(
- dyn_cast<CXXMethodDecl>(DC));
-}
-
-
-// This returns the parent DeclContext ensuring that the correct
-// parent DeclContext is returned for Lambdas
-inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) {
- if (isLambdaCallOperator(DC))
- return DC->getParent()->getParent();
- else
- return DC->getParent();
-}
-
-} // clang
-
-#endif
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
deleted file mode 100644
index 3ff392d..0000000
--- a/include/clang/AST/ASTMutationListener.h
+++ /dev/null
@@ -1,127 +0,0 @@
-//===--- ASTMutationListener.h - AST Mutation Interface --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ASTMutationListener interface.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
-#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
-
-namespace clang {
- class Attr;
- class ClassTemplateDecl;
- class ClassTemplateSpecializationDecl;
- class CXXDestructorDecl;
- class CXXRecordDecl;
- class Decl;
- class DeclContext;
- class FunctionDecl;
- class FunctionTemplateDecl;
- class Module;
- class NamedDecl;
- class ObjCCategoryDecl;
- class ObjCContainerDecl;
- class ObjCInterfaceDecl;
- class ObjCPropertyDecl;
- class QualType;
- class RecordDecl;
- class TagDecl;
- class VarDecl;
- class VarTemplateDecl;
- class VarTemplateSpecializationDecl;
-
-/// \brief An abstract interface that should be implemented by listeners
-/// that want to be notified when an AST entity gets modified after its
-/// initial creation.
-class ASTMutationListener {
-public:
- virtual ~ASTMutationListener();
-
- /// \brief A new TagDecl definition was completed.
- virtual void CompletedTagDefinition(const TagDecl *D) { }
-
- /// \brief A new declaration with name has been added to a DeclContext.
- virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D) {}
-
- /// \brief An implicit member was added after the definition was completed.
- virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {}
-
- /// \brief A template specialization (or partial one) was added to the
- /// template declaration.
- virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
- const ClassTemplateSpecializationDecl *D) {}
-
- /// \brief A template specialization (or partial one) was added to the
- /// template declaration.
- virtual void
- AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
- const VarTemplateSpecializationDecl *D) {}
-
- /// \brief A template specialization (or partial one) was added to the
- /// template declaration.
- virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
- const FunctionDecl *D) {}
-
- /// \brief A function's exception specification has been evaluated or
- /// instantiated.
- virtual void ResolvedExceptionSpec(const FunctionDecl *FD) {}
-
- /// \brief A function's return type has been deduced.
- virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
-
- /// \brief A virtual destructor's operator delete has been resolved.
- virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
- const FunctionDecl *Delete) {}
-
- /// \brief An implicit member got a definition.
- virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
-
- /// \brief A static data member was implicitly instantiated.
- virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
-
- /// \brief A function template's definition was instantiated.
- virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
-
- /// \brief A new objc category class was added for an interface.
- virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
- const ObjCInterfaceDecl *IFD) {}
-
- /// \brief A declaration is marked used which was not previously marked used.
- ///
- /// \param D the declaration marked used
- virtual void DeclarationMarkedUsed(const Decl *D) {}
-
- /// \brief A declaration is marked as OpenMP threadprivate which was not
- /// previously marked as threadprivate.
- ///
- /// \param D the declaration marked OpenMP threadprivate.
- virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {}
-
- /// \brief A definition has been made visible by being redefined locally.
- ///
- /// \param D The definition that was previously not visible.
- /// \param M The containing module in which the definition was made visible,
- /// if any.
- virtual void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {}
-
- /// \brief An attribute was added to a RecordDecl
- ///
- /// \param Attr The attribute that was added to the Record
- ///
- /// \param Record The RecordDecl that got a new attribute
- virtual void AddedAttributeToRecord(const Attr *Attr,
- const RecordDecl *Record) {}
-
- // NOTE: If new methods are added they should also be added to
- // MultiplexASTMutationListener.
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
deleted file mode 100644
index dcaac80..0000000
--- a/include/clang/AST/ASTTypeTraits.h
+++ /dev/null
@@ -1,509 +0,0 @@
-//===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Provides a dynamic type identifier and a dynamically typed node container
-// that can be used to store an AST base node at runtime in the same storage in
-// a type safe way.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
-#define LLVM_CLANG_AST_ASTTYPETRAITS_H
-
-#include "clang/AST/ASTFwd.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/Support/AlignOf.h"
-
-namespace llvm {
-
-class raw_ostream;
-
-}
-
-namespace clang {
-
-struct PrintingPolicy;
-
-namespace ast_type_traits {
-
-/// \brief Kind identifier.
-///
-/// It can be constructed from any node kind and allows for runtime type
-/// hierarchy checks.
-/// Use getFromNodeKind<T>() to construct them.
-class ASTNodeKind {
-public:
- /// \brief Empty identifier. It matches nothing.
- ASTNodeKind() : KindId(NKI_None) {}
-
- /// \brief Construct an identifier for T.
- template <class T>
- static ASTNodeKind getFromNodeKind() {
- return ASTNodeKind(KindToKindId<T>::Id);
- }
-
- /// \{
- /// \brief Construct an identifier for the dynamic type of the node
- static ASTNodeKind getFromNode(const Decl &D);
- static ASTNodeKind getFromNode(const Stmt &S);
- static ASTNodeKind getFromNode(const Type &T);
- /// \}
-
- /// \brief Returns \c true if \c this and \c Other represent the same kind.
- bool isSame(ASTNodeKind Other) const;
-
- /// \brief Returns \c true only for the default \c ASTNodeKind()
- bool isNone() const { return KindId == NKI_None; }
-
- /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
- /// \param Distance If non-null, used to return the distance between \c this
- /// and \c Other in the class hierarchy.
- bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
-
- /// \brief String representation of the kind.
- StringRef asStringRef() const;
-
- /// \brief Strict weak ordering for ASTNodeKind.
- bool operator<(const ASTNodeKind &Other) const {
- return KindId < Other.KindId;
- }
-
- /// \brief Return the most derived type between \p Kind1 and \p Kind2.
- ///
- /// Return ASTNodeKind() if they are not related.
- static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2);
-
- /// \brief Return the most derived common ancestor between Kind1 and Kind2.
- ///
- /// Return ASTNodeKind() if they are not related.
- static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
- ASTNodeKind Kind2);
-
- /// \brief Hooks for using ASTNodeKind as a key in a DenseMap.
- struct DenseMapInfo {
- // ASTNodeKind() is a good empty key because it is represented as a 0.
- static inline ASTNodeKind getEmptyKey() { return ASTNodeKind(); }
- // NKI_NumberOfKinds is not a valid value, so it is good for a
- // tombstone key.
- static inline ASTNodeKind getTombstoneKey() {
- return ASTNodeKind(NKI_NumberOfKinds);
- }
- static unsigned getHashValue(const ASTNodeKind &Val) { return Val.KindId; }
- static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS) {
- return LHS.KindId == RHS.KindId;
- }
- };
-
- /// Check if the given ASTNodeKind identifies a type that offers pointer
- /// identity. This is useful for the fast path in DynTypedNode.
- bool hasPointerIdentity() const {
- return KindId > NKI_LastKindWithoutPointerIdentity;
- }
-
-private:
- /// \brief Kind ids.
- ///
- /// Includes all possible base and derived kinds.
- enum NodeKindId {
- NKI_None,
- NKI_TemplateArgument,
- NKI_NestedNameSpecifierLoc,
- NKI_QualType,
- NKI_TypeLoc,
- NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
- NKI_CXXCtorInitializer,
- NKI_NestedNameSpecifier,
- NKI_Decl,
-#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
-#include "clang/AST/DeclNodes.inc"
- NKI_Stmt,
-#define STMT(DERIVED, BASE) NKI_##DERIVED,
-#include "clang/AST/StmtNodes.inc"
- NKI_Type,
-#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
-#include "clang/AST/TypeNodes.def"
- NKI_NumberOfKinds
- };
-
- /// \brief Use getFromNodeKind<T>() to construct the kind.
- ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
-
- /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
- /// Derived.
- /// \param Distance If non-null, used to return the distance between \c Base
- /// and \c Derived in the class hierarchy.
- static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
-
- /// \brief Helper meta-function to convert a kind T to its enum value.
- ///
- /// This struct is specialized below for all known kinds.
- template <class T> struct KindToKindId {
- static const NodeKindId Id = NKI_None;
- };
- template <class T>
- struct KindToKindId<const T> : KindToKindId<T> {};
-
- /// \brief Per kind info.
- struct KindInfo {
- /// \brief The id of the parent kind, or None if it has no parent.
- NodeKindId ParentId;
- /// \brief Name of the kind.
- const char *Name;
- };
- static const KindInfo AllKindInfo[NKI_NumberOfKinds];
-
- NodeKindId KindId;
-};
-
-#define KIND_TO_KIND_ID(Class) \
- template <> struct ASTNodeKind::KindToKindId<Class> { \
- static const NodeKindId Id = NKI_##Class; \
- };
-KIND_TO_KIND_ID(CXXCtorInitializer)
-KIND_TO_KIND_ID(TemplateArgument)
-KIND_TO_KIND_ID(NestedNameSpecifier)
-KIND_TO_KIND_ID(NestedNameSpecifierLoc)
-KIND_TO_KIND_ID(QualType)
-KIND_TO_KIND_ID(TypeLoc)
-KIND_TO_KIND_ID(Decl)
-KIND_TO_KIND_ID(Stmt)
-KIND_TO_KIND_ID(Type)
-#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
-#include "clang/AST/DeclNodes.inc"
-#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
-#include "clang/AST/StmtNodes.inc"
-#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
-#include "clang/AST/TypeNodes.def"
-#undef KIND_TO_KIND_ID
-
-inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
- OS << K.asStringRef();
- return OS;
-}
-
-/// \brief A dynamically typed AST node container.
-///
-/// Stores an AST node in a type safe way. This allows writing code that
-/// works with different kinds of AST nodes, despite the fact that they don't
-/// have a common base class.
-///
-/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
-/// and \c get<T>() to retrieve the node as type T if the types match.
-///
-/// See \c ASTNodeKind for which node base types are currently supported;
-/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
-/// the supported base types.
-class DynTypedNode {
-public:
- /// \brief Creates a \c DynTypedNode from \c Node.
- template <typename T>
- static DynTypedNode create(const T &Node) {
- return BaseConverter<T>::create(Node);
- }
-
- /// \brief Retrieve the stored node as type \c T.
- ///
- /// Returns NULL if the stored node does not have a type that is
- /// convertible to \c T.
- ///
- /// For types that have identity via their pointer in the AST
- /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
- /// pointer points to the referenced AST node.
- /// For other types (like \c QualType) the value is stored directly
- /// in the \c DynTypedNode, and the returned pointer points at
- /// the storage inside DynTypedNode. For those nodes, do not
- /// use the pointer outside the scope of the DynTypedNode.
- template <typename T>
- const T *get() const {
- return BaseConverter<T>::get(NodeKind, Storage.buffer);
- }
-
- /// \brief Retrieve the stored node as type \c T.
- ///
- /// Similar to \c get(), but asserts that the type is what we are expecting.
- template <typename T>
- const T &getUnchecked() const {
- return BaseConverter<T>::getUnchecked(NodeKind, Storage.buffer);
- }
-
- ASTNodeKind getNodeKind() const { return NodeKind; }
-
- /// \brief Returns a pointer that identifies the stored AST node.
- ///
- /// Note that this is not supported by all AST nodes. For AST nodes
- /// that don't have a pointer-defined identity inside the AST, this
- /// method returns NULL.
- const void *getMemoizationData() const {
- return NodeKind.hasPointerIdentity()
- ? *reinterpret_cast<void *const *>(Storage.buffer)
- : nullptr;
- }
-
- /// \brief Prints the node to the given output stream.
- void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
-
- /// \brief Dumps the node to the given output stream.
- void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
-
- /// \brief For nodes which represent textual entities in the source code,
- /// return their SourceRange. For all other nodes, return SourceRange().
- SourceRange getSourceRange() const;
-
- /// @{
- /// \brief Imposes an order on \c DynTypedNode.
- ///
- /// Supports comparison of nodes that support memoization.
- /// FIXME: Implement comparsion for other node types (currently
- /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
- bool operator<(const DynTypedNode &Other) const {
- if (!NodeKind.isSame(Other.NodeKind))
- return NodeKind < Other.NodeKind;
-
- if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
- return getUnchecked<QualType>().getAsOpaquePtr() <
- Other.getUnchecked<QualType>().getAsOpaquePtr();
-
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) {
- auto TLA = getUnchecked<TypeLoc>();
- auto TLB = Other.getUnchecked<TypeLoc>();
- return std::make_pair(TLA.getType().getAsOpaquePtr(),
- TLA.getOpaqueData()) <
- std::make_pair(TLB.getType().getAsOpaquePtr(),
- TLB.getOpaqueData());
- }
-
- if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
- NodeKind)) {
- auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
- auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
- return std::make_pair(NNSLA.getNestedNameSpecifier(),
- NNSLA.getOpaqueData()) <
- std::make_pair(NNSLB.getNestedNameSpecifier(),
- NNSLB.getOpaqueData());
- }
-
- assert(getMemoizationData() && Other.getMemoizationData());
- return getMemoizationData() < Other.getMemoizationData();
- }
- bool operator==(const DynTypedNode &Other) const {
- // DynTypedNode::create() stores the exact kind of the node in NodeKind.
- // If they contain the same node, their NodeKind must be the same.
- if (!NodeKind.isSame(Other.NodeKind))
- return false;
-
- // FIXME: Implement for other types.
- if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
- return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
-
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind))
- return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
-
- if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
- return getUnchecked<NestedNameSpecifierLoc>() ==
- Other.getUnchecked<NestedNameSpecifierLoc>();
-
- assert(getMemoizationData() && Other.getMemoizationData());
- return getMemoizationData() == Other.getMemoizationData();
- }
- bool operator!=(const DynTypedNode &Other) const {
- return !operator==(Other);
- }
- /// @}
-
- /// \brief Hooks for using DynTypedNode as a key in a DenseMap.
- struct DenseMapInfo {
- static inline DynTypedNode getEmptyKey() {
- DynTypedNode Node;
- Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey();
- return Node;
- }
- static inline DynTypedNode getTombstoneKey() {
- DynTypedNode Node;
- Node.NodeKind = ASTNodeKind::DenseMapInfo::getTombstoneKey();
- return Node;
- }
- static unsigned getHashValue(const DynTypedNode &Val) {
- // FIXME: Add hashing support for the remaining types.
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(Val.NodeKind)) {
- auto TL = Val.getUnchecked<TypeLoc>();
- return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
- TL.getOpaqueData());
- }
-
- if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
- Val.NodeKind)) {
- auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
- return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
- NNSL.getOpaqueData());
- }
-
- assert(Val.getMemoizationData());
- return llvm::hash_value(Val.getMemoizationData());
- }
- static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
- auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey();
- auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey();
- return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
- ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) ||
- (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) &&
- ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) ||
- LHS == RHS;
- }
- };
-
-private:
- /// \brief Takes care of converting from and to \c T.
- template <typename T, typename EnablerT = void> struct BaseConverter;
-
- /// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
- template <typename T, typename BaseT> struct DynCastPtrConverter {
- static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
- if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
- return &getUnchecked(NodeKind, Storage);
- return nullptr;
- }
- static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
- assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
- return *cast<T>(static_cast<const BaseT *>(
- *reinterpret_cast<const void *const *>(Storage)));
- }
- static DynTypedNode create(const BaseT &Node) {
- DynTypedNode Result;
- Result.NodeKind = ASTNodeKind::getFromNode(Node);
- new (Result.Storage.buffer) const void *(&Node);
- return Result;
- }
- };
-
- /// \brief Converter that stores T* (by pointer).
- template <typename T> struct PtrConverter {
- static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
- if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
- return &getUnchecked(NodeKind, Storage);
- return nullptr;
- }
- static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
- assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
- return *static_cast<const T *>(
- *reinterpret_cast<const void *const *>(Storage));
- }
- static DynTypedNode create(const T &Node) {
- DynTypedNode Result;
- Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
- new (Result.Storage.buffer) const void *(&Node);
- return Result;
- }
- };
-
- /// \brief Converter that stores T (by value).
- template <typename T> struct ValueConverter {
- static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
- if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
- return reinterpret_cast<const T *>(Storage);
- return nullptr;
- }
- static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
- assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
- return *reinterpret_cast<const T *>(Storage);
- }
- static DynTypedNode create(const T &Node) {
- DynTypedNode Result;
- Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
- new (Result.Storage.buffer) T(Node);
- return Result;
- }
- };
-
- ASTNodeKind NodeKind;
-
- /// \brief Stores the data of the node.
- ///
- /// Note that we can store \c Decls, \c Stmts, \c Types,
- /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
- /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
- /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and
- /// \c TemplateArguments on the other hand do not have storage or unique
- /// pointers and thus need to be stored by value.
- llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
- NestedNameSpecifierLoc, QualType,
- TypeLoc> Storage;
-};
-
-template <typename T>
-struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
- : public DynCastPtrConverter<T, Decl> {};
-
-template <typename T>
-struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
- : public DynCastPtrConverter<T, Stmt> {};
-
-template <typename T>
-struct DynTypedNode::BaseConverter<
- T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
- : public DynCastPtrConverter<T, Type> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- NestedNameSpecifierLoc,
- void> : public ValueConverter<NestedNameSpecifierLoc> {};
-
-template <>
-struct DynTypedNode::BaseConverter<QualType,
- void> : public ValueConverter<QualType> {};
-
-template <>
-struct DynTypedNode::BaseConverter<
- TypeLoc, void> : public ValueConverter<TypeLoc> {};
-
-// The only operation we allow on unsupported types is \c get.
-// This allows to conveniently use \c DynTypedNode when having an arbitrary
-// AST node that is not supported, but prevents misuse - a user cannot create
-// a DynTypedNode from arbitrary types.
-template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
- static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
- return NULL;
- }
-};
-
-} // end namespace ast_type_traits
-} // end namespace clang
-
-namespace llvm {
-
-template <>
-struct DenseMapInfo<clang::ast_type_traits::ASTNodeKind>
- : clang::ast_type_traits::ASTNodeKind::DenseMapInfo {};
-
-template <>
-struct DenseMapInfo<clang::ast_type_traits::DynTypedNode>
- : clang::ast_type_traits::DynTypedNode::DenseMapInfo {};
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
deleted file mode 100644
index 9078a0e..0000000
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//===-- ASTUnresolvedSet.h - Unresolved sets of declarations ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides an UnresolvedSet-like class, whose contents are
-// allocated using the allocator associated with an ASTContext.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
-#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
-
-#include "clang/AST/ASTVector.h"
-#include "clang/AST/UnresolvedSet.h"
-
-namespace clang {
-
-/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
-class ASTUnresolvedSet {
- struct DeclsTy : ASTVector<DeclAccessPair> {
- DeclsTy() {}
- DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {}
-
- bool isLazy() const { return getTag(); }
- void setLazy(bool Lazy) { setTag(Lazy); }
- };
-
- DeclsTy Decls;
-
- friend class LazyASTUnresolvedSet;
-
-public:
- ASTUnresolvedSet() {}
- ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
-
- typedef UnresolvedSetIterator iterator;
- typedef UnresolvedSetIterator const_iterator;
-
- iterator begin() { return iterator(Decls.begin()); }
- iterator end() { return iterator(Decls.end()); }
-
- const_iterator begin() const { return const_iterator(Decls.begin()); }
- const_iterator end() const { return const_iterator(Decls.end()); }
-
- void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) {
- Decls.push_back(DeclAccessPair::make(D, AS), C);
- }
-
- /// Replaces the given declaration with the new one, once.
- ///
- /// \return true if the set changed
- bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) {
- for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
- if (I->getDecl() == Old) {
- I->set(New, AS);
- return true;
- }
- }
- return false;
- }
-
- void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); }
-
- void clear() { Decls.clear(); }
-
- bool empty() const { return Decls.empty(); }
- unsigned size() const { return Decls.size(); }
-
- void reserve(ASTContext &C, unsigned N) {
- Decls.reserve(C, N);
- }
-
- void append(ASTContext &C, iterator I, iterator E) {
- Decls.append(C, I.I, E.I);
- }
-
- DeclAccessPair &operator[](unsigned I) { return Decls[I]; }
- const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
-};
-
-/// \brief An UnresolvedSet-like class that might not have been loaded from the
-/// external AST source yet.
-class LazyASTUnresolvedSet {
- mutable ASTUnresolvedSet Impl;
-
- void getFromExternalSource(ASTContext &C) const;
-
-public:
- ASTUnresolvedSet &get(ASTContext &C) const {
- if (Impl.Decls.isLazy())
- getFromExternalSource(C);
- return Impl;
- }
-
- void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }
- void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
- assert(Impl.empty() || Impl.Decls.isLazy());
- Impl.Decls.setLazy(true);
- Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS);
- }
-};
-
-} // namespace clang
-
-#endif
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
deleted file mode 100644
index 79453bf..0000000
--- a/include/clang/AST/ASTVector.h
+++ /dev/null
@@ -1,405 +0,0 @@
-//===- ASTVector.h - Vector that uses ASTContext for allocation --*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides ASTVector, a vector ADT whose contents are
-// allocated using the allocator associated with an ASTContext..
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: Most of this is copy-and-paste from BumpVector.h and SmallVector.h.
-// We can refactor this core logic into something common.
-
-#ifndef LLVM_CLANG_AST_ASTVECTOR_H
-#define LLVM_CLANG_AST_ASTVECTOR_H
-
-#include "clang/AST/AttrIterator.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/type_traits.h"
-#include <algorithm>
-#include <cstring>
-#include <memory>
-
-namespace clang {
- class ASTContext;
-
-template<typename T>
-class ASTVector {
-private:
- T *Begin, *End;
- llvm::PointerIntPair<T*, 1, bool> Capacity;
-
- void setEnd(T *P) { this->End = P; }
-
-protected:
- // Make a tag bit available to users of this class.
- // FIXME: This is a horrible hack.
- bool getTag() const { return Capacity.getInt(); }
- void setTag(bool B) { Capacity.setInt(B); }
-
-public:
- // Default ctor - Initialize to empty.
- ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {}
-
- ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
- O.Begin = O.End = nullptr;
- O.Capacity.setPointer(nullptr);
- O.Capacity.setInt(false);
- }
-
- ASTVector(const ASTContext &C, unsigned N)
- : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
- reserve(C, N);
- }
-
- ASTVector &operator=(ASTVector &&RHS) {
- ASTVector O(std::move(RHS));
- using std::swap;
- swap(Begin, O.Begin);
- swap(End, O.End);
- swap(Capacity, O.Capacity);
- return *this;
- }
-
- ~ASTVector() {
- if (std::is_class<T>::value) {
- // Destroy the constructed elements in the vector.
- destroy_range(Begin, End);
- }
- }
-
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T value_type;
- typedef T* iterator;
- typedef const T* const_iterator;
-
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
-
- typedef T& reference;
- typedef const T& const_reference;
- typedef T* pointer;
- typedef const T* const_pointer;
-
- // forward iterator creation methods.
- iterator begin() { return Begin; }
- const_iterator begin() const { return Begin; }
- iterator end() { return End; }
- const_iterator end() const { return End; }
-
- // reverse iterator creation methods.
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
-
- bool empty() const { return Begin == End; }
- size_type size() const { return End-Begin; }
-
- reference operator[](unsigned idx) {
- assert(Begin + idx < End);
- return Begin[idx];
- }
- const_reference operator[](unsigned idx) const {
- assert(Begin + idx < End);
- return Begin[idx];
- }
-
- reference front() {
- return begin()[0];
- }
- const_reference front() const {
- return begin()[0];
- }
-
- reference back() {
- return end()[-1];
- }
- const_reference back() const {
- return end()[-1];
- }
-
- void pop_back() {
- --End;
- End->~T();
- }
-
- T pop_back_val() {
- T Result = back();
- pop_back();
- return Result;
- }
-
- void clear() {
- if (std::is_class<T>::value) {
- destroy_range(Begin, End);
- }
- End = Begin;
- }
-
- /// data - Return a pointer to the vector's buffer, even if empty().
- pointer data() {
- return pointer(Begin);
- }
-
- /// data - Return a pointer to the vector's buffer, even if empty().
- const_pointer data() const {
- return const_pointer(Begin);
- }
-
- void push_back(const_reference Elt, const ASTContext &C) {
- if (End < this->capacity_ptr()) {
- Retry:
- new (End) T(Elt);
- ++End;
- return;
- }
- grow(C);
- goto Retry;
- }
-
- void reserve(const ASTContext &C, unsigned N) {
- if (unsigned(this->capacity_ptr()-Begin) < N)
- grow(C, N);
- }
-
- /// capacity - Return the total number of elements in the currently allocated
- /// buffer.
- size_t capacity() const { return this->capacity_ptr() - Begin; }
-
- /// append - Add the specified range to the end of the SmallVector.
- ///
- template<typename in_iter>
- void append(const ASTContext &C, in_iter in_start, in_iter in_end) {
- size_type NumInputs = std::distance(in_start, in_end);
-
- if (NumInputs == 0)
- return;
-
- // Grow allocated space if needed.
- if (NumInputs > size_type(this->capacity_ptr()-this->end()))
- this->grow(C, this->size()+NumInputs);
-
- // Copy the new elements over.
- // TODO: NEED To compile time dispatch on whether in_iter is a random access
- // iterator to use the fast uninitialized_copy.
- std::uninitialized_copy(in_start, in_end, this->end());
- this->setEnd(this->end() + NumInputs);
- }
-
- /// append - Add the specified range to the end of the SmallVector.
- ///
- void append(const ASTContext &C, size_type NumInputs, const T &Elt) {
- // Grow allocated space if needed.
- if (NumInputs > size_type(this->capacity_ptr()-this->end()))
- this->grow(C, this->size()+NumInputs);
-
- // Copy the new elements over.
- std::uninitialized_fill_n(this->end(), NumInputs, Elt);
- this->setEnd(this->end() + NumInputs);
- }
-
- /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
- /// starting with "Dest", constructing elements into it as needed.
- template<typename It1, typename It2>
- static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
- std::uninitialized_copy(I, E, Dest);
- }
-
- iterator insert(const ASTContext &C, iterator I, const T &Elt) {
- if (I == this->end()) { // Important special case for empty vector.
- push_back(Elt, C);
- return this->end()-1;
- }
-
- if (this->End < this->capacity_ptr()) {
- Retry:
- new (this->end()) T(this->back());
- this->setEnd(this->end()+1);
- // Push everything else over.
- std::copy_backward(I, this->end()-1, this->end());
- *I = Elt;
- return I;
- }
- size_t EltNo = I-this->begin();
- this->grow(C);
- I = this->begin()+EltNo;
- goto Retry;
- }
-
- iterator insert(const ASTContext &C, iterator I, size_type NumToInsert,
- const T &Elt) {
- // Convert iterator to elt# to avoid invalidating iterator when we reserve()
- size_t InsertElt = I - this->begin();
-
- if (I == this->end()) { // Important special case for empty vector.
- append(C, NumToInsert, Elt);
- return this->begin() + InsertElt;
- }
-
- // Ensure there is enough space.
- reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
-
- // Uninvalidate the iterator.
- I = this->begin()+InsertElt;
-
- // If there are more elements between the insertion point and the end of the
- // range than there are being inserted, we can use a simple approach to
- // insertion. Since we already reserved space, we know that this won't
- // reallocate the vector.
- if (size_t(this->end()-I) >= NumToInsert) {
- T *OldEnd = this->end();
- append(C, this->end()-NumToInsert, this->end());
-
- // Copy the existing elements that get replaced.
- std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
-
- std::fill_n(I, NumToInsert, Elt);
- return I;
- }
-
- // Otherwise, we're inserting more elements than exist already, and we're
- // not inserting at the end.
-
- // Copy over the elements that we're about to overwrite.
- T *OldEnd = this->end();
- this->setEnd(this->end() + NumToInsert);
- size_t NumOverwritten = OldEnd-I;
- this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
-
- // Replace the overwritten part.
- std::fill_n(I, NumOverwritten, Elt);
-
- // Insert the non-overwritten middle part.
- std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
- return I;
- }
-
- template<typename ItTy>
- iterator insert(const ASTContext &C, iterator I, ItTy From, ItTy To) {
- // Convert iterator to elt# to avoid invalidating iterator when we reserve()
- size_t InsertElt = I - this->begin();
-
- if (I == this->end()) { // Important special case for empty vector.
- append(C, From, To);
- return this->begin() + InsertElt;
- }
-
- size_t NumToInsert = std::distance(From, To);
-
- // Ensure there is enough space.
- reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
-
- // Uninvalidate the iterator.
- I = this->begin()+InsertElt;
-
- // If there are more elements between the insertion point and the end of the
- // range than there are being inserted, we can use a simple approach to
- // insertion. Since we already reserved space, we know that this won't
- // reallocate the vector.
- if (size_t(this->end()-I) >= NumToInsert) {
- T *OldEnd = this->end();
- append(C, this->end()-NumToInsert, this->end());
-
- // Copy the existing elements that get replaced.
- std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
-
- std::copy(From, To, I);
- return I;
- }
-
- // Otherwise, we're inserting more elements than exist already, and we're
- // not inserting at the end.
-
- // Copy over the elements that we're about to overwrite.
- T *OldEnd = this->end();
- this->setEnd(this->end() + NumToInsert);
- size_t NumOverwritten = OldEnd-I;
- this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
-
- // Replace the overwritten part.
- for (; NumOverwritten > 0; --NumOverwritten) {
- *I = *From;
- ++I; ++From;
- }
-
- // Insert the non-overwritten middle part.
- this->uninitialized_copy(From, To, OldEnd);
- return I;
- }
-
- void resize(const ASTContext &C, unsigned N, const T &NV) {
- if (N < this->size()) {
- this->destroy_range(this->begin()+N, this->end());
- this->setEnd(this->begin()+N);
- } else if (N > this->size()) {
- if (this->capacity() < N)
- this->grow(C, N);
- construct_range(this->end(), this->begin()+N, NV);
- this->setEnd(this->begin()+N);
- }
- }
-
-private:
- /// grow - double the size of the allocated memory, guaranteeing space for at
- /// least one more element or MinSize if specified.
- void grow(const ASTContext &C, size_type MinSize = 1);
-
- void construct_range(T *S, T *E, const T &Elt) {
- for (; S != E; ++S)
- new (S) T(Elt);
- }
-
- void destroy_range(T *S, T *E) {
- while (S != E) {
- --E;
- E->~T();
- }
- }
-
-protected:
- const_iterator capacity_ptr() const {
- return (iterator) Capacity.getPointer();
- }
- iterator capacity_ptr() { return (iterator)Capacity.getPointer(); }
-};
-
-// Define this out-of-line to dissuade the C++ compiler from inlining it.
-template <typename T>
-void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
- size_t CurCapacity = this->capacity();
- size_t CurSize = size();
- size_t NewCapacity = 2*CurCapacity;
- if (NewCapacity < MinSize)
- NewCapacity = MinSize;
-
- // Allocate the memory from the ASTContext.
- T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
-
- // Copy the elements over.
- if (Begin != End) {
- if (std::is_class<T>::value) {
- std::uninitialized_copy(Begin, End, NewElts);
- // Destroy the original elements.
- destroy_range(Begin, End);
- } else {
- // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
- memcpy(NewElts, Begin, CurSize * sizeof(T));
- }
- }
-
- // ASTContext never frees any memory.
- Begin = NewElts;
- End = NewElts+CurSize;
- Capacity.setPointer(Begin+NewCapacity);
-}
-
-} // end: clang namespace
-#endif
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
deleted file mode 100644
index 8b80e9f..0000000
--- a/include/clang/AST/Attr.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Attr interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ATTR_H
-#define LLVM_CLANG_AST_ATTR_H
-
-#include "clang/AST/AttrIterator.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/AttrKinds.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Sanitizers.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/VersionTuple.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-
-namespace clang {
- class ASTContext;
- class IdentifierInfo;
- class ObjCInterfaceDecl;
- class Expr;
- class QualType;
- class FunctionDecl;
- 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;
- bool Inherited : 1;
- bool IsPackExpansion : 1;
- bool Implicit : 1;
- bool IsLateParsed : 1;
- bool DuplicatesAllowed : 1;
-
- void *operator new(size_t bytes) LLVM_NOEXCEPT {
- llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
- }
- void operator delete(void *data) LLVM_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) LLVM_NOEXCEPT {
- return ::operator new(Bytes, C, Alignment);
- }
- void operator delete(void *Ptr, ASTContext &C,
- size_t Alignment) LLVM_NOEXCEPT {
- return ::operator delete(Ptr, C, Alignment);
- }
-
-protected:
- Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
- : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
- Inherited(false), IsPackExpansion(false), Implicit(false),
- IsLateParsed(IsLateParsed), DuplicatesAllowed(DuplicatesAllowed) {}
-
-public:
-
- attr::Kind getKind() const {
- return static_cast<attr::Kind>(AttrKind);
- }
-
- unsigned getSpellingListIndex() const { return SpellingListIndex; }
- const char *getSpelling() const;
-
- SourceLocation getLocation() const { return Range.getBegin(); }
- SourceRange getRange() const { return Range; }
- void setRange(SourceRange R) { Range = R; }
-
- bool isInherited() const { return Inherited; }
-
- /// \brief 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; }
-
- // Clone this attribute.
- Attr *clone(ASTContext &C) const;
-
- bool isLateParsed() const { return IsLateParsed; }
-
- // Pretty print this attribute.
- void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
-
- /// \brief By default, attributes cannot be duplicated when being merged;
- /// however, an attribute can override this. Returns true if the attribute
- /// can be duplicated when merging.
- bool duplicatesAllowed() const { return DuplicatesAllowed; }
-};
-
-class InheritableAttr : public Attr {
-protected:
- InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
- : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
-
-public:
- void setInherited(bool I) { Inherited = I; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() <= attr::LAST_INHERITABLE;
- }
-};
-
-class InheritableParamAttr : public InheritableAttr {
-protected:
- InheritableParamAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
- bool IsLateParsed, bool DuplicatesAllowed)
- : InheritableAttr(AK, R, SpellingListIndex, IsLateParsed,
- DuplicatesAllowed) {}
-
-public:
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- // Relies on relative order of enum emission with respect to MS inheritance
- // attrs.
- return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
- }
-};
-
-#include "clang/AST/Attrs.inc"
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const Attr *At) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
- DiagnosticsEngine::ak_attr);
- return DB;
-}
-
-inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const Attr *At) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
- DiagnosticsEngine::ak_attr);
- return PD;
-}
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
deleted file mode 100644
index a0c8030..0000000
--- a/include/clang/AST/AttrIterator.h
+++ /dev/null
@@ -1,142 +0,0 @@
-//===--- AttrIterator.h - Classes for attribute iteration -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Attr vector and specific_attr_iterator interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_ATTRITERATOR_H
-#define LLVM_CLANG_AST_ATTRITERATOR_H
-
-#include "clang/Basic/LLVM.h"
-#include <iterator>
-
-namespace clang {
- class ASTContext;
- class Attr;
-}
-
-// Defined in ASTContext.h
-void *operator new(size_t Bytes, const clang::ASTContext &C,
- size_t Alignment = 8);
-// FIXME: Being forced to not have a default argument here due to redeclaration
-// rules on default arguments sucks
-void *operator new[](size_t Bytes, const clang::ASTContext &C,
- size_t Alignment);
-
-// It is good practice to pair new/delete operators. Also, MSVC gives many
-// warnings if a matching delete overload is not declared, even though the
-// throw() spec guarantees it will not be implicitly called.
-void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
-void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
-
-namespace clang {
-
-/// AttrVec - A vector of Attr, which is how they are stored on the AST.
-typedef SmallVector<Attr*, 2> AttrVec;
-typedef SmallVector<const Attr*, 2> ConstAttrVec;
-
-/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
-/// providing attributes that are of a specific type.
-template <typename SpecificAttr, typename Container = AttrVec>
-class specific_attr_iterator {
- typedef typename Container::const_iterator Iterator;
-
- /// Current - The current, underlying iterator.
- /// In order to ensure we don't dereference an invalid iterator unless
- /// specifically requested, we don't necessarily advance this all the
- /// way. Instead, we advance it when an operation is requested; if the
- /// operation is acting on what should be a past-the-end iterator,
- /// then we offer no guarantees, but this way we do not dereference a
- /// past-the-end iterator when we move to a past-the-end position.
- mutable Iterator Current;
-
- void AdvanceToNext() const {
- while (!isa<SpecificAttr>(*Current))
- ++Current;
- }
-
- void AdvanceToNext(Iterator I) const {
- while (Current != I && !isa<SpecificAttr>(*Current))
- ++Current;
- }
-
-public:
- typedef SpecificAttr* value_type;
- typedef SpecificAttr* reference;
- typedef SpecificAttr* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- specific_attr_iterator() : Current() { }
- explicit specific_attr_iterator(Iterator i) : Current(i) { }
-
- reference operator*() const {
- AdvanceToNext();
- return cast<SpecificAttr>(*Current);
- }
- pointer operator->() const {
- AdvanceToNext();
- return cast<SpecificAttr>(*Current);
- }
-
- specific_attr_iterator& operator++() {
- ++Current;
- return *this;
- }
- specific_attr_iterator operator++(int) {
- specific_attr_iterator Tmp(*this);
- ++(*this);
- return Tmp;
- }
-
- friend bool operator==(specific_attr_iterator Left,
- specific_attr_iterator Right) {
- assert((Left.Current == nullptr) == (Right.Current == nullptr));
- if (Left.Current < Right.Current)
- Left.AdvanceToNext(Right.Current);
- else
- Right.AdvanceToNext(Left.Current);
- return Left.Current == Right.Current;
- }
- friend bool operator!=(specific_attr_iterator Left,
- specific_attr_iterator Right) {
- return !(Left == Right);
- }
-};
-
-template <typename SpecificAttr, typename Container>
-inline specific_attr_iterator<SpecificAttr, Container>
- specific_attr_begin(const Container& container) {
- return specific_attr_iterator<SpecificAttr, Container>(container.begin());
-}
-template <typename SpecificAttr, typename Container>
-inline specific_attr_iterator<SpecificAttr, Container>
- specific_attr_end(const Container& container) {
- return specific_attr_iterator<SpecificAttr, Container>(container.end());
-}
-
-template <typename SpecificAttr, typename Container>
-inline bool hasSpecificAttr(const Container& container) {
- return specific_attr_begin<SpecificAttr>(container) !=
- specific_attr_end<SpecificAttr>(container);
-}
-template <typename SpecificAttr, typename Container>
-inline SpecificAttr *getSpecificAttr(const Container& container) {
- specific_attr_iterator<SpecificAttr, Container> i =
- specific_attr_begin<SpecificAttr>(container);
- if (i != specific_attr_end<SpecificAttr>(container))
- return *i;
- else
- return nullptr;
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h
deleted file mode 100644
index da538e3..0000000
--- a/include/clang/AST/BaseSubobject.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===--- BaseSubobject.h - BaseSubobject class ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides a definition of the BaseSubobject class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_BASESUBOBJECT_H
-#define LLVM_CLANG_AST_BASESUBOBJECT_H
-
-#include "clang/AST/CharUnits.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/type_traits.h"
-
-namespace clang {
- class CXXRecordDecl;
-
-// BaseSubobject - Uniquely identifies a direct or indirect base class.
-// Stores both the base class decl and the offset from the most derived class to
-// the base class. Used for vtable and VTT generation.
-class BaseSubobject {
- /// Base - The base class declaration.
- const CXXRecordDecl *Base;
-
- /// BaseOffset - The offset from the most derived class to the base class.
- CharUnits BaseOffset;
-
-public:
- BaseSubobject() { }
- BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
- : Base(Base), BaseOffset(BaseOffset) { }
-
- /// getBase - Returns the base class declaration.
- const CXXRecordDecl *getBase() const { return Base; }
-
- /// getBaseOffset - Returns the base class offset.
- CharUnits getBaseOffset() const { return BaseOffset; }
-
- friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
- return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
- }
-};
-
-} // end namespace clang
-
-namespace llvm {
-
-template<> struct DenseMapInfo<clang::BaseSubobject> {
- static clang::BaseSubobject getEmptyKey() {
- return clang::BaseSubobject(
- DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
- clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey()));
- }
-
- static clang::BaseSubobject getTombstoneKey() {
- return clang::BaseSubobject(
- DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
- clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey()));
- }
-
- static unsigned getHashValue(const clang::BaseSubobject &Base) {
- typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy;
- return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
- Base.getBaseOffset()));
- }
-
- static bool isEqual(const clang::BaseSubobject &LHS,
- const clang::BaseSubobject &RHS) {
- return LHS == RHS;
- }
-};
-
-// It's OK to treat BaseSubobject as a POD type.
-template <> struct isPodLike<clang::BaseSubobject> {
- static const bool value = true;
-};
-
-}
-
-#endif
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
deleted file mode 100644
index 85e237a..0000000
--- a/include/clang/AST/BuiltinTypes.def
+++ /dev/null
@@ -1,261 +0,0 @@
-//===-- BuiltinTypeNodes.def - Metadata about BuiltinTypes ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the database about various builtin singleton types.
-//
-// BuiltinType::Id is the enumerator defining the type.
-//
-// Context.SingletonId is the global singleton of this type. Some global
-// singletons are shared by multiple types.
-//
-// BUILTIN_TYPE(Id, SingletonId) - A builtin type that has not been
-// covered by any other #define. Defining this macro covers all
-// the builtins.
-//
-// SIGNED_TYPE(Id, SingletonId) - A signed integral type.
-//
-// UNSIGNED_TYPE(Id, SingletonId) - An unsigned integral type.
-//
-// FLOATING_TYPE(Id, SingletonId) - A floating-point type.
-//
-// PLACEHOLDER_TYPE(Id, SingletonId) - A placeholder type. Placeholder
-// types are used to perform context-sensitive checking of specific
-// forms of expression.
-//
-// SHARED_SINGLETON_TYPE(Expansion) - The given expansion corresponds
-// to a builtin which uses a shared singleton type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SIGNED_TYPE
-#define SIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef UNSIGNED_TYPE
-#define UNSIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef FLOATING_TYPE
-#define FLOATING_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef PLACEHOLDER_TYPE
-#define PLACEHOLDER_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
-#endif
-
-#ifndef SHARED_SINGLETON_TYPE
-#define SHARED_SINGLETON_TYPE(Expansion) Expansion
-#endif
-
-//===- Builtin Types ------------------------------------------------------===//
-
-// void
-BUILTIN_TYPE(Void, VoidTy)
-
-//===- Unsigned Types -----------------------------------------------------===//
-
-// 'bool' in C++, '_Bool' in C99
-UNSIGNED_TYPE(Bool, BoolTy)
-
-// 'char' for targets where it's unsigned
-SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(Char_U, CharTy))
-
-// 'unsigned char', explicitly qualified
-UNSIGNED_TYPE(UChar, UnsignedCharTy)
-
-// 'wchar_t' for targets where it's unsigned
-SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy))
-
-// 'char16_t' in C++
-UNSIGNED_TYPE(Char16, Char16Ty)
-
-// 'char32_t' in C++
-UNSIGNED_TYPE(Char32, Char32Ty)
-
-// 'unsigned short'
-UNSIGNED_TYPE(UShort, UnsignedShortTy)
-
-// 'unsigned int'
-UNSIGNED_TYPE(UInt, UnsignedIntTy)
-
-// 'unsigned long'
-UNSIGNED_TYPE(ULong, UnsignedLongTy)
-
-// 'unsigned long long'
-UNSIGNED_TYPE(ULongLong, UnsignedLongLongTy)
-
-// '__uint128_t'
-UNSIGNED_TYPE(UInt128, UnsignedInt128Ty)
-
-//===- Signed Types -------------------------------------------------------===//
-
-// 'char' for targets where it's signed
-SHARED_SINGLETON_TYPE(SIGNED_TYPE(Char_S, CharTy))
-
-// 'signed char', explicitly qualified
-SIGNED_TYPE(SChar, SignedCharTy)
-
-// 'wchar_t' for targets where it's signed
-SHARED_SINGLETON_TYPE(SIGNED_TYPE(WChar_S, WCharTy))
-
-// 'short' or 'signed short'
-SIGNED_TYPE(Short, ShortTy)
-
-// 'int' or 'signed int'
-SIGNED_TYPE(Int, IntTy)
-
-// 'long' or 'signed long'
-SIGNED_TYPE(Long, LongTy)
-
-// 'long long' or 'signed long long'
-SIGNED_TYPE(LongLong, LongLongTy)
-
-// '__int128_t'
-SIGNED_TYPE(Int128, Int128Ty)
-
-//===- Floating point types -----------------------------------------------===//
-
-// 'half' in OpenCL, '__fp16' in ARM NEON.
-FLOATING_TYPE(Half, HalfTy)
-
-// 'float'
-FLOATING_TYPE(Float, FloatTy)
-
-// 'double'
-FLOATING_TYPE(Double, DoubleTy)
-
-// 'long double'
-FLOATING_TYPE(LongDouble, LongDoubleTy)
-
-//===- Language-specific types --------------------------------------------===//
-
-// This is the type of C++0x 'nullptr'.
-BUILTIN_TYPE(NullPtr, NullPtrTy)
-
-// The primitive Objective C 'id' type. The user-visible 'id'
-// type is a typedef of an ObjCObjectPointerType to an
-// ObjCObjectType with this as its base. In fact, this only ever
-// shows up in an AST as the base type of an ObjCObjectType.
-BUILTIN_TYPE(ObjCId, ObjCBuiltinIdTy)
-
-// The primitive Objective C 'Class' type. The user-visible
-// 'Class' type is a typedef of an ObjCObjectPointerType to an
-// ObjCObjectType with this as its base. In fact, this only ever
-// shows up in an AST as the base type of an ObjCObjectType.
-BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy)
-
-// The primitive Objective C 'SEL' type. The user-visible 'SEL'
-// type is a typedef of a PointerType to this.
-BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy)
-
-// OpenCL image types.
-BUILTIN_TYPE(OCLImage1d, OCLImage1dTy)
-BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy)
-BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy)
-BUILTIN_TYPE(OCLImage2d, OCLImage2dTy)
-BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy)
-BUILTIN_TYPE(OCLImage2dDepth, OCLImage2dDepthTy)
-BUILTIN_TYPE(OCLImage2dArrayDepth, OCLImage2dArrayDepthTy)
-BUILTIN_TYPE(OCLImage2dMSAA, OCLImage2dMSAATy)
-BUILTIN_TYPE(OCLImage2dArrayMSAA, OCLImage2dArrayMSAATy)
-BUILTIN_TYPE(OCLImage2dMSAADepth, OCLImage2dMSAADepthTy)
-BUILTIN_TYPE(OCLImage2dArrayMSAADepth, OCLImage2dArrayMSAADepthTy)
-BUILTIN_TYPE(OCLImage3d, OCLImage3dTy)
-
-// OpenCL sampler_t.
-BUILTIN_TYPE(OCLSampler, OCLSamplerTy)
-
-// OpenCL event_t.
-BUILTIN_TYPE(OCLEvent, OCLEventTy)
-
-// OpenCL clk_event_t.
-BUILTIN_TYPE(OCLClkEvent, OCLClkEventTy)
-
-// OpenCL queue_t.
-BUILTIN_TYPE(OCLQueue, OCLQueueTy)
-
-// OpenCL ndrange_t.
-BUILTIN_TYPE(OCLNDRange, OCLNDRangeTy)
-
-// OpenCL reserve_id_t.
-BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy)
-
-// This represents the type of an expression whose type is
-// totally unknown, e.g. 'T::foo'. It is permitted for this to
-// appear in situations where the structure of the type is
-// theoretically deducible.
-BUILTIN_TYPE(Dependent, DependentTy)
-
-// The type of an unresolved overload set. A placeholder type.
-// Expressions with this type have one of the following basic
-// forms, with parentheses generally permitted:
-// foo # possibly qualified, not if an implicit access
-// foo # possibly qualified, not if an implicit access
-// &foo # possibly qualified, not if an implicit access
-// x->foo # only if might be a static member function
-// &x->foo # only if might be a static member function
-// &Class::foo # when a pointer-to-member; sub-expr also has this type
-// OverloadExpr::find can be used to analyze the expression.
-//
-// Overload should be the first placeholder type, or else change
-// BuiltinType::isNonOverloadPlaceholderType()
-PLACEHOLDER_TYPE(Overload, OverloadTy)
-
-// The type of a bound C++ non-static member function.
-// A placeholder type. Expressions with this type have one of the
-// following basic forms:
-// foo # if an implicit access
-// x->foo # if only contains non-static members
-PLACEHOLDER_TYPE(BoundMember, BoundMemberTy)
-
-// The type of an expression which refers to a pseudo-object,
-// such as those introduced by Objective C's @property or
-// VS.NET's __property declarations. A placeholder type. The
-// pseudo-object is actually accessed by emitting a call to
-// some sort of function or method; typically there is a pair
-// of a setter and a getter, with the setter used if the
-// pseudo-object reference is used syntactically as the
-// left-hand-side of an assignment operator.
-//
-// A pseudo-object reference naming an Objective-C @property is
-// always a dot access with a base of object-pointer type,
-// e.g. 'x.foo'.
-//
-// In VS.NET, a __property declaration creates an implicit
-// member with an associated name, which can then be named
-// in any of the normal ways an ordinary member could be.
-PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy)
-
-// __builtin_any_type. A placeholder type. Useful for clients
-// like debuggers that don't know what type to give something.
-// Only a small number of operations are valid on expressions of
-// unknown type, most notably explicit casts.
-PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy)
-
-PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy)
-
-// The type of a cast which, in ARC, would normally require a
-// __bridge, but which might be okay depending on the immediate
-// context.
-PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
-
-// A placeholder type for OpenMP array sections.
-PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy)
-
-#ifdef LAST_BUILTIN_TYPE
-LAST_BUILTIN_TYPE(OMPArraySection)
-#undef LAST_BUILTIN_TYPE
-#endif
-
-#undef SHARED_SINGLETON_TYPE
-#undef PLACEHOLDER_TYPE
-#undef FLOATING_TYPE
-#undef SIGNED_TYPE
-#undef UNSIGNED_TYPE
-#undef BUILTIN_TYPE
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
deleted file mode 100644
index 260734f..0000000
--- a/include/clang/AST/CMakeLists.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-clang_tablegen(Attrs.inc -gen-clang-attr-classes
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrClasses)
-
-clang_tablegen(AttrImpl.inc -gen-clang-attr-impl
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrImpl)
-
-clang_tablegen(AttrDump.inc -gen-clang-attr-dump
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrDump)
-
-clang_tablegen(AttrVisitor.inc -gen-clang-attr-ast-visitor
- -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
- SOURCE ../Basic/Attr.td
- TARGET ClangAttrVisitor)
-
-clang_tablegen(StmtNodes.inc -gen-clang-stmt-nodes
- SOURCE ../Basic/StmtNodes.td
- TARGET ClangStmtNodes)
-
-clang_tablegen(DeclNodes.inc -gen-clang-decl-nodes
- SOURCE ../Basic/DeclNodes.td
- TARGET ClangDeclNodes)
-
-clang_tablegen(CommentNodes.inc -gen-clang-comment-nodes
- SOURCE ../Basic/CommentNodes.td
- TARGET ClangCommentNodes)
-
-clang_tablegen(CommentHTMLTags.inc -gen-clang-comment-html-tags
- SOURCE CommentHTMLTags.td
- TARGET ClangCommentHTMLTags)
-
-clang_tablegen(CommentHTMLTagsProperties.inc -gen-clang-comment-html-tags-properties
- SOURCE CommentHTMLTags.td
- TARGET ClangCommentHTMLTagsProperties)
-
-clang_tablegen(CommentHTMLNamedCharacterReferences.inc -gen-clang-comment-html-named-character-references
- SOURCE CommentHTMLNamedCharacterReferences.td
- TARGET ClangCommentHTMLNamedCharacterReferences)
-
-clang_tablegen(CommentCommandInfo.inc -gen-clang-comment-command-info
- SOURCE CommentCommands.td
- TARGET ClangCommentCommandInfo)
-
-clang_tablegen(CommentCommandList.inc -gen-clang-comment-command-list
- SOURCE CommentCommands.td
- TARGET ClangCommentCommandList)
-
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
deleted file mode 100644
index 8587260..0000000
--- a/include/clang/AST/CXXInheritance.h
+++ /dev/null
@@ -1,365 +0,0 @@
-//===------ CXXInheritance.h - C++ Inheritance ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides routines that help analyzing C++ inheritance hierarchies.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_CXXINHERITANCE_H
-#define LLVM_CLANG_AST_CXXINHERITANCE_H
-
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TypeOrdering.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cassert>
-#include <list>
-#include <map>
-
-namespace clang {
-
-class CXXBaseSpecifier;
-class CXXMethodDecl;
-class CXXRecordDecl;
-class NamedDecl;
-
-/// \brief Represents an element in a path from a derived class to a
-/// base class.
-///
-/// Each step in the path references the link from a
-/// derived class to one of its direct base classes, along with a
-/// base "number" that identifies which base subobject of the
-/// original derived class we are referencing.
-struct CXXBasePathElement {
- /// \brief The base specifier that states the link from a derived
- /// class to a base class, which will be followed by this base
- /// path element.
- const CXXBaseSpecifier *Base;
-
- /// \brief The record decl of the class that the base is a base of.
- const CXXRecordDecl *Class;
-
- /// \brief Identifies which base class subobject (of type
- /// \c Base->getType()) this base path element refers to.
- ///
- /// This value is only valid if \c !Base->isVirtual(), because there
- /// is no base numbering for the zero or one virtual bases of a
- /// given type.
- int SubobjectNumber;
-};
-
-/// \brief Represents a path from a specific derived class
-/// (which is not represented as part of the path) to a particular
-/// (direct or indirect) base class subobject.
-///
-/// Individual elements in the path are described by the \c CXXBasePathElement
-/// structure, which captures both the link from a derived class to one of its
-/// direct bases and identification describing which base class
-/// subobject is being used.
-class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
-public:
- CXXBasePath() : Access(AS_public) {}
-
- /// \brief The access along this inheritance path. This is only
- /// calculated when recording paths. AS_none is a special value
- /// used to indicate a path which permits no legal access.
- AccessSpecifier Access;
-
- /// \brief The set of declarations found inside this base class
- /// subobject.
- DeclContext::lookup_result Decls;
-
- void clear() {
- SmallVectorImpl<CXXBasePathElement>::clear();
- Access = AS_public;
- }
-};
-
-/// BasePaths - Represents the set of paths from a derived class to
-/// one of its (direct or indirect) bases. For example, given the
-/// following class hierarchy:
-///
-/// @code
-/// class A { };
-/// class B : public A { };
-/// class C : public A { };
-/// class D : public B, public C{ };
-/// @endcode
-///
-/// There are two potential BasePaths to represent paths from D to a
-/// base subobject of type A. One path is (D,0) -> (B,0) -> (A,0)
-/// and another is (D,0)->(C,0)->(A,1). These two paths actually
-/// refer to two different base class subobjects of the same type,
-/// so the BasePaths object refers to an ambiguous path. On the
-/// other hand, consider the following class hierarchy:
-///
-/// @code
-/// class A { };
-/// class B : public virtual A { };
-/// class C : public virtual A { };
-/// class D : public B, public C{ };
-/// @endcode
-///
-/// Here, there are two potential BasePaths again, (D, 0) -> (B, 0)
-/// -> (A,v) and (D, 0) -> (C, 0) -> (A, v), but since both of them
-/// refer to the same base class subobject of type A (the virtual
-/// one), there is no ambiguity.
-class CXXBasePaths {
- /// \brief The type from which this search originated.
- CXXRecordDecl *Origin;
-
- /// Paths - The actual set of paths that can be taken from the
- /// derived class to the same base class.
- std::list<CXXBasePath> Paths;
-
- /// ClassSubobjects - Records the class subobjects for each class
- /// type that we've seen. The first element in the pair says
- /// whether we found a path to a virtual base for that class type,
- /// while the element contains the number of non-virtual base
- /// class subobjects for that class type. The key of the map is
- /// the cv-unqualified canonical type of the base class subobject.
- llvm::SmallDenseMap<QualType, std::pair<bool, unsigned>, 8> ClassSubobjects;
-
- /// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
- /// ambiguous paths while it is looking for a path from a derived
- /// type to a base type.
- bool FindAmbiguities;
-
- /// RecordPaths - Whether Sema::IsDerivedFrom should record paths
- /// while it is determining whether there are paths from a derived
- /// type to a base type.
- bool RecordPaths;
-
- /// DetectVirtual - Whether Sema::IsDerivedFrom should abort the search
- /// if it finds a path that goes across a virtual base. The virtual class
- /// is also recorded.
- bool DetectVirtual;
-
- /// ScratchPath - A BasePath that is used by Sema::lookupInBases
- /// to help build the set of paths.
- CXXBasePath ScratchPath;
-
- /// DetectedVirtual - The base class that is virtual.
- const RecordType *DetectedVirtual;
-
- /// \brief Array of the declarations that have been found. This
- /// array is constructed only if needed, e.g., to iterate over the
- /// results within LookupResult.
- std::unique_ptr<NamedDecl *[]> DeclsFound;
- unsigned NumDeclsFound;
-
- friend class CXXRecordDecl;
-
- void ComputeDeclsFound();
-
- bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
- CXXRecordDecl::BaseMatchesCallback BaseMatches);
-
-public:
- typedef std::list<CXXBasePath>::iterator paths_iterator;
- typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
- typedef NamedDecl **decl_iterator;
-
- /// BasePaths - Construct a new BasePaths structure to record the
- /// paths for a derived-to-base search.
- explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
- bool DetectVirtual = true)
- : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
- DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
- NumDeclsFound(0) {}
-
- paths_iterator begin() { return Paths.begin(); }
- paths_iterator end() { return Paths.end(); }
- const_paths_iterator begin() const { return Paths.begin(); }
- const_paths_iterator end() const { return Paths.end(); }
-
- CXXBasePath& front() { return Paths.front(); }
- const CXXBasePath& front() const { return Paths.front(); }
-
- typedef llvm::iterator_range<decl_iterator> decl_range;
- decl_range found_decls();
-
- /// \brief Determine whether the path from the most-derived type to the
- /// given base type is ambiguous (i.e., it refers to multiple subobjects of
- /// the same base type).
- bool isAmbiguous(CanQualType BaseType);
-
- /// \brief Whether we are finding multiple paths to detect ambiguities.
- bool isFindingAmbiguities() const { return FindAmbiguities; }
-
- /// \brief Whether we are recording paths.
- bool isRecordingPaths() const { return RecordPaths; }
-
- /// \brief Specify whether we should be recording paths or not.
- void setRecordingPaths(bool RP) { RecordPaths = RP; }
-
- /// \brief Whether we are detecting virtual bases.
- bool isDetectingVirtual() const { return DetectVirtual; }
-
- /// \brief The virtual base discovered on the path (if we are merely
- /// detecting virtuals).
- const RecordType* getDetectedVirtual() const {
- return DetectedVirtual;
- }
-
- /// \brief Retrieve the type from which this base-paths search
- /// began
- CXXRecordDecl *getOrigin() const { return Origin; }
- void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; }
-
- /// \brief Clear the base-paths results.
- void clear();
-
- /// \brief Swap this data structure's contents with another CXXBasePaths
- /// object.
- void swap(CXXBasePaths &Other);
-};
-
-/// \brief Uniquely identifies a virtual method within a class
-/// hierarchy by the method itself and a class subobject number.
-struct UniqueVirtualMethod {
- UniqueVirtualMethod()
- : Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { }
-
- UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
- const CXXRecordDecl *InVirtualSubobject)
- : Method(Method), Subobject(Subobject),
- InVirtualSubobject(InVirtualSubobject) { }
-
- /// \brief The overriding virtual method.
- CXXMethodDecl *Method;
-
- /// \brief The subobject in which the overriding virtual method
- /// resides.
- unsigned Subobject;
-
- /// \brief The virtual base class subobject of which this overridden
- /// virtual method is a part. Note that this records the closest
- /// derived virtual base class subobject.
- const CXXRecordDecl *InVirtualSubobject;
-
- friend bool operator==(const UniqueVirtualMethod &X,
- const UniqueVirtualMethod &Y) {
- return X.Method == Y.Method && X.Subobject == Y.Subobject &&
- X.InVirtualSubobject == Y.InVirtualSubobject;
- }
-
- friend bool operator!=(const UniqueVirtualMethod &X,
- const UniqueVirtualMethod &Y) {
- return !(X == Y);
- }
-};
-
-/// \brief The set of methods that override a given virtual method in
-/// each subobject where it occurs.
-///
-/// The first part of the pair is the subobject in which the
-/// overridden virtual function occurs, while the second part of the
-/// pair is the virtual method that overrides it (including the
-/// subobject in which that virtual function occurs).
-class OverridingMethods {
- typedef SmallVector<UniqueVirtualMethod, 4> ValuesT;
- typedef llvm::MapVector<unsigned, ValuesT> MapType;
- MapType Overrides;
-
-public:
- // Iterate over the set of subobjects that have overriding methods.
- typedef MapType::iterator iterator;
- typedef MapType::const_iterator const_iterator;
- iterator begin() { return Overrides.begin(); }
- const_iterator begin() const { return Overrides.begin(); }
- iterator end() { return Overrides.end(); }
- const_iterator end() const { return Overrides.end(); }
- unsigned size() const { return Overrides.size(); }
-
- // Iterate over the set of overriding virtual methods in a given
- // subobject.
- typedef SmallVectorImpl<UniqueVirtualMethod>::iterator
- overriding_iterator;
- typedef SmallVectorImpl<UniqueVirtualMethod>::const_iterator
- overriding_const_iterator;
-
- // Add a new overriding method for a particular subobject.
- void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
-
- // Add all of the overriding methods from "other" into overrides for
- // this method. Used when merging the overrides from multiple base
- // class subobjects.
- void add(const OverridingMethods &Other);
-
- // Replace all overriding virtual methods in all subobjects with the
- // given virtual method.
- void replaceAll(UniqueVirtualMethod Overriding);
-};
-
-/// \brief A mapping from each virtual member function to its set of
-/// final overriders.
-///
-/// Within a class hierarchy for a given derived class, each virtual
-/// member function in that hierarchy has one or more "final
-/// overriders" (C++ [class.virtual]p2). A final overrider for a
-/// virtual function "f" is the virtual function that will actually be
-/// invoked when dispatching a call to "f" through the
-/// vtable. Well-formed classes have a single final overrider for each
-/// virtual function; in abstract classes, the final overrider for at
-/// least one virtual function is a pure virtual function. Due to
-/// multiple, virtual inheritance, it is possible for a class to have
-/// more than one final overrider. Athough this is an error (per C++
-/// [class.virtual]p2), it is not considered an error here: the final
-/// overrider map can represent multiple final overriders for a
-/// method, and it is up to the client to determine whether they are
-/// problem. For example, the following class \c D has two final
-/// overriders for the virtual function \c A::f(), one in \c C and one
-/// in \c D:
-///
-/// \code
-/// struct A { virtual void f(); };
-/// struct B : virtual A { virtual void f(); };
-/// struct C : virtual A { virtual void f(); };
-/// struct D : B, C { };
-/// \endcode
-///
-/// This data structure contains a mapping from every virtual
-/// function *that does not override an existing virtual function* and
-/// in every subobject where that virtual function occurs to the set
-/// of virtual functions that override it. Thus, the same virtual
-/// function \c A::f can actually occur in multiple subobjects of type
-/// \c A due to multiple inheritance, and may be overridden by
-/// different virtual functions in each, as in the following example:
-///
-/// \code
-/// struct A { virtual void f(); };
-/// struct B : A { virtual void f(); };
-/// struct C : A { virtual void f(); };
-/// struct D : B, C { };
-/// \endcode
-///
-/// Unlike in the previous example, where the virtual functions \c
-/// B::f and \c C::f both overrode \c A::f in the same subobject of
-/// type \c A, in this example the two virtual functions both override
-/// \c A::f but in *different* subobjects of type A. This is
-/// represented by numbering the subobjects in which the overridden
-/// and the overriding virtual member functions are located. Subobject
-/// 0 represents the virtual base class subobject of that type, while
-/// subobject numbers greater than 0 refer to non-virtual base class
-/// subobjects of that type.
-class CXXFinalOverriderMap
- : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { };
-
-/// \brief A set of all the primary bases for a class.
-class CXXIndirectPrimaryBaseSet
- : public llvm::SmallSet<const CXXRecordDecl*, 32> { };
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
deleted file mode 100644
index b25800b..0000000
--- a/include/clang/AST/CanonicalType.h
+++ /dev/null
@@ -1,665 +0,0 @@
-//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CanQual class template, which provides access to
-// canonical types.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_CANONICALTYPE_H
-#define LLVM_CLANG_AST_CANONICALTYPE_H
-
-#include "clang/AST/Type.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/Support/Casting.h"
-
-namespace clang {
-
-template<typename T> class CanProxy;
-template<typename T> struct CanProxyAdaptor;
-
-//----------------------------------------------------------------------------//
-// Canonical, qualified type template
-//----------------------------------------------------------------------------//
-
-/// \brief Represents a canonical, potentially-qualified type.
-///
-/// The CanQual template is a lightweight smart pointer that provides access
-/// to the canonical representation of a type, where all typedefs and other
-/// syntactic sugar has been eliminated. A CanQualType may also have various
-/// qualifiers (const, volatile, restrict) attached to it.
-///
-/// The template type parameter @p T is one of the Type classes (PointerType,
-/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
-/// type (or some subclass of that type). The typedef @c CanQualType is just
-/// a shorthand for @c CanQual<Type>.
-///
-/// An instance of @c CanQual<T> can be implicitly converted to a
-/// @c CanQual<U> when T is derived from U, which essentially provides an
-/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
-/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
-/// be implicitly converted to a QualType, but the reverse operation requires
-/// a call to ASTContext::getCanonicalType().
-///
-///
-template<typename T = Type>
-class CanQual {
- /// \brief The actual, canonical type.
- QualType Stored;
-
-public:
- /// \brief Constructs a NULL canonical type.
- CanQual() : Stored() { }
-
- /// \brief Converting constructor that permits implicit upcasting of
- /// canonical type pointers.
- template <typename U>
- CanQual(const CanQual<U> &Other,
- typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
-
- /// \brief Retrieve the underlying type pointer, which refers to a
- /// canonical type.
- ///
- /// The underlying pointer must not be NULL.
- const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
-
- /// \brief Retrieve the underlying type pointer, which refers to a
- /// canonical type, or NULL.
- ///
- const T *getTypePtrOrNull() const {
- return cast_or_null<T>(Stored.getTypePtrOrNull());
- }
-
- /// \brief Implicit conversion to a qualified type.
- operator QualType() const { return Stored; }
-
- /// \brief Implicit conversion to bool.
- explicit operator bool() const { return !isNull(); }
-
- bool isNull() const {
- return Stored.isNull();
- }
-
- SplitQualType split() const { return Stored.split(); }
-
- /// \brief Retrieve a canonical type pointer with a different static type,
- /// upcasting or downcasting as needed.
- ///
- /// The getAs() function is typically used to try to downcast to a
- /// more specific (canonical) type in the type system. For example:
- ///
- /// @code
- /// void f(CanQual<Type> T) {
- /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
- /// // look at Ptr's pointee type
- /// }
- /// }
- /// @endcode
- ///
- /// \returns A proxy pointer to the same type, but with the specified
- /// static type (@p U). If the dynamic type is not the specified static type
- /// or a derived class thereof, a NULL canonical type.
- template<typename U> CanProxy<U> getAs() const;
-
- template<typename U> CanProxy<U> castAs() const;
-
- /// \brief Overloaded arrow operator that produces a canonical type
- /// proxy.
- CanProxy<T> operator->() const;
-
- /// \brief Retrieve all qualifiers.
- Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
-
- /// \brief Retrieve the const/volatile/restrict qualifiers.
- unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
-
- /// \brief Determines whether this type has any qualifiers
- bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
-
- bool isConstQualified() const {
- return Stored.isLocalConstQualified();
- }
- bool isVolatileQualified() const {
- return Stored.isLocalVolatileQualified();
- }
- bool isRestrictQualified() const {
- return Stored.isLocalRestrictQualified();
- }
-
- /// \brief Determines if this canonical type is furthermore
- /// canonical as a parameter. The parameter-canonicalization
- /// process decays arrays to pointers and drops top-level qualifiers.
- bool isCanonicalAsParam() const {
- return Stored.isCanonicalAsParam();
- }
-
- /// \brief Retrieve the unqualified form of this type.
- CanQual<T> getUnqualifiedType() const;
-
- /// \brief Retrieves a version of this type with const applied.
- /// Note that this does not always yield a canonical type.
- QualType withConst() const {
- return Stored.withConst();
- }
-
- /// \brief Determines whether this canonical type is more qualified than
- /// the @p Other canonical type.
- bool isMoreQualifiedThan(CanQual<T> Other) const {
- return Stored.isMoreQualifiedThan(Other.Stored);
- }
-
- /// \brief Determines whether this canonical type is at least as qualified as
- /// the @p Other canonical type.
- bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
- return Stored.isAtLeastAsQualifiedAs(Other.Stored);
- }
-
- /// \brief If the canonical type is a reference type, returns the type that
- /// it refers to; otherwise, returns the type itself.
- CanQual<Type> getNonReferenceType() const;
-
- /// \brief Retrieve the internal representation of this canonical type.
- void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
-
- /// \brief Construct a canonical type from its internal representation.
- static CanQual<T> getFromOpaquePtr(void *Ptr);
-
- /// \brief Builds a canonical type from a QualType.
- ///
- /// This routine is inherently unsafe, because it requires the user to
- /// ensure that the given type is a canonical type with the correct
- // (dynamic) type.
- static CanQual<T> CreateUnsafe(QualType Other);
-
- void dump() const { Stored.dump(); }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddPointer(getAsOpaquePtr());
- }
-};
-
-template<typename T, typename U>
-inline bool operator==(CanQual<T> x, CanQual<U> y) {
- return x.getAsOpaquePtr() == y.getAsOpaquePtr();
-}
-
-template<typename T, typename U>
-inline bool operator!=(CanQual<T> x, CanQual<U> y) {
- return x.getAsOpaquePtr() != y.getAsOpaquePtr();
-}
-
-/// \brief Represents a canonical, potentially-qualified type.
-typedef CanQual<Type> CanQualType;
-
-inline CanQualType Type::getCanonicalTypeUnqualified() const {
- return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
-}
-
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- CanQualType T) {
- DB << static_cast<QualType>(T);
- return DB;
-}
-
-//----------------------------------------------------------------------------//
-// Internal proxy classes used by canonical types
-//----------------------------------------------------------------------------//
-
-#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor) \
-CanQualType Accessor() const { \
-return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \
-}
-
-#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \
-Type Accessor() const { return this->getTypePtr()->Accessor(); }
-
-/// \brief Base class of all canonical proxy types, which is responsible for
-/// storing the underlying canonical type and providing basic conversions.
-template<typename T>
-class CanProxyBase {
-protected:
- CanQual<T> Stored;
-
-public:
- /// \brief Retrieve the pointer to the underlying Type
- const T *getTypePtr() const { return Stored.getTypePtr(); }
-
- /// \brief Implicit conversion to the underlying pointer.
- ///
- /// Also provides the ability to use canonical type proxies in a Boolean
- // context,e.g.,
- /// @code
- /// if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
- /// @endcode
- operator const T*() const { return this->Stored.getTypePtrOrNull(); }
-
- /// \brief Try to convert the given canonical type to a specific structural
- /// type.
- template<typename U> CanProxy<U> getAs() const {
- return this->Stored.template getAs<U>();
- }
-
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
-
- // Type predicates
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
-
- /// \brief Retrieve the proxy-adaptor type.
- ///
- /// This arrow operator is used when CanProxyAdaptor has been specialized
- /// for the given type T. In that case, we reference members of the
- /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
- /// by the arrow operator in the primary CanProxyAdaptor template.
- const CanProxyAdaptor<T> *operator->() const {
- return static_cast<const CanProxyAdaptor<T> *>(this);
- }
-};
-
-/// \brief Replacable canonical proxy adaptor class that provides the link
-/// between a canonical type and the accessors of the type.
-///
-/// The CanProxyAdaptor is a replaceable class template that is instantiated
-/// as part of each canonical proxy type. The primary template merely provides
-/// redirection to the underlying type (T), e.g., @c PointerType. One can
-/// provide specializations of this class template for each underlying type
-/// that provide accessors returning canonical types (@c CanQualType) rather
-/// than the more typical @c QualType, to propagate the notion of "canonical"
-/// through the system.
-template<typename T>
-struct CanProxyAdaptor : CanProxyBase<T> { };
-
-/// \brief Canonical proxy type returned when retrieving the members of a
-/// canonical type or as the result of the @c CanQual<T>::getAs member
-/// function.
-///
-/// The CanProxy type mainly exists as a proxy through which operator-> will
-/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
-/// type that provides canonical-type access to the fields of the type.
-template<typename T>
-class CanProxy : public CanProxyAdaptor<T> {
-public:
- /// \brief Build a NULL proxy.
- CanProxy() { }
-
- /// \brief Build a proxy to the given canonical type.
- CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
-
- /// \brief Implicit conversion to the stored canonical type.
- operator CanQual<T>() const { return this->Stored; }
-};
-
-} // end namespace clang
-
-namespace llvm {
-
-/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
-/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
-/// to return smart pointer (proxies?).
-template<typename T>
-struct simplify_type< ::clang::CanQual<T> > {
- typedef const T *SimpleType;
- static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
- return Val.getTypePtr();
- }
-};
-
-// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
-template<typename T>
-class PointerLikeTypeTraits<clang::CanQual<T> > {
-public:
- static inline void *getAsVoidPointer(clang::CanQual<T> P) {
- return P.getAsOpaquePtr();
- }
- static inline clang::CanQual<T> getFromVoidPointer(void *P) {
- return clang::CanQual<T>::getFromOpaquePtr(P);
- }
- // qualifier information is encoded in the low bits.
- enum { NumLowBitsAvailable = 0 };
-};
-
-} // end namespace llvm
-
-namespace clang {
-
-//----------------------------------------------------------------------------//
-// Canonical proxy adaptors for canonical type nodes.
-//----------------------------------------------------------------------------//
-
-/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
-/// into an iterator over CanQualTypes.
-template <typename InputIterator>
-struct CanTypeIterator
- : llvm::iterator_adaptor_base<
- CanTypeIterator<InputIterator>, InputIterator,
- typename std::iterator_traits<InputIterator>::iterator_category,
- CanQualType,
- typename std::iterator_traits<InputIterator>::difference_type,
- CanProxy<Type>, CanQualType> {
- CanTypeIterator() {}
- explicit CanTypeIterator(InputIterator Iter)
- : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
-
- CanQualType operator*() const { return CanQualType::CreateUnsafe(*this->I); }
- CanProxy<Type> operator->() const;
-};
-
-template<>
-struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
-};
-
-template<>
-struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<BlockPointerType>
- : public CanProxyBase<BlockPointerType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<LValueReferenceType>
- : public CanProxyBase<LValueReferenceType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<RValueReferenceType>
- : public CanProxyBase<RValueReferenceType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
-};
-
-template<>
-struct CanProxyAdaptor<MemberPointerType>
- : public CanProxyBase<MemberPointerType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
-};
-
-// CanProxyAdaptors for arrays are intentionally unimplemented because
-// they are not safe.
-template<> struct CanProxyAdaptor<ArrayType>;
-template<> struct CanProxyAdaptor<ConstantArrayType>;
-template<> struct CanProxyAdaptor<IncompleteArrayType>;
-template<> struct CanProxyAdaptor<VariableArrayType>;
-template<> struct CanProxyAdaptor<DependentSizedArrayType>;
-
-template<>
-struct CanProxyAdaptor<DependentSizedExtVectorType>
- : public CanProxyBase<DependentSizedExtVectorType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
-};
-
-template<>
-struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
-};
-
-template<>
-struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
-};
-
-template<>
-struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
-};
-
-template<>
-struct CanProxyAdaptor<FunctionNoProtoType>
- : public CanProxyBase<FunctionNoProtoType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
-};
-
-template<>
-struct CanProxyAdaptor<FunctionProtoType>
- : public CanProxyBase<FunctionProtoType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
- CanQualType getParamType(unsigned i) const {
- return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
- }
-
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
-
- typedef CanTypeIterator<FunctionProtoType::param_type_iterator>
- param_type_iterator;
-
- param_type_iterator param_type_begin() const {
- return param_type_iterator(this->getTypePtr()->param_type_begin());
- }
-
- param_type_iterator param_type_end() const {
- return param_type_iterator(this->getTypePtr()->param_type_end());
- }
-
- // Note: canonical function types never have exception specifications
-};
-
-template<>
-struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
-};
-
-template<>
-struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
-};
-
-template <>
-struct CanProxyAdaptor<UnaryTransformType>
- : public CanProxyBase<UnaryTransformType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
-};
-
-template<>
-struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
-};
-
-template<>
-struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
-};
-
-template<>
-struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
-};
-
-template<>
-struct CanProxyAdaptor<TemplateTypeParmType>
- : public CanProxyBase<TemplateTypeParmType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
-};
-
-template<>
-struct CanProxyAdaptor<ObjCObjectType>
- : public CanProxyBase<ObjCObjectType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
- getInterface)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
-
- typedef ObjCObjectPointerType::qual_iterator qual_iterator;
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
-};
-
-template<>
-struct CanProxyAdaptor<ObjCObjectPointerType>
- : public CanProxyBase<ObjCObjectPointerType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
- getInterfaceType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
-
- typedef ObjCObjectPointerType::qual_iterator qual_iterator;
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
-};
-
-//----------------------------------------------------------------------------//
-// Method and function definitions
-//----------------------------------------------------------------------------//
-template<typename T>
-inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
- return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
-}
-
-template<typename T>
-inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
- if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
- return RefType->getPointeeType();
- else
- return *this;
-}
-
-template<typename T>
-CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
- CanQual<T> Result;
- Result.Stored = QualType::getFromOpaquePtr(Ptr);
- assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
- Result.Stored.isCanonical()) && "Type is not canonical!");
- return Result;
-}
-
-template<typename T>
-CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
- assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
- assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
- "Dynamic type does not meet the static type's requires");
- CanQual<T> Result;
- Result.Stored = Other;
- return Result;
-}
-
-template<typename T>
-template<typename U>
-CanProxy<U> CanQual<T>::getAs() const {
- ArrayType_cannot_be_used_with_getAs<U> at;
- (void)at;
-
- if (Stored.isNull())
- return CanProxy<U>();
-
- if (isa<U>(Stored.getTypePtr()))
- return CanQual<U>::CreateUnsafe(Stored);
-
- return CanProxy<U>();
-}
-
-template<typename T>
-template<typename U>
-CanProxy<U> CanQual<T>::castAs() const {
- ArrayType_cannot_be_used_with_getAs<U> at;
- (void)at;
-
- assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
- return CanQual<U>::CreateUnsafe(Stored);
-}
-
-template<typename T>
-CanProxy<T> CanQual<T>::operator->() const {
- return CanProxy<T>(*this);
-}
-
-template <typename InputIterator>
-CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const {
- return CanProxy<Type>(*this);
-}
-
-}
-
-
-#endif
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
deleted file mode 100644
index 1d22bcc..0000000
--- a/include/clang/AST/CharUnits.h
+++ /dev/null
@@ -1,240 +0,0 @@
-//===--- CharUnits.h - Character units for sizes and offsets ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CharUnits class
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_CHARUNITS_H
-#define LLVM_CLANG_AST_CHARUNITS_H
-
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/MathExtras.h"
-
-namespace clang {
-
- /// CharUnits - This is an opaque type for sizes expressed in character units.
- /// Instances of this type represent a quantity as a multiple of the size
- /// of the standard C type, char, on the target architecture. As an opaque
- /// type, CharUnits protects you from accidentally combining operations on
- /// quantities in bit units and character units.
- ///
- /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
- /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
- /// the same quantity of storage. However, we use the term 'character unit'
- /// rather than 'byte' to avoid an implication that a character unit is
- /// exactly 8 bits.
- ///
- /// For portability, never assume that a target character is 8 bits wide. Use
- /// CharUnit values wherever you calculate sizes, offsets, or alignments
- /// in character units.
- class CharUnits {
- public:
- typedef int64_t QuantityType;
-
- private:
- QuantityType Quantity;
-
- explicit CharUnits(QuantityType C) : Quantity(C) {}
-
- public:
-
- /// CharUnits - A default constructor.
- CharUnits() : Quantity(0) {}
-
- /// Zero - Construct a CharUnits quantity of zero.
- static CharUnits Zero() {
- return CharUnits(0);
- }
-
- /// One - Construct a CharUnits quantity of one.
- static CharUnits One() {
- return CharUnits(1);
- }
-
- /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
- static CharUnits fromQuantity(QuantityType Quantity) {
- return CharUnits(Quantity);
- }
-
- // Compound assignment.
- CharUnits& operator+= (const CharUnits &Other) {
- Quantity += Other.Quantity;
- return *this;
- }
- CharUnits& operator++ () {
- ++Quantity;
- return *this;
- }
- CharUnits operator++ (int) {
- return CharUnits(Quantity++);
- }
- CharUnits& operator-= (const CharUnits &Other) {
- Quantity -= Other.Quantity;
- return *this;
- }
- CharUnits& operator-- () {
- --Quantity;
- return *this;
- }
- CharUnits operator-- (int) {
- return CharUnits(Quantity--);
- }
-
- // Comparison operators.
- bool operator== (const CharUnits &Other) const {
- return Quantity == Other.Quantity;
- }
- bool operator!= (const CharUnits &Other) const {
- return Quantity != Other.Quantity;
- }
-
- // Relational operators.
- bool operator< (const CharUnits &Other) const {
- return Quantity < Other.Quantity;
- }
- bool operator<= (const CharUnits &Other) const {
- return Quantity <= Other.Quantity;
- }
- bool operator> (const CharUnits &Other) const {
- return Quantity > Other.Quantity;
- }
- bool operator>= (const CharUnits &Other) const {
- return Quantity >= Other.Quantity;
- }
-
- // Other predicates.
-
- /// isZero - Test whether the quantity equals zero.
- bool isZero() const { return Quantity == 0; }
-
- /// isOne - Test whether the quantity equals one.
- bool isOne() const { return Quantity == 1; }
-
- /// isPositive - Test whether the quantity is greater than zero.
- bool isPositive() const { return Quantity > 0; }
-
- /// isNegative - Test whether the quantity is less than zero.
- bool isNegative() const { return Quantity < 0; }
-
- /// isPowerOfTwo - Test whether the quantity is a power of two.
- /// Zero is not a power of two.
- bool isPowerOfTwo() const {
- return (Quantity & -Quantity) == Quantity;
- }
-
- /// Test whether this is a multiple of the other value.
- ///
- /// Among other things, this promises that
- /// self.RoundUpToAlignment(N) will just return self.
- bool isMultipleOf(CharUnits N) const {
- return (*this % N) == 0;
- }
-
- // Arithmetic operators.
- CharUnits operator* (QuantityType N) const {
- return CharUnits(Quantity * N);
- }
- CharUnits operator/ (QuantityType N) const {
- return CharUnits(Quantity / N);
- }
- QuantityType operator/ (const CharUnits &Other) const {
- return Quantity / Other.Quantity;
- }
- CharUnits operator% (QuantityType N) const {
- return CharUnits(Quantity % N);
- }
- QuantityType operator% (const CharUnits &Other) const {
- return Quantity % Other.Quantity;
- }
- CharUnits operator+ (const CharUnits &Other) const {
- return CharUnits(Quantity + Other.Quantity);
- }
- CharUnits operator- (const CharUnits &Other) const {
- return CharUnits(Quantity - Other.Quantity);
- }
- CharUnits operator- () const {
- return CharUnits(-Quantity);
- }
-
-
- // Conversions.
-
- /// getQuantity - Get the raw integer representation of this quantity.
- QuantityType getQuantity() const { return Quantity; }
-
- /// RoundUpToAlignment - 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.
- CharUnits RoundUpToAlignment(const CharUnits &Align) const {
- return CharUnits(llvm::RoundUpToAlignment(Quantity,
- Align.Quantity));
- }
-
- /// Given that this is a non-zero alignment value, what is the
- /// alignment at the given offset?
- CharUnits alignmentAtOffset(CharUnits offset) const {
- assert(Quantity != 0 && "offsetting from unknown alignment?");
- return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
- }
-
- /// Given that this is the alignment of the first element of an
- /// array, return the minimum alignment of any element in the array.
- CharUnits alignmentOfArrayElement(CharUnits elementSize) const {
- // Since we don't track offsetted alignments, the alignment of
- // the second element (or any odd element) will be minimally
- // aligned.
- return alignmentAtOffset(elementSize);
- }
-
-
- }; // class CharUnit
-} // namespace clang
-
-inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale,
- const clang::CharUnits &CU) {
- return CU * Scale;
-}
-
-namespace llvm {
-
-template<> struct DenseMapInfo<clang::CharUnits> {
- static clang::CharUnits getEmptyKey() {
- clang::CharUnits::QuantityType Quantity =
- DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
-
- return clang::CharUnits::fromQuantity(Quantity);
- }
-
- static clang::CharUnits getTombstoneKey() {
- clang::CharUnits::QuantityType Quantity =
- DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
-
- return clang::CharUnits::fromQuantity(Quantity);
- }
-
- static unsigned getHashValue(const clang::CharUnits &CU) {
- clang::CharUnits::QuantityType Quantity = CU.getQuantity();
- return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
- }
-
- static bool isEqual(const clang::CharUnits &LHS,
- const clang::CharUnits &RHS) {
- return LHS == RHS;
- }
-};
-
-template <> struct isPodLike<clang::CharUnits> {
- static const bool value = true;
-};
-
-} // end namespace llvm
-
-#endif // LLVM_CLANG_AST_CHARUNITS_H
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
deleted file mode 100644
index 94470cb..0000000
--- a/include/clang/AST/Comment.h
+++ /dev/null
@@ -1,1142 +0,0 @@
-//===--- Comment.h - Comment AST nodes --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines comment AST nodes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENT_H
-#define LLVM_CLANG_AST_COMMENT_H
-
-#include "clang/AST/CommentCommandTraits.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-class Decl;
-class ParmVarDecl;
-class TemplateParameterList;
-
-namespace comments {
-class FullComment;
-
-/// Describes the syntax that was used in a documentation command.
-///
-/// Exact values of this enumeration are important because they used to select
-/// parts of diagnostic messages. Audit diagnostics before changing or adding
-/// a new value.
-enum CommandMarkerKind {
- /// Command started with a backslash character:
- /// \code
- /// \foo
- /// \endcode
- CMK_Backslash = 0,
-
- /// Command started with an 'at' character:
- /// \code
- /// @foo
- /// \endcode
- CMK_At = 1
-};
-
-/// Any part of the comment.
-/// Abstract class.
-class Comment {
-protected:
- /// Preferred location to show caret.
- SourceLocation Loc;
-
- /// Source range of this AST node.
- SourceRange Range;
-
- class CommentBitfields {
- friend class Comment;
-
- /// Type of this AST node.
- unsigned Kind : 8;
- };
- enum { NumCommentBits = 8 };
-
- class InlineContentCommentBitfields {
- friend class InlineContentComment;
-
- unsigned : NumCommentBits;
-
- /// True if there is a newline after this inline content node.
- /// (There is no separate AST node for a newline.)
- unsigned HasTrailingNewline : 1;
- };
- enum { NumInlineContentCommentBits = NumCommentBits + 1 };
-
- class TextCommentBitfields {
- friend class TextComment;
-
- unsigned : NumInlineContentCommentBits;
-
- /// True if \c IsWhitespace field contains a valid value.
- mutable unsigned IsWhitespaceValid : 1;
-
- /// True if this comment AST node contains only whitespace.
- mutable unsigned IsWhitespace : 1;
- };
- enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
-
- class InlineCommandCommentBitfields {
- friend class InlineCommandComment;
-
- unsigned : NumInlineContentCommentBits;
-
- unsigned RenderKind : 2;
- unsigned CommandID : CommandInfo::NumCommandIDBits;
- };
- enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 2 +
- CommandInfo::NumCommandIDBits };
-
- class HTMLTagCommentBitfields {
- friend class HTMLTagComment;
-
- unsigned : NumInlineContentCommentBits;
-
- /// True if we found that this tag is malformed in some way.
- unsigned IsMalformed : 1;
- };
- enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 };
-
- class HTMLStartTagCommentBitfields {
- friend class HTMLStartTagComment;
-
- unsigned : NumHTMLTagCommentBits;
-
- /// True if this tag is self-closing (e. g., <br />). This is based on tag
- /// spelling in comment (plain <br> would not set this flag).
- unsigned IsSelfClosing : 1;
- };
- enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 };
-
- class ParagraphCommentBitfields {
- friend class ParagraphComment;
-
- unsigned : NumCommentBits;
-
- /// True if \c IsWhitespace field contains a valid value.
- mutable unsigned IsWhitespaceValid : 1;
-
- /// True if this comment AST node contains only whitespace.
- mutable unsigned IsWhitespace : 1;
- };
- enum { NumParagraphCommentBits = NumCommentBits + 2 };
-
- class BlockCommandCommentBitfields {
- friend class BlockCommandComment;
-
- unsigned : NumCommentBits;
-
- unsigned CommandID : CommandInfo::NumCommandIDBits;
-
- /// Describes the syntax that was used in a documentation command.
- /// Contains values from CommandMarkerKind enum.
- unsigned CommandMarker : 1;
- };
- enum { NumBlockCommandCommentBits = NumCommentBits +
- CommandInfo::NumCommandIDBits + 1 };
-
- class ParamCommandCommentBitfields {
- friend class ParamCommandComment;
-
- unsigned : NumBlockCommandCommentBits;
-
- /// Parameter passing direction, see ParamCommandComment::PassDirection.
- unsigned Direction : 2;
-
- /// True if direction was specified explicitly in the comment.
- unsigned IsDirectionExplicit : 1;
- };
- enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
-
- union {
- CommentBitfields CommentBits;
- InlineContentCommentBitfields InlineContentCommentBits;
- TextCommentBitfields TextCommentBits;
- InlineCommandCommentBitfields InlineCommandCommentBits;
- HTMLTagCommentBitfields HTMLTagCommentBits;
- HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
- ParagraphCommentBitfields ParagraphCommentBits;
- BlockCommandCommentBitfields BlockCommandCommentBits;
- ParamCommandCommentBitfields ParamCommandCommentBits;
- };
-
- void setSourceRange(SourceRange SR) {
- Range = SR;
- }
-
- void setLocation(SourceLocation L) {
- Loc = L;
- }
-
-public:
- enum CommentKind {
- NoCommentKind = 0,
-#define COMMENT(CLASS, PARENT) CLASS##Kind,
-#define COMMENT_RANGE(BASE, FIRST, LAST) \
- First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind,
-#define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
- First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind
-#define ABSTRACT_COMMENT(COMMENT)
-#include "clang/AST/CommentNodes.inc"
- };
-
- Comment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd) :
- Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
- CommentBits.Kind = K;
- }
-
- CommentKind getCommentKind() const {
- return static_cast<CommentKind>(CommentBits.Kind);
- }
-
- const char *getCommentKindName() const;
-
- void dump() const;
- void dumpColor() const;
- void dump(const ASTContext &Context) const;
- void dump(raw_ostream &OS, const CommandTraits *Traits,
- const SourceManager *SM) const;
-
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return Range.getBegin();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- return Range.getEnd();
- }
-
- SourceLocation getLocation() const LLVM_READONLY { return Loc; }
-
- typedef Comment * const *child_iterator;
-
- child_iterator child_begin() const;
- child_iterator child_end() const;
-
- // TODO: const child iterator
-
- unsigned child_count() const {
- return child_end() - child_begin();
- }
-};
-
-/// Inline content (contained within a block).
-/// Abstract class.
-class InlineContentComment : public Comment {
-protected:
- InlineContentComment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd) :
- Comment(K, LocBegin, LocEnd) {
- InlineContentCommentBits.HasTrailingNewline = 0;
- }
-
-public:
- static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstInlineContentCommentConstant &&
- C->getCommentKind() <= LastInlineContentCommentConstant;
- }
-
- void addTrailingNewline() {
- InlineContentCommentBits.HasTrailingNewline = 1;
- }
-
- bool hasTrailingNewline() const {
- return InlineContentCommentBits.HasTrailingNewline;
- }
-};
-
-/// Plain text.
-class TextComment : public InlineContentComment {
- StringRef Text;
-
-public:
- TextComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef Text) :
- InlineContentComment(TextCommentKind, LocBegin, LocEnd),
- Text(Text) {
- TextCommentBits.IsWhitespaceValid = false;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == TextCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- StringRef getText() const LLVM_READONLY { return Text; }
-
- bool isWhitespace() const {
- if (TextCommentBits.IsWhitespaceValid)
- return TextCommentBits.IsWhitespace;
-
- TextCommentBits.IsWhitespace = isWhitespaceNoCache();
- TextCommentBits.IsWhitespaceValid = true;
- return TextCommentBits.IsWhitespace;
- }
-
-private:
- bool isWhitespaceNoCache() const;
-};
-
-/// A command with word-like arguments that is considered inline content.
-class InlineCommandComment : public InlineContentComment {
-public:
- struct Argument {
- SourceRange Range;
- StringRef Text;
-
- Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
- };
-
- /// The most appropriate rendering mode for this command, chosen on command
- /// semantics in Doxygen.
- enum RenderKind {
- RenderNormal,
- RenderBold,
- RenderMonospaced,
- RenderEmphasized
- };
-
-protected:
- /// Command arguments.
- ArrayRef<Argument> Args;
-
-public:
- InlineCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- RenderKind RK,
- ArrayRef<Argument> Args) :
- InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
- Args(Args) {
- InlineCommandCommentBits.RenderKind = RK;
- InlineCommandCommentBits.CommandID = CommandID;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == InlineCommandCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- unsigned getCommandID() const {
- return InlineCommandCommentBits.CommandID;
- }
-
- StringRef getCommandName(const CommandTraits &Traits) const {
- return Traits.getCommandInfo(getCommandID())->Name;
- }
-
- SourceRange getCommandNameRange() const {
- return SourceRange(getLocStart().getLocWithOffset(-1),
- getLocEnd());
- }
-
- RenderKind getRenderKind() const {
- return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
- }
-
- unsigned getNumArgs() const {
- return Args.size();
- }
-
- StringRef getArgText(unsigned Idx) const {
- return Args[Idx].Text;
- }
-
- SourceRange getArgRange(unsigned Idx) const {
- return Args[Idx].Range;
- }
-};
-
-/// Abstract class for opening and closing HTML tags. HTML tags are always
-/// treated as inline content (regardless HTML semantics).
-class HTMLTagComment : public InlineContentComment {
-protected:
- StringRef TagName;
- SourceRange TagNameRange;
-
- HTMLTagComment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef TagName,
- SourceLocation TagNameBegin,
- SourceLocation TagNameEnd) :
- InlineContentComment(K, LocBegin, LocEnd),
- TagName(TagName),
- TagNameRange(TagNameBegin, TagNameEnd) {
- setLocation(TagNameBegin);
- HTMLTagCommentBits.IsMalformed = 0;
- }
-
-public:
- static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstHTMLTagCommentConstant &&
- C->getCommentKind() <= LastHTMLTagCommentConstant;
- }
-
- StringRef getTagName() const LLVM_READONLY { return TagName; }
-
- SourceRange getTagNameSourceRange() const LLVM_READONLY {
- SourceLocation L = getLocation();
- return SourceRange(L.getLocWithOffset(1),
- L.getLocWithOffset(1 + TagName.size()));
- }
-
- bool isMalformed() const {
- return HTMLTagCommentBits.IsMalformed;
- }
-
- void setIsMalformed() {
- HTMLTagCommentBits.IsMalformed = 1;
- }
-};
-
-/// An opening HTML tag with attributes.
-class HTMLStartTagComment : public HTMLTagComment {
-public:
- class Attribute {
- public:
- SourceLocation NameLocBegin;
- StringRef Name;
-
- SourceLocation EqualsLoc;
-
- SourceRange ValueRange;
- StringRef Value;
-
- Attribute() { }
-
- Attribute(SourceLocation NameLocBegin, StringRef Name) :
- NameLocBegin(NameLocBegin), Name(Name),
- EqualsLoc(SourceLocation()),
- ValueRange(SourceRange()), Value(StringRef())
- { }
-
- Attribute(SourceLocation NameLocBegin, StringRef Name,
- SourceLocation EqualsLoc,
- SourceRange ValueRange, StringRef Value) :
- NameLocBegin(NameLocBegin), Name(Name),
- EqualsLoc(EqualsLoc),
- ValueRange(ValueRange), Value(Value)
- { }
-
- SourceLocation getNameLocEnd() const {
- return NameLocBegin.getLocWithOffset(Name.size());
- }
-
- SourceRange getNameRange() const {
- return SourceRange(NameLocBegin, getNameLocEnd());
- }
- };
-
-private:
- ArrayRef<Attribute> Attributes;
-
-public:
- HTMLStartTagComment(SourceLocation LocBegin,
- StringRef TagName) :
- HTMLTagComment(HTMLStartTagCommentKind,
- LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()),
- TagName,
- LocBegin.getLocWithOffset(1),
- LocBegin.getLocWithOffset(1 + TagName.size())) {
- HTMLStartTagCommentBits.IsSelfClosing = false;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == HTMLStartTagCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- unsigned getNumAttrs() const {
- return Attributes.size();
- }
-
- const Attribute &getAttr(unsigned Idx) const {
- return Attributes[Idx];
- }
-
- void setAttrs(ArrayRef<Attribute> Attrs) {
- Attributes = Attrs;
- if (!Attrs.empty()) {
- const Attribute &Attr = Attrs.back();
- SourceLocation L = Attr.ValueRange.getEnd();
- if (L.isValid())
- Range.setEnd(L);
- else {
- Range.setEnd(Attr.getNameLocEnd());
- }
- }
- }
-
- void setGreaterLoc(SourceLocation GreaterLoc) {
- Range.setEnd(GreaterLoc);
- }
-
- bool isSelfClosing() const {
- return HTMLStartTagCommentBits.IsSelfClosing;
- }
-
- void setSelfClosing() {
- HTMLStartTagCommentBits.IsSelfClosing = true;
- }
-};
-
-/// A closing HTML tag.
-class HTMLEndTagComment : public HTMLTagComment {
-public:
- HTMLEndTagComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef TagName) :
- HTMLTagComment(HTMLEndTagCommentKind,
- LocBegin, LocEnd,
- TagName,
- LocBegin.getLocWithOffset(2),
- LocBegin.getLocWithOffset(2 + TagName.size()))
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == HTMLEndTagCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-};
-
-/// Block content (contains inline content).
-/// Abstract class.
-class BlockContentComment : public Comment {
-protected:
- BlockContentComment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd) :
- Comment(K, LocBegin, LocEnd)
- { }
-
-public:
- static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstBlockContentCommentConstant &&
- C->getCommentKind() <= LastBlockContentCommentConstant;
- }
-};
-
-/// A single paragraph that contains inline content.
-class ParagraphComment : public BlockContentComment {
- ArrayRef<InlineContentComment *> Content;
-
-public:
- ParagraphComment(ArrayRef<InlineContentComment *> Content) :
- BlockContentComment(ParagraphCommentKind,
- SourceLocation(),
- SourceLocation()),
- Content(Content) {
- if (Content.empty()) {
- ParagraphCommentBits.IsWhitespace = true;
- ParagraphCommentBits.IsWhitespaceValid = true;
- return;
- }
-
- ParagraphCommentBits.IsWhitespaceValid = false;
-
- setSourceRange(SourceRange(Content.front()->getLocStart(),
- Content.back()->getLocEnd()));
- setLocation(Content.front()->getLocStart());
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == ParagraphCommentKind;
- }
-
- child_iterator child_begin() const {
- return reinterpret_cast<child_iterator>(Content.begin());
- }
-
- child_iterator child_end() const {
- return reinterpret_cast<child_iterator>(Content.end());
- }
-
- bool isWhitespace() const {
- if (ParagraphCommentBits.IsWhitespaceValid)
- return ParagraphCommentBits.IsWhitespace;
-
- ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache();
- ParagraphCommentBits.IsWhitespaceValid = true;
- return ParagraphCommentBits.IsWhitespace;
- }
-
-private:
- bool isWhitespaceNoCache() const;
-};
-
-/// A command that has zero or more word-like arguments (number of word-like
-/// arguments depends on command name) and a paragraph as an argument
-/// (e. g., \\brief).
-class BlockCommandComment : public BlockContentComment {
-public:
- struct Argument {
- SourceRange Range;
- StringRef Text;
-
- Argument() { }
- Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
- };
-
-protected:
- /// Word-like arguments.
- ArrayRef<Argument> Args;
-
- /// Paragraph argument.
- ParagraphComment *Paragraph;
-
- BlockCommandComment(CommentKind K,
- SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockContentComment(K, LocBegin, LocEnd),
- Paragraph(nullptr) {
- setLocation(getCommandNameBeginLoc());
- BlockCommandCommentBits.CommandID = CommandID;
- BlockCommandCommentBits.CommandMarker = CommandMarker;
- }
-
-public:
- BlockCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
- Paragraph(nullptr) {
- setLocation(getCommandNameBeginLoc());
- BlockCommandCommentBits.CommandID = CommandID;
- BlockCommandCommentBits.CommandMarker = CommandMarker;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstBlockCommandCommentConstant &&
- C->getCommentKind() <= LastBlockCommandCommentConstant;
- }
-
- child_iterator child_begin() const {
- return reinterpret_cast<child_iterator>(&Paragraph);
- }
-
- child_iterator child_end() const {
- return reinterpret_cast<child_iterator>(&Paragraph + 1);
- }
-
- unsigned getCommandID() const {
- return BlockCommandCommentBits.CommandID;
- }
-
- StringRef getCommandName(const CommandTraits &Traits) const {
- return Traits.getCommandInfo(getCommandID())->Name;
- }
-
- SourceLocation getCommandNameBeginLoc() const {
- return getLocStart().getLocWithOffset(1);
- }
-
- SourceRange getCommandNameRange(const CommandTraits &Traits) const {
- StringRef Name = getCommandName(Traits);
- return SourceRange(getCommandNameBeginLoc(),
- getLocStart().getLocWithOffset(1 + Name.size()));
- }
-
- unsigned getNumArgs() const {
- return Args.size();
- }
-
- StringRef getArgText(unsigned Idx) const {
- return Args[Idx].Text;
- }
-
- SourceRange getArgRange(unsigned Idx) const {
- return Args[Idx].Range;
- }
-
- void setArgs(ArrayRef<Argument> A) {
- Args = A;
- if (Args.size() > 0) {
- SourceLocation NewLocEnd = Args.back().Range.getEnd();
- if (NewLocEnd.isValid())
- setSourceRange(SourceRange(getLocStart(), NewLocEnd));
- }
- }
-
- ParagraphComment *getParagraph() const LLVM_READONLY {
- return Paragraph;
- }
-
- bool hasNonWhitespaceParagraph() const {
- return Paragraph && !Paragraph->isWhitespace();
- }
-
- void setParagraph(ParagraphComment *PC) {
- Paragraph = PC;
- SourceLocation NewLocEnd = PC->getLocEnd();
- if (NewLocEnd.isValid())
- setSourceRange(SourceRange(getLocStart(), NewLocEnd));
- }
-
- CommandMarkerKind getCommandMarker() const LLVM_READONLY {
- return static_cast<CommandMarkerKind>(
- BlockCommandCommentBits.CommandMarker);
- }
-};
-
-/// Doxygen \\param command.
-class ParamCommandComment : public BlockCommandComment {
-private:
- /// Parameter index in the function declaration.
- unsigned ParamIndex;
-
-public:
- enum : unsigned {
- InvalidParamIndex = ~0U,
- VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
- };
-
- ParamCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
- CommandID, CommandMarker),
- ParamIndex(InvalidParamIndex) {
- ParamCommandCommentBits.Direction = In;
- ParamCommandCommentBits.IsDirectionExplicit = false;
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == ParamCommandCommentKind;
- }
-
- enum PassDirection {
- In,
- Out,
- InOut
- };
-
- static const char *getDirectionAsString(PassDirection D);
-
- PassDirection getDirection() const LLVM_READONLY {
- return static_cast<PassDirection>(ParamCommandCommentBits.Direction);
- }
-
- bool isDirectionExplicit() const LLVM_READONLY {
- return ParamCommandCommentBits.IsDirectionExplicit;
- }
-
- void setDirection(PassDirection Direction, bool Explicit) {
- ParamCommandCommentBits.Direction = Direction;
- ParamCommandCommentBits.IsDirectionExplicit = Explicit;
- }
-
- bool hasParamName() const {
- return getNumArgs() > 0;
- }
-
- StringRef getParamName(const FullComment *FC) const;
-
- StringRef getParamNameAsWritten() const {
- return Args[0].Text;
- }
-
- SourceRange getParamNameRange() const {
- return Args[0].Range;
- }
-
- bool isParamIndexValid() const LLVM_READONLY {
- return ParamIndex != InvalidParamIndex;
- }
-
- bool isVarArgParam() const LLVM_READONLY {
- return ParamIndex == VarArgParamIndex;
- }
-
- void setIsVarArgParam() {
- ParamIndex = VarArgParamIndex;
- assert(isParamIndexValid());
- }
-
- unsigned getParamIndex() const LLVM_READONLY {
- assert(isParamIndexValid());
- assert(!isVarArgParam());
- return ParamIndex;
- }
-
- void setParamIndex(unsigned Index) {
- ParamIndex = Index;
- assert(isParamIndexValid());
- assert(!isVarArgParam());
- }
-};
-
-/// Doxygen \\tparam command, describes a template parameter.
-class TParamCommandComment : public BlockCommandComment {
-private:
- /// If this template parameter name was resolved (found in template parameter
- /// list), then this stores a list of position indexes in all template
- /// parameter lists.
- ///
- /// For example:
- /// \verbatim
- /// template<typename C, template<typename T> class TT>
- /// void test(TT<int> aaa);
- /// \endverbatim
- /// For C: Position = { 0 }
- /// For TT: Position = { 1 }
- /// For T: Position = { 1, 0 }
- ArrayRef<unsigned> Position;
-
-public:
- TParamCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID,
- CommandMarker)
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == TParamCommandCommentKind;
- }
-
- bool hasParamName() const {
- return getNumArgs() > 0;
- }
-
- StringRef getParamName(const FullComment *FC) const;
-
- StringRef getParamNameAsWritten() const {
- return Args[0].Text;
- }
-
- SourceRange getParamNameRange() const {
- return Args[0].Range;
- }
-
- bool isPositionValid() const LLVM_READONLY {
- return !Position.empty();
- }
-
- unsigned getDepth() const {
- assert(isPositionValid());
- return Position.size();
- }
-
- unsigned getIndex(unsigned Depth) const {
- assert(isPositionValid());
- return Position[Depth];
- }
-
- void setPosition(ArrayRef<unsigned> NewPosition) {
- Position = NewPosition;
- assert(isPositionValid());
- }
-};
-
-/// A line of text contained in a verbatim block.
-class VerbatimBlockLineComment : public Comment {
- StringRef Text;
-
-public:
- VerbatimBlockLineComment(SourceLocation LocBegin,
- StringRef Text) :
- Comment(VerbatimBlockLineCommentKind,
- LocBegin,
- LocBegin.getLocWithOffset(Text.size())),
- Text(Text)
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimBlockLineCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- StringRef getText() const LLVM_READONLY {
- return Text;
- }
-};
-
-/// A verbatim block command (e. g., preformatted code). Verbatim block has an
-/// opening and a closing command and contains multiple lines of text
-/// (VerbatimBlockLineComment nodes).
-class VerbatimBlockComment : public BlockCommandComment {
-protected:
- StringRef CloseName;
- SourceLocation CloseNameLocBegin;
- ArrayRef<VerbatimBlockLineComment *> Lines;
-
-public:
- VerbatimBlockComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID) :
- BlockCommandComment(VerbatimBlockCommentKind,
- LocBegin, LocEnd, CommandID,
- CMK_At) // FIXME: improve source fidelity.
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimBlockCommentKind;
- }
-
- child_iterator child_begin() const {
- return reinterpret_cast<child_iterator>(Lines.begin());
- }
-
- child_iterator child_end() const {
- return reinterpret_cast<child_iterator>(Lines.end());
- }
-
- void setCloseName(StringRef Name, SourceLocation LocBegin) {
- CloseName = Name;
- CloseNameLocBegin = LocBegin;
- }
-
- void setLines(ArrayRef<VerbatimBlockLineComment *> L) {
- Lines = L;
- }
-
- StringRef getCloseName() const {
- return CloseName;
- }
-
- unsigned getNumLines() const {
- return Lines.size();
- }
-
- StringRef getText(unsigned LineIdx) const {
- return Lines[LineIdx]->getText();
- }
-};
-
-/// A verbatim line command. Verbatim line has an opening command, a single
-/// line of text (up to the newline after the opening command) and has no
-/// closing command.
-class VerbatimLineComment : public BlockCommandComment {
-protected:
- StringRef Text;
- SourceLocation TextBegin;
-
-public:
- VerbatimLineComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- SourceLocation TextBegin,
- StringRef Text) :
- BlockCommandComment(VerbatimLineCommentKind,
- LocBegin, LocEnd,
- CommandID,
- CMK_At), // FIXME: improve source fidelity.
- Text(Text),
- TextBegin(TextBegin)
- { }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimLineCommentKind;
- }
-
- child_iterator child_begin() const { return nullptr; }
-
- child_iterator child_end() const { return nullptr; }
-
- StringRef getText() const {
- return Text;
- }
-
- SourceRange getTextRange() const {
- return SourceRange(TextBegin, getLocEnd());
- }
-};
-
-/// Information about the declaration, useful to clients of FullComment.
-struct DeclInfo {
- /// Declaration the comment is actually attached to (in the source).
- /// Should not be NULL.
- const Decl *CommentDecl;
-
- /// CurrentDecl is the declaration with which the FullComment is associated.
- ///
- /// It can be different from \c CommentDecl. It happens when we we decide
- /// that the comment originally attached to \c CommentDecl is fine for
- /// \c CurrentDecl too (for example, for a redeclaration or an overrider of
- /// \c CommentDecl).
- ///
- /// The information in the DeclInfo corresponds to CurrentDecl.
- const Decl *CurrentDecl;
-
- /// Parameters that can be referenced by \\param if \c CommentDecl is something
- /// that we consider a "function".
- ArrayRef<const ParmVarDecl *> ParamVars;
-
- /// Function return type if \c CommentDecl is something that we consider
- /// a "function".
- QualType ReturnType;
-
- /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
- /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
- /// true).
- const TemplateParameterList *TemplateParameters;
-
- /// A simplified description of \c CommentDecl kind that should be good enough
- /// for documentation rendering purposes.
- enum DeclKind {
- /// Everything else not explicitly mentioned below.
- OtherKind,
-
- /// Something that we consider a "function":
- /// \li function,
- /// \li function template,
- /// \li function template specialization,
- /// \li member function,
- /// \li member function template,
- /// \li member function template specialization,
- /// \li ObjC method,
- /// \li a typedef for a function pointer, member function pointer,
- /// ObjC block.
- FunctionKind,
-
- /// Something that we consider a "class":
- /// \li class/struct,
- /// \li class template,
- /// \li class template (partial) specialization.
- ClassKind,
-
- /// Something that we consider a "variable":
- /// \li namespace scope variables;
- /// \li static and non-static class data members;
- /// \li enumerators.
- VariableKind,
-
- /// A C++ namespace.
- NamespaceKind,
-
- /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration),
- /// see \c TypedefNameDecl.
- TypedefKind,
-
- /// An enumeration or scoped enumeration.
- EnumKind
- };
-
- /// What kind of template specialization \c CommentDecl is.
- enum TemplateDeclKind {
- NotTemplate,
- Template,
- TemplateSpecialization,
- TemplatePartialSpecialization
- };
-
- /// If false, only \c CommentDecl is valid.
- unsigned IsFilled : 1;
-
- /// Simplified kind of \c CommentDecl, see \c DeclKind enum.
- unsigned Kind : 3;
-
- /// Is \c CommentDecl a template declaration.
- unsigned TemplateKind : 2;
-
- /// Is \c CommentDecl an ObjCMethodDecl.
- unsigned IsObjCMethod : 1;
-
- /// Is \c CommentDecl a non-static member function of C++ class or
- /// instance method of ObjC class.
- /// Can be true only if \c IsFunctionDecl is true.
- unsigned IsInstanceMethod : 1;
-
- /// Is \c CommentDecl a static member function of C++ class or
- /// class method of ObjC class.
- /// Can be true only if \c IsFunctionDecl is true.
- unsigned IsClassMethod : 1;
-
- void fill();
-
- DeclKind getKind() const LLVM_READONLY {
- return static_cast<DeclKind>(Kind);
- }
-
- TemplateDeclKind getTemplateKind() const LLVM_READONLY {
- return static_cast<TemplateDeclKind>(TemplateKind);
- }
-};
-
-/// A full comment attached to a declaration, contains block content.
-class FullComment : public Comment {
- ArrayRef<BlockContentComment *> Blocks;
- DeclInfo *ThisDeclInfo;
-
-public:
- FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
- Comment(FullCommentKind, SourceLocation(), SourceLocation()),
- Blocks(Blocks), ThisDeclInfo(D) {
- if (Blocks.empty())
- return;
-
- setSourceRange(SourceRange(Blocks.front()->getLocStart(),
- Blocks.back()->getLocEnd()));
- setLocation(Blocks.front()->getLocStart());
- }
-
- static bool classof(const Comment *C) {
- return C->getCommentKind() == FullCommentKind;
- }
-
- child_iterator child_begin() const {
- return reinterpret_cast<child_iterator>(Blocks.begin());
- }
-
- child_iterator child_end() const {
- return reinterpret_cast<child_iterator>(Blocks.end());
- }
-
- const Decl *getDecl() const LLVM_READONLY {
- return ThisDeclInfo->CommentDecl;
- }
-
- const DeclInfo *getDeclInfo() const LLVM_READONLY {
- if (!ThisDeclInfo->IsFilled)
- ThisDeclInfo->fill();
- return ThisDeclInfo;
- }
-
- ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
-
-};
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h
deleted file mode 100644
index be5b8ee..0000000
--- a/include/clang/AST/CommentBriefParser.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===--- CommentBriefParser.h - Dumb comment parser -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a very simple Doxygen comment parser.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CLANG_AST_COMMENTBRIEFPARSER_H
-#define LLVM_CLANG_AST_COMMENTBRIEFPARSER_H
-
-#include "clang/AST/CommentLexer.h"
-
-namespace clang {
-namespace comments {
-
-/// A very simple comment parser that extracts "a brief description".
-///
-/// Due to a variety of comment styles, it considers the following as "a brief
-/// description", in order of priority:
-/// \li a \\brief or \\short command,
-/// \li the first paragraph,
-/// \li a \\result or \\return or \\returns paragraph.
-class BriefParser {
- Lexer &L;
-
- const CommandTraits &Traits;
-
- /// Current lookahead token.
- Token Tok;
-
- SourceLocation ConsumeToken() {
- SourceLocation Loc = Tok.getLocation();
- L.lex(Tok);
- return Loc;
- }
-
-public:
- BriefParser(Lexer &L, const CommandTraits &Traits);
-
- /// Return the best "brief description" we can find.
- std::string Parse();
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
deleted file mode 100644
index 289f2fd..0000000
--- a/include/clang/AST/CommentCommandTraits.h
+++ /dev/null
@@ -1,189 +0,0 @@
-//===--- CommentCommandTraits.h - Comment command properties ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the class that provides information about comment
-// commands.
-//
-//===----------------------------------------------------------------------===//
-
-
-#ifndef LLVM_CLANG_AST_COMMENTCOMMANDTRAITS_H
-#define LLVM_CLANG_AST_COMMENTCOMMANDTRAITS_H
-
-#include "clang/Basic/CommentOptions.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
-namespace comments {
-
-/// \brief Information about a single command.
-///
-/// When reordering, adding or removing members please update the corresponding
-/// TableGen backend.
-struct CommandInfo {
- unsigned getID() const {
- return ID;
- }
-
- const char *Name;
-
- /// Name of the command that ends the verbatim block.
- const char *EndCommandName;
-
- /// DRY definition of the number of bits used for a command ID.
- enum { NumCommandIDBits = 20 };
-
- /// The ID of the command.
- unsigned ID : NumCommandIDBits;
-
- /// Number of word-like arguments for a given block command, except for
- /// \\param and \\tparam commands -- these have special argument parsers.
- unsigned NumArgs : 4;
-
- /// True if this command is a inline command (of any kind).
- unsigned IsInlineCommand : 1;
-
- /// True if this command is a block command (of any kind).
- unsigned IsBlockCommand : 1;
-
- /// True if this command is introducing a brief documentation
- /// paragraph (\\brief or an alias).
- unsigned IsBriefCommand : 1;
-
- /// True if this command is \\returns or an alias.
- unsigned IsReturnsCommand : 1;
-
- /// True if this command is introducing documentation for a function
- /// parameter (\\param or an alias).
- unsigned IsParamCommand : 1;
-
- /// True if this command is introducing documentation for
- /// a template parameter (\\tparam or an alias).
- unsigned IsTParamCommand : 1;
-
- /// True if this command is \\throws or an alias.
- unsigned IsThrowsCommand : 1;
-
- /// True if this command is \\deprecated or an alias.
- unsigned IsDeprecatedCommand : 1;
-
- /// \brief True if this is a \\headerfile-like command.
- unsigned IsHeaderfileCommand : 1;
-
- /// True if we don't want to warn about this command being passed an empty
- /// paragraph. Meaningful only for block commands.
- unsigned IsEmptyParagraphAllowed : 1;
-
- /// \brief True if this command is a verbatim-like block command.
- ///
- /// A verbatim-like block command eats every character (except line starting
- /// decorations) until matching end command is seen or comment end is hit.
- unsigned IsVerbatimBlockCommand : 1;
-
- /// \brief True if this command is an end command for a verbatim-like block.
- unsigned IsVerbatimBlockEndCommand : 1;
-
- /// \brief True if this command is a verbatim line command.
- ///
- /// A verbatim-like line command eats everything until a newline is seen or
- /// comment end is hit.
- unsigned IsVerbatimLineCommand : 1;
-
- /// \brief True if this command contains a declaration for the entity being
- /// documented.
- ///
- /// For example:
- /// \code
- /// \fn void f(int a);
- /// \endcode
- unsigned IsDeclarationCommand : 1;
-
- /// \brief True if verbatim-like line command is a function declaration.
- unsigned IsFunctionDeclarationCommand : 1;
-
- /// \brief True if block command is further describing a container API; such
- /// as \@coclass, \@classdesign, etc.
- unsigned IsRecordLikeDetailCommand : 1;
-
- /// \brief True if block command is a container API; such as \@interface.
- unsigned IsRecordLikeDeclarationCommand : 1;
-
- /// \brief True if this command is unknown. This \c CommandInfo object was
- /// created during parsing.
- unsigned IsUnknownCommand : 1;
-};
-
-/// This class provides information about commands that can be used
-/// in comments.
-class CommandTraits {
-public:
- enum KnownCommandIDs {
-#define COMMENT_COMMAND(NAME) KCI_##NAME,
-#include "clang/AST/CommentCommandList.inc"
-#undef COMMENT_COMMAND
- KCI_Last
- };
-
- CommandTraits(llvm::BumpPtrAllocator &Allocator,
- const CommentOptions &CommentOptions);
-
- void registerCommentOptions(const CommentOptions &CommentOptions);
-
- /// \returns a CommandInfo object for a given command name or
- /// NULL if no CommandInfo object exists for this command.
- const CommandInfo *getCommandInfoOrNULL(StringRef Name) const;
-
- const CommandInfo *getCommandInfo(StringRef Name) const {
- if (const CommandInfo *Info = getCommandInfoOrNULL(Name))
- return Info;
- llvm_unreachable("the command should be known");
- }
-
- const CommandInfo *getTypoCorrectCommandInfo(StringRef Typo) const;
-
- const CommandInfo *getCommandInfo(unsigned CommandID) const;
-
- const CommandInfo *registerUnknownCommand(StringRef CommandName);
-
- const CommandInfo *registerBlockCommand(StringRef CommandName);
-
- /// \returns a CommandInfo object for a given command name or
- /// NULL if \c Name is not a builtin command.
- static const CommandInfo *getBuiltinCommandInfo(StringRef Name);
-
- /// \returns a CommandInfo object for a given command ID or
- /// NULL if \c CommandID is not a builtin command.
- static const CommandInfo *getBuiltinCommandInfo(unsigned CommandID);
-
-private:
- CommandTraits(const CommandTraits &) = delete;
- void operator=(const CommandTraits &) = delete;
-
- const CommandInfo *getRegisteredCommandInfo(StringRef Name) const;
- const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const;
-
- CommandInfo *createCommandInfoWithName(StringRef CommandName);
-
- unsigned NextID;
-
- /// Allocator for CommandInfo objects.
- llvm::BumpPtrAllocator &Allocator;
-
- SmallVector<CommandInfo *, 4> RegisteredCommands;
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
deleted file mode 100644
index 958ee03..0000000
--- a/include/clang/AST/CommentCommands.td
+++ /dev/null
@@ -1,241 +0,0 @@
-//===----------------------------------------------------------------------===//
-// Define command classes.
-//===----------------------------------------------------------------------===//
-
-class Command<string name> {
- string Name = name;
- string EndCommandName = "";
-
- int NumArgs = 0;
-
- bit IsInlineCommand = 0;
-
- bit IsBlockCommand = 0;
- bit IsBriefCommand = 0;
- bit IsReturnsCommand = 0;
- bit IsParamCommand = 0;
- bit IsTParamCommand = 0;
- bit IsThrowsCommand = 0;
- bit IsDeprecatedCommand = 0;
- bit IsHeaderfileCommand = 0;
-
- bit IsEmptyParagraphAllowed = 0;
-
- bit IsVerbatimBlockCommand = 0;
- bit IsVerbatimBlockEndCommand = 0;
- bit IsVerbatimLineCommand = 0;
- bit IsDeclarationCommand = 0;
- bit IsFunctionDeclarationCommand = 0;
- bit IsRecordLikeDetailCommand = 0;
- bit IsRecordLikeDeclarationCommand = 0;
-}
-
-class InlineCommand<string name> : Command<name> {
- let IsInlineCommand = 1;
-}
-
-class BlockCommand<string name> : Command<name> {
- let IsBlockCommand = 1;
-}
-
-class RecordLikeDetailCommand<string name> : BlockCommand<name> {
- let IsRecordLikeDetailCommand = 1;
-}
-
-class VerbatimBlockCommand<string name> : Command<name> {
- let EndCommandName = name;
- let IsVerbatimBlockCommand = 1;
-}
-
-multiclass VerbatimBlockCommand<string name, string endCommandName> {
- def Begin : Command<name> {
- let EndCommandName = endCommandName;
- let IsVerbatimBlockCommand = 1;
- }
-
- def End : Command<endCommandName> {
- let IsVerbatimBlockEndCommand = 1;
- }
-}
-
-class VerbatimLineCommand<string name> : Command<name> {
- let IsVerbatimLineCommand = 1;
-}
-
-class DeclarationVerbatimLineCommand<string name> :
- VerbatimLineCommand<name> {
- let IsDeclarationCommand = 1;
-}
-
-class FunctionDeclarationVerbatimLineCommand<string name> :
- DeclarationVerbatimLineCommand<name> {
- let IsFunctionDeclarationCommand = 1;
-}
-
-class RecordLikeDeclarationVerbatimLineCommand<string name> :
- DeclarationVerbatimLineCommand<name> {
- let IsRecordLikeDeclarationCommand = 1;
-}
-
-//===----------------------------------------------------------------------===//
-// InlineCommand
-//===----------------------------------------------------------------------===//
-
-def B : InlineCommand<"b">;
-def C : InlineCommand<"c">;
-def P : InlineCommand<"p">;
-def A : InlineCommand<"a">;
-def E : InlineCommand<"e">;
-def Em : InlineCommand<"em">;
-
-//===----------------------------------------------------------------------===//
-// BlockCommand
-//===----------------------------------------------------------------------===//
-
-def Brief : BlockCommand<"brief"> { let IsBriefCommand = 1; }
-def Short : BlockCommand<"short"> { let IsBriefCommand = 1; }
-
-// Opposite of \brief, it is the default in our implementation.
-def Details : BlockCommand<"details">;
-
-def Returns : BlockCommand<"returns"> { let IsReturnsCommand = 1; }
-def Return : BlockCommand<"return"> { let IsReturnsCommand = 1; }
-def Result : BlockCommand<"result"> { let IsReturnsCommand = 1; }
-
-def Param : BlockCommand<"param"> { let IsParamCommand = 1; }
-
-// Doxygen command for template parameter documentation.
-def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; }
-
-// HeaderDoc command for template parameter documentation.
-def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }
-
-def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; }
-def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; }
-def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; }
-
-def Deprecated : BlockCommand<"deprecated"> {
- let IsEmptyParagraphAllowed = 1;
- let IsDeprecatedCommand = 1;
-}
-
-def Headerfile : BlockCommand<"headerfile"> { let IsHeaderfileCommand = 1; }
-
-// We don't do any additional semantic analysis for the following
-// BlockCommands. It might be a good idea to do something extra for them, but
-// for now we model them as plain BlockCommands.
-def Arg : BlockCommand<"arg">;
-def Attention : BlockCommand<"attention">;
-def Author : BlockCommand<"author">;
-def Authors : BlockCommand<"authors">;
-def Bug : BlockCommand<"bug">;
-def Copyright : BlockCommand<"copyright">;
-def Date : BlockCommand<"date">;
-def Invariant : BlockCommand<"invariant">;
-def Li : BlockCommand<"li">;
-def Note : BlockCommand<"note">;
-def Par : BlockCommand<"par">;
-def Post : BlockCommand<"post">;
-def Pre : BlockCommand<"pre">;
-def Remark : BlockCommand<"remark">;
-def Remarks : BlockCommand<"remarks">;
-def Sa : BlockCommand<"sa">;
-def See : BlockCommand<"see">;
-def Since : BlockCommand<"since">;
-def Todo : BlockCommand<"todo">;
-def Version : BlockCommand<"version">;
-def Warning : BlockCommand<"warning">;
-// HeaderDoc commands
-def Abstract : BlockCommand<"abstract"> { let IsBriefCommand = 1; }
-def ClassDesign : RecordLikeDetailCommand<"classdesign">;
-def CoClass : RecordLikeDetailCommand<"coclass">;
-def Dependency : RecordLikeDetailCommand<"dependency">;
-def Discussion : BlockCommand<"discussion">;
-def Helper : RecordLikeDetailCommand<"helper">;
-def HelperClass : RecordLikeDetailCommand<"helperclass">;
-def Helps : RecordLikeDetailCommand<"helps">;
-def InstanceSize : RecordLikeDetailCommand<"instancesize">;
-def Ownership : RecordLikeDetailCommand<"ownership">;
-def Performance : RecordLikeDetailCommand<"performance">;
-def Security : RecordLikeDetailCommand<"security">;
-def SeeAlso : BlockCommand<"seealso">;
-def SuperClass : RecordLikeDetailCommand<"superclass">;
-
-//===----------------------------------------------------------------------===//
-// VerbatimBlockCommand
-//===----------------------------------------------------------------------===//
-
-defm Code : VerbatimBlockCommand<"code", "endcode">;
-defm Verbatim : VerbatimBlockCommand<"verbatim", "endverbatim">;
-defm Htmlonly : VerbatimBlockCommand<"htmlonly", "endhtmlonly">;
-defm Latexonly : VerbatimBlockCommand<"latexonly", "endlatexonly">;
-defm Xmlonly : VerbatimBlockCommand<"xmlonly", "endxmlonly">;
-defm Manonly : VerbatimBlockCommand<"manonly", "endmanonly">;
-defm Rtfonly : VerbatimBlockCommand<"rtfonly", "endrtfonly">;
-
-defm Dot : VerbatimBlockCommand<"dot", "enddot">;
-defm Msc : VerbatimBlockCommand<"msc", "endmsc">;
-
-// These three commands have special support in CommentLexer to recognize their
-// names.
-def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula
-defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula
-defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment
-
-// HeaderDoc commands
-defm Textblock : VerbatimBlockCommand<"textblock", "/textblock">;
-defm Link : VerbatimBlockCommand<"link", "/link">;
-
-//===----------------------------------------------------------------------===//
-// VerbatimLineCommand
-//===----------------------------------------------------------------------===//
-
-def Defgroup : VerbatimLineCommand<"defgroup">;
-def Ingroup : VerbatimLineCommand<"ingroup">;
-def Addtogroup : VerbatimLineCommand<"addtogroup">;
-def Weakgroup : VerbatimLineCommand<"weakgroup">;
-def Name : VerbatimLineCommand<"name">;
-
-def Section : VerbatimLineCommand<"section">;
-def Subsection : VerbatimLineCommand<"subsection">;
-def Subsubsection : VerbatimLineCommand<"subsubsection">;
-def Paragraph : VerbatimLineCommand<"paragraph">;
-
-def Mainpage : VerbatimLineCommand<"mainpage">;
-def Subpage : VerbatimLineCommand<"subpage">;
-def Ref : VerbatimLineCommand<"ref">;
-
-def Relates : VerbatimLineCommand<"relates">;
-def Related : VerbatimLineCommand<"related">;
-def RelatesAlso : VerbatimLineCommand<"relatesalso">;
-def RelatedAlso : VerbatimLineCommand<"relatedalso">;
-
-//===----------------------------------------------------------------------===//
-// DeclarationVerbatimLineCommand
-//===----------------------------------------------------------------------===//
-
-// Doxygen commands.
-def Def : DeclarationVerbatimLineCommand<"def">;
-def Fn : DeclarationVerbatimLineCommand<"fn">;
-def Namespace : DeclarationVerbatimLineCommand<"namespace">;
-def Overload : DeclarationVerbatimLineCommand<"overload">;
-def Property : DeclarationVerbatimLineCommand<"property">;
-def Typedef : DeclarationVerbatimLineCommand<"typedef">;
-def Var : DeclarationVerbatimLineCommand<"var">;
-
-// HeaderDoc commands.
-def Class : RecordLikeDeclarationVerbatimLineCommand<"class">;
-def Interface : RecordLikeDeclarationVerbatimLineCommand<"interface">;
-def Protocol : RecordLikeDeclarationVerbatimLineCommand<"protocol">;
-def Struct : RecordLikeDeclarationVerbatimLineCommand<"struct">;
-def Union : RecordLikeDeclarationVerbatimLineCommand<"union">;
-def Category : DeclarationVerbatimLineCommand<"category">;
-def Template : DeclarationVerbatimLineCommand<"template">;
-def Function : FunctionDeclarationVerbatimLineCommand<"function">;
-def FunctionGroup : FunctionDeclarationVerbatimLineCommand<"functiongroup">;
-def Method : FunctionDeclarationVerbatimLineCommand<"method">;
-def MethodGroup : FunctionDeclarationVerbatimLineCommand<"methodgroup">;
-def Callback : FunctionDeclarationVerbatimLineCommand<"callback">;
-def Const : DeclarationVerbatimLineCommand<"const">;
-def Constant : DeclarationVerbatimLineCommand<"constant">;
-def Enum : DeclarationVerbatimLineCommand<"enum">;
diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h
deleted file mode 100644
index f3a209b..0000000
--- a/include/clang/AST/CommentDiagnostic.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===--- CommentDiagnostic.h - Diagnostics for the AST library --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
-#define LLVM_CLANG_AST_COMMENTDIAGNOSTIC_H
-
-#include "clang/Basic/Diagnostic.h"
-
-namespace clang {
- namespace diag {
- enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
-#define COMMENTSTART
-#include "clang/Basic/DiagnosticCommentKinds.inc"
-#undef DIAG
- NUM_BUILTIN_COMMENT_DIAGNOSTICS
- };
- } // end namespace diag
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentHTMLNamedCharacterReferences.td b/include/clang/AST/CommentHTMLNamedCharacterReferences.td
deleted file mode 100644
index 4493108..0000000
--- a/include/clang/AST/CommentHTMLNamedCharacterReferences.td
+++ /dev/null
@@ -1,177 +0,0 @@
-// HTML Named Character Reference
-class NCR<string spelling, int codePoint> {
- string Spelling = spelling;
- int CodePoint = codePoint;
-}
-
-// The list below includes named character references supported by Doxygen:
-// http://www.stack.nl/~dimitri/doxygen/manual/htmlcmds.html
-//
-// It does not include all HTML 5 named character references.
-//
-// Corresponding code point values can be found here:
-// http://www.w3.org/TR/2011/WD-html5-20110113/named-character-references.html
-
-def : NCR<"copy", 0x000A9>;
-def : NCR<"COPY", 0x000A9>;
-def : NCR<"trade", 0x02122>;
-def : NCR<"TRADE", 0x02122>;
-def : NCR<"reg", 0x000AE>;
-def : NCR<"REG", 0x000AE>;
-def : NCR<"lt", 0x0003C>;
-def : NCR<"Lt", 0x0003C>;
-def : NCR<"LT", 0x0003C>;
-def : NCR<"gt", 0x0003E>;
-def : NCR<"Gt", 0x0003E>;
-def : NCR<"GT", 0x0003E>;
-def : NCR<"amp", 0x00026>;
-def : NCR<"AMP", 0x00026>;
-def : NCR<"apos", 0x00027>;
-def : NCR<"quot", 0x00022>;
-def : NCR<"QUOT", 0x00022>;
-def : NCR<"lsquo", 0x02018>;
-def : NCR<"rsquo", 0x02019>;
-def : NCR<"ldquo", 0x0201C>;
-def : NCR<"rdquo", 0x0201D>;
-def : NCR<"ndash", 0x02013>;
-def : NCR<"mdash", 0x02014>;
-
-def : NCR<"Auml", 0x000C4>;
-def : NCR<"Euml", 0x000CB>;
-def : NCR<"Iuml", 0x000CF>;
-def : NCR<"Ouml", 0x000D6>;
-def : NCR<"Uuml", 0x000DC>;
-def : NCR<"Yuml", 0x00178>;
-def : NCR<"auml", 0x000E4>;
-def : NCR<"euml", 0x000EB>;
-def : NCR<"iuml", 0x000EF>;
-def : NCR<"ouml", 0x000F6>;
-def : NCR<"uuml", 0x000FC>;
-def : NCR<"yuml", 0x000FF>;
-
-def : NCR<"Aacute", 0x000C1>;
-def : NCR<"Eacute", 0x000C9>;
-def : NCR<"Iacute", 0x000CD>;
-def : NCR<"Oacute", 0x000D3>;
-def : NCR<"Uacute", 0x000DA>;
-def : NCR<"Yacute", 0x000DD>;
-def : NCR<"aacute", 0x000E1>;
-def : NCR<"eacute", 0x000E9>;
-def : NCR<"iacute", 0x000ED>;
-def : NCR<"oacute", 0x000F3>;
-def : NCR<"uacute", 0x000FA>;
-def : NCR<"yacute", 0x000FD>;
-
-def : NCR<"Agrave", 0x000C0>;
-def : NCR<"Egrave", 0x000C8>;
-def : NCR<"Igrave", 0x000CC>;
-def : NCR<"Ograve", 0x000D2>;
-def : NCR<"Ugrave", 0x000D9>;
-// def : NCR<"Ygrave", 0x01EF2>; // Defined neither in Doxygen, nor in HTML5.
-def : NCR<"agrave", 0x000E0>;
-def : NCR<"egrave", 0x000E8>;
-def : NCR<"igrave", 0x000EC>;
-def : NCR<"ograve", 0x000F2>;
-def : NCR<"ugrave", 0x000F9>;
-def : NCR<"ygrave", 0x01EF3>; // Defined in Doxygen, not defined in HTML5.
-
-def : NCR<"Acirc", 0x000C2>;
-def : NCR<"Ecirc", 0x000CA>;
-def : NCR<"Icirc", 0x000CE>;
-def : NCR<"Ocirc", 0x000D4>;
-def : NCR<"Ucirc", 0x000DB>;
-def : NCR<"Ycirc", 0x00176>; // Not defined in Doxygen, defined in HTML5.
-def : NCR<"acirc", 0x000E2>;
-def : NCR<"ecirc", 0x000EA>;
-def : NCR<"icirc", 0x000EE>;
-def : NCR<"ocirc", 0x000F4>;
-def : NCR<"ucirc", 0x000FB>;
-def : NCR<"ycirc", 0x00177>;
-
-def : NCR<"Atilde", 0x000C3>;
-def : NCR<"Ntilde", 0x000D1>;
-def : NCR<"Otilde", 0x000D5>;
-def : NCR<"atilde", 0x000E3>;
-def : NCR<"ntilde", 0x000F1>;
-def : NCR<"otilde", 0x000F5>;
-
-def : NCR<"szlig", 0x000DF>;
-
-def : NCR<"ccedil", 0x000E7>;
-def : NCR<"Ccedil", 0x000C7>;
-
-def : NCR<"aring", 0x000E5>;
-def : NCR<"Aring", 0x000C5>;
-
-def : NCR<"nbsp", 0x000A0>;
-
-def : NCR<"Gamma", 0x00393>;
-def : NCR<"Delta", 0x00394>;
-def : NCR<"Theta", 0x00398>;
-def : NCR<"Lambda", 0x0039B>;
-def : NCR<"Xi", 0x0039E>;
-def : NCR<"Pi", 0x003A0>;
-def : NCR<"Sigma", 0x003A3>;
-def : NCR<"Upsilon", 0x003A5>;
-def : NCR<"Phi", 0x003A6>;
-def : NCR<"Psi", 0x003A8>;
-def : NCR<"Omega", 0x003A9>;
-
-def : NCR<"alpha", 0x003B1>;
-def : NCR<"beta", 0x003B2>;
-def : NCR<"gamma", 0x003B3>;
-def : NCR<"delta", 0x003B4>;
-def : NCR<"epsilon", 0x003B5>;
-def : NCR<"zeta", 0x003B6>;
-def : NCR<"eta", 0x003B7>;
-def : NCR<"theta", 0x003B8>;
-def : NCR<"iota", 0x003B9>;
-def : NCR<"kappa", 0x003BA>;
-def : NCR<"lambda", 0x003BB>;
-def : NCR<"mu", 0x003BC>;
-def : NCR<"nu", 0x003BD>;
-def : NCR<"xi", 0x003BE>;
-def : NCR<"pi", 0x003C0>;
-def : NCR<"rho", 0x003C1>;
-def : NCR<"sigma", 0x003C3>;
-def : NCR<"tau", 0x003C4>;
-def : NCR<"upsilon", 0x003C5>;
-def : NCR<"phi", 0x003C6>;
-def : NCR<"chi", 0x003C7>;
-def : NCR<"psi", 0x003C8>;
-def : NCR<"omega", 0x003C9>;
-def : NCR<"sigmaf", 0x003C2>;
-
-def : NCR<"sect", 0x000A7>;
-def : NCR<"deg", 0x000B0>;
-def : NCR<"prime", 0x02032>;
-def : NCR<"Prime", 0x02033>;
-def : NCR<"infin", 0x0221E>;
-def : NCR<"empty", 0x02205>;
-def : NCR<"plusmn", 0x000B1>;
-def : NCR<"times", 0x000D7>;
-def : NCR<"minus", 0x02212>;
-def : NCR<"sdot", 0x022C5>;
-def : NCR<"part", 0x02202>;
-def : NCR<"nabla", 0x02207>;
-def : NCR<"radic", 0x0221A>;
-def : NCR<"perp", 0x022A5>;
-def : NCR<"sum", 0x02211>;
-def : NCR<"int", 0x0222B>;
-def : NCR<"prod", 0x0220F>;
-def : NCR<"sim", 0x0223C>;
-def : NCR<"asymp", 0x02248>;
-def : NCR<"ne", 0x02260>;
-def : NCR<"equiv", 0x02261>;
-def : NCR<"prop", 0x0221D>;
-def : NCR<"le", 0x02264>;
-def : NCR<"ge", 0x02265>;
-def : NCR<"larr", 0x02190>;
-def : NCR<"rarr", 0x02192>;
-def : NCR<"isin", 0x02208>;
-def : NCR<"notin", 0x02209>;
-def : NCR<"lceil", 0x02308>;
-def : NCR<"rceil", 0x02309>;
-def : NCR<"lfloor", 0x0230A>;
-def : NCR<"rfloor", 0x0230B>;
-
diff --git a/include/clang/AST/CommentHTMLTags.td b/include/clang/AST/CommentHTMLTags.td
deleted file mode 100644
index 2514900..0000000
--- a/include/clang/AST/CommentHTMLTags.td
+++ /dev/null
@@ -1,67 +0,0 @@
-class Tag<string spelling> {
- string Spelling = spelling;
- bit EndTagOptional = 0;
- bit EndTagForbidden = 0;
-}
-
-def Em : Tag<"em">;
-def Strong : Tag<"strong">;
-def Tt : Tag<"tt">;
-def I : Tag<"i">;
-def B : Tag<"b">;
-def Big : Tag<"big">;
-def Small : Tag<"small">;
-def Strike : Tag<"strike">;
-def S : Tag<"s">;
-def U : Tag<"u">;
-def Font : Tag<"font">;
-def A : Tag<"a">;
-def Hr : Tag<"hr"> { let EndTagForbidden = 1; }
-def Div : Tag<"div">;
-def Span : Tag<"span">;
-def H1 : Tag<"h1">;
-def H2 : Tag<"h2">;
-def H3 : Tag<"h3">;
-def H4 : Tag<"h4">;
-def H5 : Tag<"h5">;
-def H6 : Tag<"h6">;
-def Code : Tag<"code">;
-def Blockquote : Tag<"blockquote">;
-def Sub : Tag<"sub">;
-def Sup : Tag<"sup">;
-def Img : Tag<"img"> { let EndTagForbidden = 1; }
-def P : Tag<"p"> { let EndTagOptional = 1; }
-def Br : Tag<"br"> { let EndTagForbidden = 1; }
-def Pre : Tag<"pre">;
-def Ins : Tag<"ins">;
-def Del : Tag<"del">;
-def Ul : Tag<"ul">;
-def Ol : Tag<"ol">;
-def Li : Tag<"li"> { let EndTagOptional = 1; }
-def Dl : Tag<"dl">;
-def Dt : Tag<"dt"> { let EndTagOptional = 1; }
-def Dd : Tag<"dd"> { let EndTagOptional = 1; }
-def Table : Tag<"table">;
-def Caption : Tag<"caption">;
-def Thead : Tag<"thead"> { let EndTagOptional = 1; }
-def Tfoot : Tag<"tfoot"> { let EndTagOptional = 1; }
-def Tbody : Tag<"tbody"> { let EndTagOptional = 1; }
-def Colgroup : Tag<"colgroup"> { let EndTagOptional = 1; }
-def Col : Tag<"col"> { let EndTagForbidden = 1; }
-def Tr : Tag<"tr"> { let EndTagOptional = 1; }
-def Th : Tag<"th"> { let EndTagOptional = 1; }
-def Td : Tag<"td"> { let EndTagOptional = 1; }
-
-// Define a blacklist of attributes that are not safe to pass through to HTML
-// output if the input is untrusted.
-//
-// FIXME: this should be a whitelist. When changing this to a whitelist, don't
-// forget to change the default in the TableGen backend.
-class Attribute<string spelling> {
- string Spelling = spelling;
- bit IsSafeToPassThrough = 1;
-}
-class EventHandlerContentAttribute<string spelling> : Attribute<spelling> {
- let IsSafeToPassThrough = 0;
-}
-
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
deleted file mode 100644
index f190b93..0000000
--- a/include/clang/AST/CommentLexer.h
+++ /dev/null
@@ -1,362 +0,0 @@
-//===--- CommentLexer.h - Lexer for structured comments ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines lexer for structured comments and supporting token class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENTLEXER_H
-#define LLVM_CLANG_AST_COMMENTLEXER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
-namespace comments {
-
-class Lexer;
-class TextTokenRetokenizer;
-struct CommandInfo;
-class CommandTraits;
-
-namespace tok {
-enum TokenKind {
- eof,
- newline,
- text,
- unknown_command, // Command that does not have an ID.
- backslash_command, // Command with an ID, that used backslash marker.
- at_command, // Command with an ID, that used 'at' marker.
- verbatim_block_begin,
- verbatim_block_line,
- verbatim_block_end,
- verbatim_line_name,
- verbatim_line_text,
- html_start_tag, // <tag
- html_ident, // attr
- html_equals, // =
- html_quoted_string, // "blah\"blah" or 'blah\'blah'
- html_greater, // >
- html_slash_greater, // />
- html_end_tag // </tag
-};
-} // end namespace tok
-
-/// \brief Comment token.
-class Token {
- friend class Lexer;
- friend class TextTokenRetokenizer;
-
- /// The location of the token.
- SourceLocation Loc;
-
- /// The actual kind of the token.
- tok::TokenKind Kind;
-
- /// Length of the token spelling in comment. Can be 0 for synthenized
- /// tokens.
- unsigned Length;
-
- /// Contains text value associated with a token.
- const char *TextPtr;
-
- /// Integer value associated with a token.
- ///
- /// If the token is a konwn command, contains command ID and TextPtr is
- /// unused (command spelling can be found with CommandTraits). Otherwise,
- /// contains the length of the string that starts at TextPtr.
- unsigned IntVal;
-
-public:
- SourceLocation getLocation() const LLVM_READONLY { return Loc; }
- void setLocation(SourceLocation SL) { Loc = SL; }
-
- SourceLocation getEndLocation() const LLVM_READONLY {
- if (Length == 0 || Length == 1)
- return Loc;
- return Loc.getLocWithOffset(Length - 1);
- }
-
- tok::TokenKind getKind() const LLVM_READONLY { return Kind; }
- void setKind(tok::TokenKind K) { Kind = K; }
-
- bool is(tok::TokenKind K) const LLVM_READONLY { return Kind == K; }
- bool isNot(tok::TokenKind K) const LLVM_READONLY { return Kind != K; }
-
- unsigned getLength() const LLVM_READONLY { return Length; }
- void setLength(unsigned L) { Length = L; }
-
- StringRef getText() const LLVM_READONLY {
- assert(is(tok::text));
- return StringRef(TextPtr, IntVal);
- }
-
- void setText(StringRef Text) {
- assert(is(tok::text));
- TextPtr = Text.data();
- IntVal = Text.size();
- }
-
- StringRef getUnknownCommandName() const LLVM_READONLY {
- assert(is(tok::unknown_command));
- return StringRef(TextPtr, IntVal);
- }
-
- void setUnknownCommandName(StringRef Name) {
- assert(is(tok::unknown_command));
- TextPtr = Name.data();
- IntVal = Name.size();
- }
-
- unsigned getCommandID() const LLVM_READONLY {
- assert(is(tok::backslash_command) || is(tok::at_command));
- return IntVal;
- }
-
- void setCommandID(unsigned ID) {
- assert(is(tok::backslash_command) || is(tok::at_command));
- IntVal = ID;
- }
-
- unsigned getVerbatimBlockID() const LLVM_READONLY {
- assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
- return IntVal;
- }
-
- void setVerbatimBlockID(unsigned ID) {
- assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
- IntVal = ID;
- }
-
- StringRef getVerbatimBlockText() const LLVM_READONLY {
- assert(is(tok::verbatim_block_line));
- return StringRef(TextPtr, IntVal);
- }
-
- void setVerbatimBlockText(StringRef Text) {
- assert(is(tok::verbatim_block_line));
- TextPtr = Text.data();
- IntVal = Text.size();
- }
-
- unsigned getVerbatimLineID() const LLVM_READONLY {
- assert(is(tok::verbatim_line_name));
- return IntVal;
- }
-
- void setVerbatimLineID(unsigned ID) {
- assert(is(tok::verbatim_line_name));
- IntVal = ID;
- }
-
- StringRef getVerbatimLineText() const LLVM_READONLY {
- assert(is(tok::verbatim_line_text));
- return StringRef(TextPtr, IntVal);
- }
-
- void setVerbatimLineText(StringRef Text) {
- assert(is(tok::verbatim_line_text));
- TextPtr = Text.data();
- IntVal = Text.size();
- }
-
- StringRef getHTMLTagStartName() const LLVM_READONLY {
- assert(is(tok::html_start_tag));
- return StringRef(TextPtr, IntVal);
- }
-
- void setHTMLTagStartName(StringRef Name) {
- assert(is(tok::html_start_tag));
- TextPtr = Name.data();
- IntVal = Name.size();
- }
-
- StringRef getHTMLIdent() const LLVM_READONLY {
- assert(is(tok::html_ident));
- return StringRef(TextPtr, IntVal);
- }
-
- void setHTMLIdent(StringRef Name) {
- assert(is(tok::html_ident));
- TextPtr = Name.data();
- IntVal = Name.size();
- }
-
- StringRef getHTMLQuotedString() const LLVM_READONLY {
- assert(is(tok::html_quoted_string));
- return StringRef(TextPtr, IntVal);
- }
-
- void setHTMLQuotedString(StringRef Str) {
- assert(is(tok::html_quoted_string));
- TextPtr = Str.data();
- IntVal = Str.size();
- }
-
- StringRef getHTMLTagEndName() const LLVM_READONLY {
- assert(is(tok::html_end_tag));
- return StringRef(TextPtr, IntVal);
- }
-
- void setHTMLTagEndName(StringRef Name) {
- assert(is(tok::html_end_tag));
- TextPtr = Name.data();
- IntVal = Name.size();
- }
-
- void dump(const Lexer &L, const SourceManager &SM) const;
-};
-
-/// \brief Comment lexer.
-class Lexer {
-private:
- Lexer(const Lexer &) = delete;
- void operator=(const Lexer &) = delete;
-
- /// Allocator for strings that are semantic values of tokens and have to be
- /// computed (for example, resolved decimal character references).
- llvm::BumpPtrAllocator &Allocator;
-
- DiagnosticsEngine &Diags;
-
- const CommandTraits &Traits;
-
- const char *const BufferStart;
- const char *const BufferEnd;
- SourceLocation FileLoc;
-
- const char *BufferPtr;
-
- /// One past end pointer for the current comment. For BCPL comments points
- /// to newline or BufferEnd, for C comments points to star in '*/'.
- const char *CommentEnd;
-
- enum LexerCommentState {
- LCS_BeforeComment,
- LCS_InsideBCPLComment,
- LCS_InsideCComment,
- LCS_BetweenComments
- };
-
- /// Low-level lexer state, track if we are inside or outside of comment.
- LexerCommentState CommentState;
-
- enum LexerState {
- /// Lexing normal comment text
- LS_Normal,
-
- /// Finished lexing verbatim block beginning command, will lex first body
- /// line.
- LS_VerbatimBlockFirstLine,
-
- /// Lexing verbatim block body line-by-line, skipping line-starting
- /// decorations.
- LS_VerbatimBlockBody,
-
- /// Finished lexing verbatim line beginning command, will lex text (one
- /// line).
- LS_VerbatimLineText,
-
- /// Finished lexing \verbatim <TAG \endverbatim part, lexing tag attributes.
- LS_HTMLStartTag,
-
- /// Finished lexing \verbatim </TAG \endverbatim part, lexing '>'.
- LS_HTMLEndTag
- };
-
- /// Current lexing mode.
- LexerState State;
-
- /// If State is LS_VerbatimBlock, contains the name of verbatim end
- /// command, including command marker.
- SmallString<16> VerbatimBlockEndCommandName;
-
- /// Given a character reference name (e.g., "lt"), return the character that
- /// it stands for (e.g., "<").
- StringRef resolveHTMLNamedCharacterReference(StringRef Name) const;
-
- /// Given a Unicode codepoint as base-10 integer, return the character.
- StringRef resolveHTMLDecimalCharacterReference(StringRef Name) const;
-
- /// Given a Unicode codepoint as base-16 integer, return the character.
- StringRef resolveHTMLHexCharacterReference(StringRef Name) const;
-
- void formTokenWithChars(Token &Result, const char *TokEnd,
- tok::TokenKind Kind);
-
- void formTextToken(Token &Result, const char *TokEnd) {
- StringRef Text(BufferPtr, TokEnd - BufferPtr);
- formTokenWithChars(Result, TokEnd, tok::text);
- Result.setText(Text);
- }
-
- SourceLocation getSourceLocation(const char *Loc) const {
- assert(Loc >= BufferStart && Loc <= BufferEnd &&
- "Location out of range for this buffer!");
-
- const unsigned CharNo = Loc - BufferStart;
- return FileLoc.getLocWithOffset(CharNo);
- }
-
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
- return Diags.Report(Loc, DiagID);
- }
-
- /// Eat string matching regexp \code \s*\* \endcode.
- void skipLineStartingDecorations();
-
- /// Lex stuff inside comments. CommentEnd should be set correctly.
- void lexCommentText(Token &T);
-
- void setupAndLexVerbatimBlock(Token &T,
- const char *TextBegin,
- char Marker, const CommandInfo *Info);
-
- void lexVerbatimBlockFirstLine(Token &T);
-
- void lexVerbatimBlockBody(Token &T);
-
- void setupAndLexVerbatimLine(Token &T, const char *TextBegin,
- const CommandInfo *Info);
-
- void lexVerbatimLineText(Token &T);
-
- void lexHTMLCharacterReference(Token &T);
-
- void setupAndLexHTMLStartTag(Token &T);
-
- void lexHTMLStartTag(Token &T);
-
- void setupAndLexHTMLEndTag(Token &T);
-
- void lexHTMLEndTag(Token &T);
-
-public:
- Lexer(llvm::BumpPtrAllocator &Allocator, DiagnosticsEngine &Diags,
- const CommandTraits &Traits,
- SourceLocation FileLoc,
- const char *BufferStart, const char *BufferEnd);
-
- void lex(Token &T);
-
- StringRef getSpelling(const Token &Tok,
- const SourceManager &SourceMgr,
- bool *Invalid = nullptr) const;
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
deleted file mode 100644
index fa88628..0000000
--- a/include/clang/AST/CommentParser.h
+++ /dev/null
@@ -1,123 +0,0 @@
-//===--- CommentParser.h - Doxygen comment parser ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Doxygen comment parser.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENTPARSER_H
-#define LLVM_CLANG_AST_COMMENTPARSER_H
-
-#include "clang/AST/Comment.h"
-#include "clang/AST/CommentLexer.h"
-#include "clang/AST/CommentSema.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/Support/Allocator.h"
-
-namespace clang {
-class SourceManager;
-
-namespace comments {
-class CommandTraits;
-
-/// Doxygen comment parser.
-class Parser {
- Parser(const Parser &) = delete;
- void operator=(const Parser &) = delete;
-
- friend class TextTokenRetokenizer;
-
- Lexer &L;
-
- Sema &S;
-
- /// Allocator for anything that goes into AST nodes.
- llvm::BumpPtrAllocator &Allocator;
-
- /// Source manager for the comment being parsed.
- const SourceManager &SourceMgr;
-
- DiagnosticsEngine &Diags;
-
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
- return Diags.Report(Loc, DiagID);
- }
-
- const CommandTraits &Traits;
-
- /// Current lookahead token. We can safely assume that all tokens are from
- /// a single source file.
- Token Tok;
-
- /// A stack of additional lookahead tokens.
- SmallVector<Token, 8> MoreLATokens;
-
- void consumeToken() {
- if (MoreLATokens.empty())
- L.lex(Tok);
- else
- Tok = MoreLATokens.pop_back_val();
- }
-
- void putBack(const Token &OldTok) {
- MoreLATokens.push_back(Tok);
- Tok = OldTok;
- }
-
- void putBack(ArrayRef<Token> Toks) {
- if (Toks.empty())
- return;
-
- MoreLATokens.push_back(Tok);
- MoreLATokens.append(Toks.rbegin(), std::prev(Toks.rend()));
-
- Tok = Toks[0];
- }
-
- bool isTokBlockCommand() {
- return (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) &&
- Traits.getCommandInfo(Tok.getCommandID())->IsBlockCommand;
- }
-
-public:
- Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator,
- const SourceManager &SourceMgr, DiagnosticsEngine &Diags,
- const CommandTraits &Traits);
-
- /// Parse arguments for \\param command.
- void parseParamCommandArgs(ParamCommandComment *PC,
- TextTokenRetokenizer &Retokenizer);
-
- /// Parse arguments for \\tparam command.
- void parseTParamCommandArgs(TParamCommandComment *TPC,
- TextTokenRetokenizer &Retokenizer);
-
- void parseBlockCommandArgs(BlockCommandComment *BC,
- TextTokenRetokenizer &Retokenizer,
- unsigned NumArgs);
-
- BlockCommandComment *parseBlockCommand();
- InlineCommandComment *parseInlineCommand();
-
- HTMLStartTagComment *parseHTMLStartTag();
- HTMLEndTagComment *parseHTMLEndTag();
-
- BlockContentComment *parseParagraphOrBlockCommand();
-
- VerbatimBlockComment *parseVerbatimBlock();
- VerbatimLineComment *parseVerbatimLine();
- BlockContentComment *parseBlockContent();
- FullComment *parseFullComment();
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
deleted file mode 100644
index 6a80383..0000000
--- a/include/clang/AST/CommentSema.h
+++ /dev/null
@@ -1,254 +0,0 @@
-//===--- CommentSema.h - Doxygen comment semantic analysis ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the semantic analysis class for Doxygen comments.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENTSEMA_H
-#define LLVM_CLANG_AST_COMMENTSEMA_H
-
-#include "clang/AST/Comment.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-
-namespace clang {
-class Decl;
-class SourceMgr;
-class Preprocessor;
-
-namespace comments {
-class CommandTraits;
-
-class Sema {
- Sema(const Sema &) = delete;
- void operator=(const Sema &) = delete;
-
- /// Allocator for AST nodes.
- llvm::BumpPtrAllocator &Allocator;
-
- /// Source manager for the comment being parsed.
- const SourceManager &SourceMgr;
-
- DiagnosticsEngine &Diags;
-
- CommandTraits &Traits;
-
- const Preprocessor *PP;
-
- /// Information about the declaration this comment is attached to.
- DeclInfo *ThisDeclInfo;
-
- /// Comment AST nodes that correspond to parameter names in
- /// \c TemplateParameters.
- ///
- /// Contains a valid value if \c DeclInfo->IsFilled is true.
- llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
-
- /// AST node for the \\brief command and its aliases.
- const BlockCommandComment *BriefCommand;
-
- /// AST node for the \\headerfile command.
- const BlockCommandComment *HeaderfileCommand;
-
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
- return Diags.Report(Loc, DiagID);
- }
-
- /// A stack of HTML tags that are currently open (not matched with closing
- /// tags).
- SmallVector<HTMLStartTagComment *, 8> HTMLOpenTags;
-
-public:
- Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
- DiagnosticsEngine &Diags, CommandTraits &Traits,
- const Preprocessor *PP);
-
- void setDecl(const Decl *D);
-
- /// Returns a copy of array, owned by Sema's allocator.
- template<typename T>
- ArrayRef<T> copyArray(ArrayRef<T> Source) {
- if (!Source.empty())
- return Source.copy(Allocator);
- return None;
- }
-
- ParagraphComment *actOnParagraphComment(
- ArrayRef<InlineContentComment *> Content);
-
- BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker);
-
- void actOnBlockCommandArgs(BlockCommandComment *Command,
- ArrayRef<BlockCommandComment::Argument> Args);
-
- void actOnBlockCommandFinish(BlockCommandComment *Command,
- ParagraphComment *Paragraph);
-
- ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker);
-
- void actOnParamCommandDirectionArg(ParamCommandComment *Command,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
-
- void actOnParamCommandParamNameArg(ParamCommandComment *Command,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
-
- void actOnParamCommandFinish(ParamCommandComment *Command,
- ParagraphComment *Paragraph);
-
- TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker);
-
- void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
-
- void actOnTParamCommandFinish(TParamCommandComment *Command,
- ParagraphComment *Paragraph);
-
- InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
- SourceLocation CommandLocEnd,
- unsigned CommandID);
-
- InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
- SourceLocation CommandLocEnd,
- unsigned CommandID,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
-
- InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef CommandName);
-
- InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID);
-
- TextComment *actOnText(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef Text);
-
- VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc,
- unsigned CommandID);
-
- VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
- StringRef Text);
-
- void actOnVerbatimBlockFinish(VerbatimBlockComment *Block,
- SourceLocation CloseNameLocBegin,
- StringRef CloseName,
- ArrayRef<VerbatimBlockLineComment *> Lines);
-
- VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
- unsigned CommandID,
- SourceLocation TextBegin,
- StringRef Text);
-
- HTMLStartTagComment *actOnHTMLStartTagStart(SourceLocation LocBegin,
- StringRef TagName);
-
- void actOnHTMLStartTagFinish(HTMLStartTagComment *Tag,
- ArrayRef<HTMLStartTagComment::Attribute> Attrs,
- SourceLocation GreaterLoc,
- bool IsSelfClosing);
-
- HTMLEndTagComment *actOnHTMLEndTag(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef TagName);
-
- FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks);
-
- void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
-
- void checkReturnsCommand(const BlockCommandComment *Command);
-
- /// Emit diagnostics about duplicate block commands that should be
- /// used only once per comment, e.g., \\brief and \\returns.
- void checkBlockCommandDuplicate(const BlockCommandComment *Command);
-
- void checkDeprecatedCommand(const BlockCommandComment *Comment);
-
- void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment);
-
- void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment);
-
- void checkContainerDecl(const BlockCommandComment *Comment);
-
- /// Resolve parameter names to parameter indexes in function declaration.
- /// Emit diagnostics about unknown parametrs.
- void resolveParamCommandIndexes(const FullComment *FC);
-
- bool isFunctionDecl();
- bool isAnyFunctionDecl();
-
- /// \returns \c true if declaration that this comment is attached to declares
- /// a function pointer.
- bool isFunctionPointerVarDecl();
- bool isFunctionOrMethodVariadic();
- bool isObjCMethodDecl();
- bool isObjCPropertyDecl();
- bool isTemplateOrSpecialization();
- bool isRecordLikeDecl();
- bool isClassOrStructDecl();
- bool isUnionDecl();
- bool isObjCInterfaceDecl();
- bool isObjCProtocolDecl();
- bool isClassTemplateDecl();
- bool isFunctionTemplateDecl();
-
- ArrayRef<const ParmVarDecl *> getParamVars();
-
- /// Extract all important semantic information from
- /// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members.
- void inspectThisDecl();
-
- /// Returns index of a function parameter with a given name.
- unsigned resolveParmVarReference(StringRef Name,
- ArrayRef<const ParmVarDecl *> ParamVars);
-
- /// Returns index of a function parameter with the name closest to a given
- /// typo.
- unsigned correctTypoInParmVarReference(StringRef Typo,
- ArrayRef<const ParmVarDecl *> ParamVars);
-
- bool resolveTParamReference(StringRef Name,
- const TemplateParameterList *TemplateParameters,
- SmallVectorImpl<unsigned> *Position);
-
- StringRef correctTypoInTParamReference(
- StringRef Typo,
- const TemplateParameterList *TemplateParameters);
-
- InlineCommandComment::RenderKind
- getInlineCommandRenderKind(StringRef Name) const;
-};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
-
diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h
deleted file mode 100644
index 21641bf..0000000
--- a/include/clang/AST/CommentVisitor.h
+++ /dev/null
@@ -1,70 +0,0 @@
-//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_COMMENTVISITOR_H
-#define LLVM_CLANG_AST_COMMENTVISITOR_H
-
-#include "clang/AST/Comment.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
-namespace comments {
-
-template <typename T> struct make_ptr { typedef T *type; };
-template <typename T> struct make_const_ptr { typedef const T *type; };
-
-template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
-class CommentVisitorBase {
-public:
-#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->visit ## NAME(static_cast<PTR(CLASS)>(C))
-
- RetTy visit(PTR(Comment) C) {
- if (!C)
- return RetTy();
-
- switch (C->getCommentKind()) {
- default: llvm_unreachable("Unknown comment kind!");
-#define ABSTRACT_COMMENT(COMMENT)
-#define COMMENT(CLASS, PARENT) \
- case Comment::CLASS##Kind: DISPATCH(CLASS, CLASS);
-#include "clang/AST/CommentNodes.inc"
-#undef ABSTRACT_COMMENT
-#undef COMMENT
- }
- }
-
- // If the derived class does not implement a certain Visit* method, fall back
- // on Visit* method for the superclass.
-#define ABSTRACT_COMMENT(COMMENT) COMMENT
-#define COMMENT(CLASS, PARENT) \
- RetTy visit ## CLASS(PTR(CLASS) C) { DISPATCH(PARENT, PARENT); }
-#include "clang/AST/CommentNodes.inc"
-#undef ABSTRACT_COMMENT
-#undef COMMENT
-
- RetTy visitComment(PTR(Comment) C) { return RetTy(); }
-
-#undef PTR
-#undef DISPATCH
-};
-
-template<typename ImplClass, typename RetTy=void>
-class CommentVisitor :
- public CommentVisitorBase<make_ptr, ImplClass, RetTy> {};
-
-template<typename ImplClass, typename RetTy=void>
-class ConstCommentVisitor :
- public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
-
-} // end namespace comments
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
deleted file mode 100644
index 046ce70..0000000
--- a/include/clang/AST/Decl.h
+++ /dev/null
@@ -1,3801 +0,0 @@
-//===--- Decl.h - Classes for representing declarations ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Decl subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECL_H
-#define LLVM_CLANG_AST_DECL_H
-
-#include "clang/AST/APValue.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/Redeclarable.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/Linkage.h"
-#include "clang/Basic/Module.h"
-#include "clang/Basic/OperatorKinds.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/TrailingObjects.h"
-
-namespace clang {
-struct ASTTemplateArgumentListInfo;
-class CXXTemporary;
-class CompoundStmt;
-class DependentFunctionTemplateSpecializationInfo;
-class Expr;
-class FunctionTemplateDecl;
-class FunctionTemplateSpecializationInfo;
-class LabelStmt;
-class MemberSpecializationInfo;
-class NestedNameSpecifier;
-class ParmVarDecl;
-class Stmt;
-class StringLiteral;
-class TemplateArgumentList;
-class TemplateParameterList;
-class TypeAliasTemplateDecl;
-class TypeLoc;
-class UnresolvedSetImpl;
-class VarTemplateDecl;
-
-/// \brief A container of type source information.
-///
-/// A client can read the relevant info using TypeLoc wrappers, e.g:
-/// @code
-/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
-/// TL.getStartLoc().print(OS, SrcMgr);
-/// @endcode
-///
-class TypeSourceInfo {
- QualType Ty;
- // Contains a memory block after the class, used for type source information,
- // allocated by ASTContext.
- friend class ASTContext;
- TypeSourceInfo(QualType ty) : Ty(ty) { }
-public:
- /// \brief Return the type wrapped by this type source info.
- QualType getType() const { return Ty; }
-
- /// \brief Return the TypeLoc wrapper for the type source info.
- TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
-
- /// \brief Override the type stored in this TypeSourceInfo. Use with caution!
- void overrideType(QualType T) { Ty = T; }
-};
-
-/// TranslationUnitDecl - The top declaration context.
-class TranslationUnitDecl : public Decl, public DeclContext {
- virtual void anchor();
- ASTContext &Ctx;
-
- /// The (most recently entered) anonymous namespace for this
- /// translation unit, if one has been created.
- NamespaceDecl *AnonymousNamespace;
-
- explicit TranslationUnitDecl(ASTContext &ctx);
-public:
- ASTContext &getASTContext() const { return Ctx; }
-
- NamespaceDecl *getAnonymousNamespace() const { return AnonymousNamespace; }
- void setAnonymousNamespace(NamespaceDecl *D) { AnonymousNamespace = D; }
-
- static TranslationUnitDecl *Create(ASTContext &C);
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TranslationUnit; }
- static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
- return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
- }
- static TranslationUnitDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<TranslationUnitDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// \brief Declaration context for names declared as extern "C" in C++. This
-/// is neither the semantic nor lexical context for such declarations, but is
-/// used to check for conflicts with other extern "C" declarations. Example:
-///
-/// \code
-/// namespace N { extern "C" void f(); } // #1
-/// void N::f() {} // #2
-/// namespace M { extern "C" void f(); } // #3
-/// \endcode
-///
-/// The semantic context of #1 is namespace N and its lexical context is the
-/// LinkageSpecDecl; the semantic context of #2 is namespace N and its lexical
-/// context is the TU. However, both declarations are also visible in the
-/// extern "C" context.
-///
-/// The declaration at #3 finds it is a redeclaration of \c N::f through
-/// lookup in the extern "C" context.
-class ExternCContextDecl : public Decl, public DeclContext {
- virtual void anchor();
-
- explicit ExternCContextDecl(TranslationUnitDecl *TU)
- : Decl(ExternCContext, TU, SourceLocation()),
- DeclContext(ExternCContext) {}
-public:
- static ExternCContextDecl *Create(const ASTContext &C,
- TranslationUnitDecl *TU);
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ExternCContext; }
- static DeclContext *castToDeclContext(const ExternCContextDecl *D) {
- return static_cast<DeclContext *>(const_cast<ExternCContextDecl*>(D));
- }
- static ExternCContextDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<ExternCContextDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// NamedDecl - This represents a decl with a name. Many decls have names such
-/// as ObjCMethodDecl, but not \@class, etc.
-class NamedDecl : public Decl {
- virtual void anchor();
- /// Name - The name of this declaration, which is typically a normal
- /// identifier but may also be a special kind of name (C++
- /// constructor, Objective-C selector, etc.)
- DeclarationName Name;
-
-private:
- NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY;
-
-protected:
- NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
- : Decl(DK, DC, L), Name(N) { }
-
-public:
- /// getIdentifier - Get the identifier that names this declaration,
- /// if there is one. This will return NULL if this declaration has
- /// no name (e.g., for an unnamed class) or if the name is a special
- /// name (C++ constructor, Objective-C selector, etc.).
- IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
-
- /// getName - Get the name of identifier for this declaration as a StringRef.
- /// This requires that the declaration have a name and that it be a simple
- /// identifier.
- StringRef getName() const {
- assert(Name.isIdentifier() && "Name is not a simple identifier");
- return getIdentifier() ? getIdentifier()->getName() : "";
- }
-
- /// getNameAsString - Get a human-readable name for the declaration, even if
- /// it is one of the special kinds of names (C++ constructor, Objective-C
- /// selector, etc). Creating this name requires expensive string
- /// manipulation, so it should be called only when performance doesn't matter.
- /// For simple declarations, getNameAsCString() should suffice.
- //
- // FIXME: This function should be renamed to indicate that it is not just an
- // alternate form of getName(), and clients should move as appropriate.
- //
- // FIXME: Deprecated, move clients to getName().
- std::string getNameAsString() const { return Name.getAsString(); }
-
- void printName(raw_ostream &os) const { os << Name; }
-
- /// getDeclName - Get the actual, stored name of the declaration,
- /// which may be a special name.
- DeclarationName getDeclName() const { return Name; }
-
- /// \brief Set the name of this declaration.
- void setDeclName(DeclarationName N) { Name = N; }
-
- /// printQualifiedName - Returns human-readable qualified name for
- /// declaration, like A::B::i, for i being member of namespace A::B.
- /// If declaration is not member of context which can be named (record,
- /// namespace), it will return same result as printName().
- /// Creating this name is expensive, so it should be called only when
- /// performance doesn't matter.
- void printQualifiedName(raw_ostream &OS) const;
- void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
-
- // FIXME: Remove string version.
- std::string getQualifiedNameAsString() const;
-
- /// getNameForDiagnostic - Appends a human-readable name for this
- /// declaration into the given stream.
- ///
- /// This is the method invoked by Sema when displaying a NamedDecl
- /// in a diagnostic. It does not necessarily produce the same
- /// result as printName(); for example, class template
- /// specializations are printed with their template arguments.
- virtual void getNameForDiagnostic(raw_ostream &OS,
- const PrintingPolicy &Policy,
- bool Qualified) const;
-
- /// \brief Determine whether this declaration, if
- /// known to be well-formed within its context, will replace the
- /// declaration OldD if introduced into scope. A declaration will
- /// replace another declaration if, for example, it is a
- /// redeclaration of the same variable or function, but not if it is
- /// a declaration of a different kind (function vs. class) or an
- /// overloaded function.
- ///
- /// \param IsKnownNewer \c true if this declaration is known to be newer
- /// than \p OldD (for instance, if this declaration is newly-created).
- bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const;
-
- /// \brief Determine whether this declaration has linkage.
- bool hasLinkage() const;
-
- using Decl::isModulePrivate;
- using Decl::setModulePrivate;
-
- /// \brief Determine whether this declaration is hidden from name lookup.
- bool isHidden() const { return Hidden; }
-
- /// \brief Set whether this declaration is hidden from name lookup.
- void setHidden(bool Hide) {
- assert((!Hide || isFromASTFile() || hasLocalOwningModuleStorage()) &&
- "declaration with no owning module can't be hidden");
- Hidden = Hide;
- }
-
- /// \brief Determine whether this declaration is a C++ class member.
- bool isCXXClassMember() const {
- const DeclContext *DC = getDeclContext();
-
- // C++0x [class.mem]p1:
- // The enumerators of an unscoped enumeration defined in
- // the class are members of the class.
- if (isa<EnumDecl>(DC))
- DC = DC->getRedeclContext();
-
- return DC->isRecord();
- }
-
- /// \brief Determine whether the given declaration is an instance member of
- /// a C++ class.
- bool isCXXInstanceMember() const;
-
- /// \brief Determine what kind of linkage this entity has.
- /// This is not the linkage as defined by the standard or the codegen notion
- /// of linkage. It is just an implementation detail that is used to compute
- /// those.
- Linkage getLinkageInternal() const;
-
- /// \brief Get the linkage from a semantic point of view. Entities in
- /// anonymous namespaces are external (in c++98).
- Linkage getFormalLinkage() const {
- return clang::getFormalLinkage(getLinkageInternal());
- }
-
- /// \brief True if this decl has external linkage.
- bool hasExternalFormalLinkage() const {
- return isExternalFormalLinkage(getLinkageInternal());
- }
-
- bool isExternallyVisible() const {
- return clang::isExternallyVisible(getLinkageInternal());
- }
-
- /// \brief Determines the visibility of this entity.
- Visibility getVisibility() const {
- return getLinkageAndVisibility().getVisibility();
- }
-
- /// \brief Determines the linkage and visibility of this entity.
- LinkageInfo getLinkageAndVisibility() const;
-
- /// Kinds of explicit visibility.
- enum ExplicitVisibilityKind {
- VisibilityForType,
- VisibilityForValue
- };
-
- /// \brief If visibility was explicitly specified for this
- /// declaration, return that visibility.
- Optional<Visibility>
- getExplicitVisibility(ExplicitVisibilityKind kind) const;
-
- /// \brief True if the computed linkage is valid. Used for consistency
- /// checking. Should always return true.
- bool isLinkageValid() const;
-
- /// \brief True if something has required us to compute the linkage
- /// of this declaration.
- ///
- /// Language features which can retroactively change linkage (like a
- /// typedef name for linkage purposes) may need to consider this,
- /// but hopefully only in transitory ways during parsing.
- bool hasLinkageBeenComputed() const {
- return hasCachedLinkage();
- }
-
- /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
- /// the underlying named decl.
- NamedDecl *getUnderlyingDecl() {
- // Fast-path the common case.
- if (this->getKind() != UsingShadow &&
- this->getKind() != ObjCCompatibleAlias &&
- this->getKind() != NamespaceAlias)
- return this;
-
- return getUnderlyingDeclImpl();
- }
- const NamedDecl *getUnderlyingDecl() const {
- return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
- }
-
- NamedDecl *getMostRecentDecl() {
- return cast<NamedDecl>(static_cast<Decl *>(this)->getMostRecentDecl());
- }
- const NamedDecl *getMostRecentDecl() const {
- return const_cast<NamedDecl*>(this)->getMostRecentDecl();
- }
-
- ObjCStringFormatFamily getObjCFStringFormattingFamily() const;
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
- ND.printName(OS);
- return OS;
-}
-
-/// LabelDecl - Represents the declaration of a label. Labels also have a
-/// corresponding LabelStmt, which indicates the position that the label was
-/// defined at. For normal labels, the location of the decl is the same as the
-/// location of the statement. For GNU local labels (__label__), the decl
-/// location is where the __label__ is.
-class LabelDecl : public NamedDecl {
- void anchor() override;
- LabelStmt *TheStmt;
- StringRef MSAsmName;
- bool MSAsmNameResolved;
- /// LocStart - For normal labels, this is the same as the main declaration
- /// label, i.e., the location of the identifier; for GNU local labels,
- /// this is the location of the __label__ keyword.
- SourceLocation LocStart;
-
- LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
- LabelStmt *S, SourceLocation StartL)
- : NamedDecl(Label, DC, IdentL, II),
- TheStmt(S),
- MSAsmNameResolved(false),
- LocStart(StartL) {}
-
-public:
- static LabelDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation IdentL, IdentifierInfo *II);
- static LabelDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation IdentL, IdentifierInfo *II,
- SourceLocation GnuLabelL);
- static LabelDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- LabelStmt *getStmt() const { return TheStmt; }
- void setStmt(LabelStmt *T) { TheStmt = T; }
-
- bool isGnuLocal() const { return LocStart != getLocation(); }
- void setLocStart(SourceLocation L) { LocStart = L; }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(LocStart, getLocation());
- }
-
- bool isMSAsmLabel() const { return MSAsmName.size() != 0; }
- bool isResolvedMSAsmLabel() const { return isMSAsmLabel() && MSAsmNameResolved; }
- void setMSAsmLabel(StringRef Name);
- StringRef getMSAsmLabel() const { return MSAsmName; }
- void setMSAsmLabelResolved() { MSAsmNameResolved = true; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Label; }
-};
-
-/// NamespaceDecl - Represent a C++ namespace.
-class NamespaceDecl : public NamedDecl, public DeclContext,
- public Redeclarable<NamespaceDecl>
-{
- /// LocStart - The starting location of the source range, pointing
- /// to either the namespace or the inline keyword.
- SourceLocation LocStart;
- /// RBraceLoc - The ending location of the source range.
- SourceLocation RBraceLoc;
-
- /// \brief A pointer to either the anonymous namespace that lives just inside
- /// this namespace or to the first namespace in the chain (the latter case
- /// only when this is not the first in the chain), along with a
- /// boolean value indicating whether this is an inline namespace.
- llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline;
-
- NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, NamespaceDecl *PrevDecl);
-
- typedef Redeclarable<NamespaceDecl> redeclarable_base;
- NamespaceDecl *getNextRedeclarationImpl() override;
- NamespaceDecl *getPreviousDeclImpl() override;
- NamespaceDecl *getMostRecentDeclImpl() override;
-
-public:
- static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
- bool Inline, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- NamespaceDecl *PrevDecl);
-
- static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- /// \brief Returns true if this is an anonymous namespace declaration.
- ///
- /// For example:
- /// \code
- /// namespace {
- /// ...
- /// };
- /// \endcode
- /// q.v. C++ [namespace.unnamed]
- bool isAnonymousNamespace() const {
- return !getIdentifier();
- }
-
- /// \brief Returns true if this is an inline namespace declaration.
- bool isInline() const {
- return AnonOrFirstNamespaceAndInline.getInt();
- }
-
- /// \brief Set whether this is an inline namespace declaration.
- void setInline(bool Inline) {
- AnonOrFirstNamespaceAndInline.setInt(Inline);
- }
-
- /// \brief Get the original (first) namespace declaration.
- NamespaceDecl *getOriginalNamespace();
-
- /// \brief Get the original (first) namespace declaration.
- const NamespaceDecl *getOriginalNamespace() const;
-
- /// \brief Return true if this declaration is an original (first) declaration
- /// of the namespace. This is false for non-original (subsequent) namespace
- /// declarations and anonymous namespaces.
- bool isOriginalNamespace() const;
-
- /// \brief Retrieve the anonymous namespace nested inside this namespace,
- /// if any.
- NamespaceDecl *getAnonymousNamespace() const {
- return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer();
- }
-
- void setAnonymousNamespace(NamespaceDecl *D) {
- getOriginalNamespace()->AnonOrFirstNamespaceAndInline.setPointer(D);
- }
-
- /// Retrieves the canonical declaration of this namespace.
- NamespaceDecl *getCanonicalDecl() override {
- return getOriginalNamespace();
- }
- const NamespaceDecl *getCanonicalDecl() const {
- return getOriginalNamespace();
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(LocStart, RBraceLoc);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
- SourceLocation getRBraceLoc() const { return RBraceLoc; }
- void setLocStart(SourceLocation L) { LocStart = L; }
- void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Namespace; }
- static DeclContext *castToDeclContext(const NamespaceDecl *D) {
- return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
- }
- static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// ValueDecl - Represent the declaration of a variable (in which case it is
-/// an lvalue) a function (in which case it is a function designator) or
-/// an enum constant.
-class ValueDecl : public NamedDecl {
- void anchor() override;
- QualType DeclType;
-
-protected:
- ValueDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T)
- : NamedDecl(DK, DC, L, N), DeclType(T) {}
-public:
- QualType getType() const { return DeclType; }
- void setType(QualType newType) { DeclType = newType; }
-
- /// \brief Determine whether this symbol is weakly-imported,
- /// or declared with the weak or weak-ref attr.
- bool isWeak() const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
-};
-
-/// QualifierInfo - A struct with extended info about a syntactic
-/// name qualifier, to be used for the case of out-of-line declarations.
-struct QualifierInfo {
- NestedNameSpecifierLoc QualifierLoc;
-
- /// NumTemplParamLists - The number of "outer" template parameter lists.
- /// The count includes all of the template parameter lists that were matched
- /// against the template-ids occurring into the NNS and possibly (in the
- /// case of an explicit specialization) a final "template <>".
- unsigned NumTemplParamLists;
-
- /// TemplParamLists - A new-allocated array of size NumTemplParamLists,
- /// containing pointers to the "outer" template parameter lists.
- /// It includes all of the template parameter lists that were matched
- /// against the template-ids occurring into the NNS and possibly (in the
- /// case of an explicit specialization) a final "template <>".
- TemplateParameterList** TemplParamLists;
-
- /// Default constructor.
- QualifierInfo()
- : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(nullptr) {}
-
- /// setTemplateParameterListsInfo - Sets info about "outer" template
- /// parameter lists.
- void setTemplateParameterListsInfo(ASTContext &Context,
- ArrayRef<TemplateParameterList *> TPLists);
-
-private:
- // Copy constructor and copy assignment are disabled.
- QualifierInfo(const QualifierInfo&) = delete;
- QualifierInfo& operator=(const QualifierInfo&) = delete;
-};
-
-/// \brief Represents a ValueDecl that came out of a declarator.
-/// Contains type source information through TypeSourceInfo.
-class DeclaratorDecl : public ValueDecl {
- // A struct representing both a TInfo and a syntactic qualifier,
- // to be used for the (uncommon) case of out-of-line declarations.
- struct ExtInfo : public QualifierInfo {
- TypeSourceInfo *TInfo;
- };
-
- llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
-
- /// InnerLocStart - The start of the source range for this declaration,
- /// ignoring outer template declarations.
- SourceLocation InnerLocStart;
-
- bool hasExtInfo() const { return DeclInfo.is<ExtInfo*>(); }
- ExtInfo *getExtInfo() { return DeclInfo.get<ExtInfo*>(); }
- const ExtInfo *getExtInfo() const { return DeclInfo.get<ExtInfo*>(); }
-
-protected:
- DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- SourceLocation StartL)
- : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {
- }
-
-public:
- TypeSourceInfo *getTypeSourceInfo() const {
- return hasExtInfo()
- ? getExtInfo()->TInfo
- : DeclInfo.get<TypeSourceInfo*>();
- }
- void setTypeSourceInfo(TypeSourceInfo *TI) {
- if (hasExtInfo())
- getExtInfo()->TInfo = TI;
- else
- DeclInfo = TI;
- }
-
- /// getInnerLocStart - Return SourceLocation representing start of source
- /// range ignoring outer template declarations.
- SourceLocation getInnerLocStart() const { return InnerLocStart; }
- void setInnerLocStart(SourceLocation L) { InnerLocStart = L; }
-
- /// getOuterLocStart - Return SourceLocation representing start of source
- /// range taking into account any outer template declarations.
- SourceLocation getOuterLocStart() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
- SourceLocation getLocStart() const LLVM_READONLY {
- return getOuterLocStart();
- }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the name of this
- /// declaration, if it was present in the source.
- NestedNameSpecifier *getQualifier() const {
- return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
- : nullptr;
- }
-
- /// \brief Retrieve the nested-name-specifier (with source-location
- /// information) that qualifies the name of this declaration, if it was
- /// present in the source.
- NestedNameSpecifierLoc getQualifierLoc() const {
- return hasExtInfo() ? getExtInfo()->QualifierLoc
- : NestedNameSpecifierLoc();
- }
-
- void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
-
- unsigned getNumTemplateParameterLists() const {
- return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
- }
- TemplateParameterList *getTemplateParameterList(unsigned index) const {
- assert(index < getNumTemplateParameterLists());
- return getExtInfo()->TemplParamLists[index];
- }
- void setTemplateParameterListsInfo(ASTContext &Context,
- ArrayRef<TemplateParameterList *> TPLists);
-
- SourceLocation getTypeSpecStartLoc() const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstDeclarator && K <= lastDeclarator;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Structure used to store a statement, the constant value to
-/// which it was evaluated (if any), and whether or not the statement
-/// is an integral constant expression (if known).
-struct EvaluatedStmt {
- EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
- CheckingICE(false), IsICE(false) { }
-
- /// \brief Whether this statement was already evaluated.
- bool WasEvaluated : 1;
-
- /// \brief Whether this statement is being evaluated.
- bool IsEvaluating : 1;
-
- /// \brief Whether we already checked whether this statement was an
- /// integral constant expression.
- bool CheckedICE : 1;
-
- /// \brief Whether we are checking whether this statement is an
- /// integral constant expression.
- bool CheckingICE : 1;
-
- /// \brief Whether this statement is an integral constant expression,
- /// or in C++11, whether the statement is a constant expression. Only
- /// valid if CheckedICE is true.
- bool IsICE : 1;
-
- Stmt *Value;
- APValue Evaluated;
-};
-
-/// VarDecl - An instance of this class is created to represent a variable
-/// declaration or definition.
-class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
-public:
- /// getStorageClassSpecifierString - Return the string used to
- /// specify the storage class \p SC.
- ///
- /// It is illegal to call this function with SC == None.
- static const char *getStorageClassSpecifierString(StorageClass SC);
-
- /// \brief Initialization styles.
- enum InitializationStyle {
- CInit, ///< C-style initialization with assignment
- CallInit, ///< Call-style initialization (C++98)
- ListInit ///< Direct list-initialization (C++11)
- };
-
- /// \brief Kinds of thread-local storage.
- enum TLSKind {
- TLS_None, ///< Not a TLS variable.
- TLS_Static, ///< TLS with a known-constant initializer.
- TLS_Dynamic ///< TLS with a dynamic initializer.
- };
-
-protected:
- // A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we
- // have allocated the auxilliary struct of information there.
- //
- // TODO: It is a bit unfortunate to use a PointerUnion inside the VarDecl for
- // this as *many* VarDecls are ParmVarDecls that don't have default
- // arguments. We could save some space by moving this pointer union to be
- // allocated in trailing space when necessary.
- typedef llvm::PointerUnion<Stmt *, EvaluatedStmt *> InitType;
-
- /// \brief The initializer for this variable or, for a ParmVarDecl, the
- /// C++ default argument.
- mutable InitType Init;
-
-private:
- class VarDeclBitfields {
- friend class VarDecl;
- friend class ASTDeclReader;
-
- unsigned SClass : 3;
- unsigned TSCSpec : 2;
- unsigned InitStyle : 2;
- };
- enum { NumVarDeclBits = 7 };
-
- friend class ASTDeclReader;
- friend class StmtIteratorBase;
- friend class ASTNodeImporter;
-
-protected:
- enum { NumParameterIndexBits = 8 };
-
- enum DefaultArgKind {
- DAK_None,
- DAK_Unparsed,
- DAK_Uninstantiated,
- DAK_Normal
- };
-
- class ParmVarDeclBitfields {
- friend class ParmVarDecl;
- friend class ASTDeclReader;
-
- unsigned : NumVarDeclBits;
-
- /// Whether this parameter inherits a default argument from a
- /// prior declaration.
- unsigned HasInheritedDefaultArg : 1;
-
- /// Describes the kind of default argument for this parameter. By default
- /// this is none. If this is normal, then the default argument is stored in
- /// the \c VarDecl initalizer expression unless we were unble to parse
- /// (even an invalid) expression for the default argument.
- unsigned DefaultArgKind : 2;
-
- /// Whether this parameter undergoes K&R argument promotion.
- unsigned IsKNRPromoted : 1;
-
- /// Whether this parameter is an ObjC method parameter or not.
- unsigned IsObjCMethodParam : 1;
-
- /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
- /// Otherwise, the number of function parameter scopes enclosing
- /// the function parameter scope in which this parameter was
- /// declared.
- unsigned ScopeDepthOrObjCQuals : 7;
-
- /// The number of parameters preceding this parameter in the
- /// function parameter scope in which it was declared.
- unsigned ParameterIndex : NumParameterIndexBits;
- };
-
- class NonParmVarDeclBitfields {
- friend class VarDecl;
- friend class ASTDeclReader;
-
- unsigned : NumVarDeclBits;
-
- /// \brief Whether this variable is the exception variable in a C++ catch
- /// or an Objective-C @catch statement.
- unsigned ExceptionVar : 1;
-
- /// \brief Whether this local variable could be allocated in the return
- /// slot of its function, enabling the named return value optimization
- /// (NRVO).
- unsigned NRVOVariable : 1;
-
- /// \brief Whether this variable is the for-range-declaration in a C++0x
- /// for-range statement.
- unsigned CXXForRangeDecl : 1;
-
- /// \brief Whether this variable is an ARC pseudo-__strong
- /// variable; see isARCPseudoStrong() for details.
- unsigned ARCPseudoStrong : 1;
-
- /// \brief Whether this variable is (C++0x) constexpr.
- unsigned IsConstexpr : 1;
-
- /// \brief Whether this variable is a (C++ Concepts TS) concept.
- unsigned IsConcept : 1;
-
- /// \brief Whether this variable is the implicit variable for a lambda
- /// init-capture.
- unsigned IsInitCapture : 1;
-
- /// \brief Whether this local extern variable's previous declaration was
- /// declared in the same block scope. This controls whether we should merge
- /// the type of this declaration with its previous declaration.
- unsigned PreviousDeclInSameBlockScope : 1;
- };
-
- union {
- unsigned AllBits;
- VarDeclBitfields VarDeclBits;
- ParmVarDeclBitfields ParmVarDeclBits;
- NonParmVarDeclBitfields NonParmVarDeclBits;
- };
-
- VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC);
-
- typedef Redeclarable<VarDecl> redeclarable_base;
- VarDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- VarDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- VarDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- static VarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- StorageClass S);
-
- static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// \brief Returns the storage class as written in the source. For the
- /// computed linkage of symbol, see getLinkage.
- StorageClass getStorageClass() const {
- return (StorageClass) VarDeclBits.SClass;
- }
- void setStorageClass(StorageClass SC);
-
- void setTSCSpec(ThreadStorageClassSpecifier TSC) {
- VarDeclBits.TSCSpec = TSC;
- assert(VarDeclBits.TSCSpec == TSC && "truncation");
- }
- ThreadStorageClassSpecifier getTSCSpec() const {
- return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec);
- }
- TLSKind getTLSKind() const;
-
- /// hasLocalStorage - Returns true if a variable with function scope
- /// is a non-static local variable.
- bool hasLocalStorage() const {
- if (getStorageClass() == SC_None)
- // Second check is for C++11 [dcl.stc]p4.
- return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
-
- // Global Named Register (GNU extension)
- if (getStorageClass() == SC_Register && !isLocalVarDeclOrParm())
- return false;
-
- // Return true for: Auto, Register.
- // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal.
-
- return getStorageClass() >= SC_Auto;
- }
-
- /// isStaticLocal - Returns true if a variable with function scope is a
- /// static local variable.
- bool isStaticLocal() const {
- return (getStorageClass() == SC_Static ||
- // C++11 [dcl.stc]p4
- (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local))
- && !isFileVarDecl();
- }
-
- /// \brief Returns true if a variable has extern or __private_extern__
- /// storage.
- bool hasExternalStorage() const {
- return getStorageClass() == SC_Extern ||
- getStorageClass() == SC_PrivateExtern;
- }
-
- /// \brief Returns true for all variables that do not have local storage.
- ///
- /// This includes all global variables as well as static variables declared
- /// within a function.
- bool hasGlobalStorage() const { return !hasLocalStorage(); }
-
- /// \brief Get the storage duration of this variable, per C++ [basic.stc].
- StorageDuration getStorageDuration() const {
- return hasLocalStorage() ? SD_Automatic :
- getTSCSpec() ? SD_Thread : SD_Static;
- }
-
- /// \brief Compute the language linkage.
- LanguageLinkage getLanguageLinkage() const;
-
- /// \brief Determines whether this variable is a variable with
- /// external, C linkage.
- bool isExternC() const;
-
- /// \brief Determines whether this variable's context is, or is nested within,
- /// a C++ extern "C" linkage spec.
- bool isInExternCContext() const;
-
- /// \brief Determines whether this variable's context is, or is nested within,
- /// a C++ extern "C++" linkage spec.
- bool isInExternCXXContext() const;
-
- /// isLocalVarDecl - Returns true for local variable declarations
- /// other than parameters. Note that this includes static variables
- /// inside of functions. It also includes variables inside blocks.
- ///
- /// void foo() { int x; static int y; extern int z; }
- ///
- bool isLocalVarDecl() const {
- if (getKind() != Decl::Var)
- return false;
- if (const DeclContext *DC = getLexicalDeclContext())
- return DC->getRedeclContext()->isFunctionOrMethod();
- return false;
- }
-
- /// \brief Similar to isLocalVarDecl but also includes parameters.
- bool isLocalVarDeclOrParm() const {
- return isLocalVarDecl() || getKind() == Decl::ParmVar;
- }
-
- /// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but
- /// excludes variables declared in blocks.
- bool isFunctionOrMethodVarDecl() const {
- if (getKind() != Decl::Var)
- return false;
- const DeclContext *DC = getLexicalDeclContext()->getRedeclContext();
- return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
- }
-
- /// \brief Determines whether this is a static data member.
- ///
- /// This will only be true in C++, and applies to, e.g., the
- /// variable 'x' in:
- /// \code
- /// struct S {
- /// static int x;
- /// };
- /// \endcode
- bool isStaticDataMember() const {
- // If it wasn't static, it would be a FieldDecl.
- return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
- }
-
- VarDecl *getCanonicalDecl() override;
- const VarDecl *getCanonicalDecl() const {
- return const_cast<VarDecl*>(this)->getCanonicalDecl();
- }
-
- enum DefinitionKind {
- DeclarationOnly, ///< This declaration is only a declaration.
- TentativeDefinition, ///< This declaration is a tentative definition.
- Definition ///< This declaration is definitely a definition.
- };
-
- /// \brief Check whether this declaration is a definition. If this could be
- /// a tentative definition (in C), don't check whether there's an overriding
- /// definition.
- DefinitionKind isThisDeclarationADefinition(ASTContext &) const;
- DefinitionKind isThisDeclarationADefinition() const {
- return isThisDeclarationADefinition(getASTContext());
- }
-
- /// \brief Check whether this variable is defined in this
- /// translation unit.
- DefinitionKind hasDefinition(ASTContext &) const;
- DefinitionKind hasDefinition() const {
- return hasDefinition(getASTContext());
- }
-
- /// \brief Get the tentative definition that acts as the real definition in
- /// a TU. Returns null if there is a proper definition available.
- VarDecl *getActingDefinition();
- const VarDecl *getActingDefinition() const {
- return const_cast<VarDecl*>(this)->getActingDefinition();
- }
-
- /// \brief Get the real (not just tentative) definition for this declaration.
- VarDecl *getDefinition(ASTContext &);
- const VarDecl *getDefinition(ASTContext &C) const {
- return const_cast<VarDecl*>(this)->getDefinition(C);
- }
- VarDecl *getDefinition() {
- return getDefinition(getASTContext());
- }
- const VarDecl *getDefinition() const {
- return const_cast<VarDecl*>(this)->getDefinition();
- }
-
- /// \brief Determine whether this is or was instantiated from an out-of-line
- /// definition of a static data member.
- bool isOutOfLine() const override;
-
- /// \brief If this is a static data member, find its out-of-line definition.
- VarDecl *getOutOfLineDefinition();
-
- /// isFileVarDecl - Returns true for file scoped variable declaration.
- bool isFileVarDecl() const {
- Kind K = getKind();
- if (K == ParmVar || K == ImplicitParam)
- return false;
-
- if (getLexicalDeclContext()->getRedeclContext()->isFileContext())
- return true;
-
- if (isStaticDataMember())
- return true;
-
- return false;
- }
-
- /// getAnyInitializer - Get the initializer for this variable, no matter which
- /// declaration it is attached to.
- const Expr *getAnyInitializer() const {
- const VarDecl *D;
- return getAnyInitializer(D);
- }
-
- /// getAnyInitializer - Get the initializer for this variable, no matter which
- /// declaration it is attached to. Also get that declaration.
- const Expr *getAnyInitializer(const VarDecl *&D) const;
-
- bool hasInit() const;
- const Expr *getInit() const {
- return const_cast<VarDecl *>(this)->getInit();
- }
- Expr *getInit();
-
- /// \brief Retrieve the address of the initializer expression.
- Stmt **getInitAddress();
-
- void setInit(Expr *I);
-
- /// \brief Determine whether this variable's value can be used in a
- /// constant expression, according to the relevant language standard.
- /// This only checks properties of the declaration, and does not check
- /// whether the initializer is in fact a constant expression.
- bool isUsableInConstantExpressions(ASTContext &C) const;
-
- EvaluatedStmt *ensureEvaluatedStmt() const;
-
- /// \brief Attempt to evaluate the value of the initializer attached to this
- /// declaration, and produce notes explaining why it cannot be evaluated or is
- /// not a constant expression. Returns a pointer to the value if evaluation
- /// succeeded, 0 otherwise.
- APValue *evaluateValue() const;
- APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
-
- /// \brief Return the already-evaluated value of this variable's
- /// initializer, or NULL if the value is not yet known. Returns pointer
- /// to untyped APValue if the value could not be evaluated.
- APValue *getEvaluatedValue() const;
-
- /// \brief Determines whether it is already known whether the
- /// initializer is an integral constant expression or not.
- bool isInitKnownICE() const;
-
- /// \brief Determines whether the initializer is an integral constant
- /// expression, or in C++11, whether the initializer is a constant
- /// expression.
- ///
- /// \pre isInitKnownICE()
- bool isInitICE() const;
-
- /// \brief Determine whether the value of the initializer attached to this
- /// declaration is an integral constant expression.
- bool checkInitIsICE() const;
-
- void setInitStyle(InitializationStyle Style) {
- VarDeclBits.InitStyle = Style;
- }
-
- /// \brief The style of initialization for this declaration.
- ///
- /// C-style initialization is "int x = 1;". Call-style initialization is
- /// a C++98 direct-initializer, e.g. "int x(1);". The Init expression will be
- /// the expression inside the parens or a "ClassType(a,b,c)" class constructor
- /// expression for class types. List-style initialization is C++11 syntax,
- /// e.g. "int x{1};". Clients can distinguish between different forms of
- /// initialization by checking this value. In particular, "int x = {1};" is
- /// C-style, "int x({1})" is call-style, and "int x{1};" is list-style; the
- /// Init expression in all three cases is an InitListExpr.
- InitializationStyle getInitStyle() const {
- return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
- }
-
- /// \brief Whether the initializer is a direct-initializer (list or call).
- bool isDirectInit() const {
- return getInitStyle() != CInit;
- }
-
- /// \brief Determine whether this variable is the exception variable in a
- /// C++ catch statememt or an Objective-C \@catch statement.
- bool isExceptionVariable() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ExceptionVar;
- }
- void setExceptionVariable(bool EV) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.ExceptionVar = EV;
- }
-
- /// \brief Determine whether this local variable can be used with the named
- /// return value optimization (NRVO).
- ///
- /// The named return value optimization (NRVO) works by marking certain
- /// non-volatile local variables of class type as NRVO objects. These
- /// locals can be allocated within the return slot of their containing
- /// function, in which case there is no need to copy the object to the
- /// return slot when returning from the function. Within the function body,
- /// each return that returns the NRVO object will have this variable as its
- /// NRVO candidate.
- bool isNRVOVariable() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.NRVOVariable;
- }
- void setNRVOVariable(bool NRVO) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.NRVOVariable = NRVO;
- }
-
- /// \brief Determine whether this variable is the for-range-declaration in
- /// a C++0x for-range statement.
- bool isCXXForRangeDecl() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.CXXForRangeDecl;
- }
- void setCXXForRangeDecl(bool FRD) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.CXXForRangeDecl = FRD;
- }
-
- /// \brief Determine whether this variable is an ARC pseudo-__strong
- /// variable. A pseudo-__strong variable has a __strong-qualified
- /// type but does not actually retain the object written into it.
- /// Generally such variables are also 'const' for safety.
- bool isARCPseudoStrong() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ARCPseudoStrong;
- }
- void setARCPseudoStrong(bool ps) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.ARCPseudoStrong = ps;
- }
-
- /// Whether this variable is (C++11) constexpr.
- bool isConstexpr() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConstexpr;
- }
- void setConstexpr(bool IC) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.IsConstexpr = IC;
- }
-
- /// Whether this variable is (C++ Concepts TS) concept.
- bool isConcept() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConcept;
- }
- void setConcept(bool IC) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.IsConcept = IC;
- }
-
- /// Whether this variable is the implicit variable for a lambda init-capture.
- bool isInitCapture() const {
- return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture;
- }
- void setInitCapture(bool IC) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.IsInitCapture = IC;
- }
-
- /// Whether this local extern variable declaration's previous declaration
- /// was declared in the same block scope. Only correct in C++.
- bool isPreviousDeclInSameBlockScope() const {
- return isa<ParmVarDecl>(this)
- ? false
- : NonParmVarDeclBits.PreviousDeclInSameBlockScope;
- }
- void setPreviousDeclInSameBlockScope(bool Same) {
- assert(!isa<ParmVarDecl>(this));
- NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
- }
-
- /// \brief If this variable is an instantiated static data member of a
- /// class template specialization, returns the templated static data member
- /// from which it was instantiated.
- VarDecl *getInstantiatedFromStaticDataMember() const;
-
- /// \brief If this variable is an instantiation of a variable template or a
- /// static data member of a class template, determine what kind of
- /// template specialization or instantiation this is.
- TemplateSpecializationKind getTemplateSpecializationKind() const;
-
- /// \brief If this variable is an instantiation of a variable template or a
- /// static data member of a class template, determine its point of
- /// instantiation.
- SourceLocation getPointOfInstantiation() const;
-
- /// \brief If this variable is an instantiation of a static data member of a
- /// class template specialization, retrieves the member specialization
- /// information.
- MemberSpecializationInfo *getMemberSpecializationInfo() const;
-
- /// \brief For a static data member that was instantiated from a static
- /// data member of a class template, set the template specialiation kind.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
- SourceLocation PointOfInstantiation = SourceLocation());
-
- /// \brief Specify that this variable is an instantiation of the
- /// static data member VD.
- void setInstantiationOfStaticDataMember(VarDecl *VD,
- TemplateSpecializationKind TSK);
-
- /// \brief Retrieves the variable template that is described by this
- /// variable declaration.
- ///
- /// Every variable template is represented as a VarTemplateDecl and a
- /// VarDecl. The former contains template properties (such as
- /// the template parameter lists) while the latter contains the
- /// actual description of the template's
- /// contents. VarTemplateDecl::getTemplatedDecl() retrieves the
- /// VarDecl that from a VarTemplateDecl, while
- /// getDescribedVarTemplate() retrieves the VarTemplateDecl from
- /// a VarDecl.
- VarTemplateDecl *getDescribedVarTemplate() const;
-
- void setDescribedVarTemplate(VarTemplateDecl *Template);
-
- // 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; }
-};
-
-class ImplicitParamDecl : public VarDecl {
- void anchor() override;
-public:
- static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T);
-
- static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType Type)
- : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
- /*tinfo*/ nullptr, SC_None) {
- setImplicit();
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ImplicitParam; }
-};
-
-/// ParmVarDecl - Represents a parameter to a function.
-class ParmVarDecl : public VarDecl {
-public:
- enum { MaxFunctionScopeDepth = 255 };
- enum { MaxFunctionScopeIndex = 255 };
-
-protected:
- ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
- : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
- assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
- assert(ParmVarDeclBits.DefaultArgKind == DAK_None);
- assert(ParmVarDeclBits.IsKNRPromoted == false);
- assert(ParmVarDeclBits.IsObjCMethodParam == false);
- setDefaultArg(DefArg);
- }
-
-public:
- static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg);
-
- static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- void setObjCMethodScopeInfo(unsigned parameterIndex) {
- ParmVarDeclBits.IsObjCMethodParam = true;
- setParameterIndex(parameterIndex);
- }
-
- void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) {
- assert(!ParmVarDeclBits.IsObjCMethodParam);
-
- ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth;
- assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth
- && "truncation!");
-
- setParameterIndex(parameterIndex);
- }
-
- bool isObjCMethodParameter() const {
- return ParmVarDeclBits.IsObjCMethodParam;
- }
-
- unsigned getFunctionScopeDepth() const {
- if (ParmVarDeclBits.IsObjCMethodParam) return 0;
- return ParmVarDeclBits.ScopeDepthOrObjCQuals;
- }
-
- /// Returns the index of this parameter in its prototype or method scope.
- unsigned getFunctionScopeIndex() const {
- return getParameterIndex();
- }
-
- ObjCDeclQualifier getObjCDeclQualifier() const {
- if (!ParmVarDeclBits.IsObjCMethodParam) return OBJC_TQ_None;
- return ObjCDeclQualifier(ParmVarDeclBits.ScopeDepthOrObjCQuals);
- }
- void setObjCDeclQualifier(ObjCDeclQualifier QTVal) {
- assert(ParmVarDeclBits.IsObjCMethodParam);
- ParmVarDeclBits.ScopeDepthOrObjCQuals = QTVal;
- }
-
- /// True if the value passed to this parameter must undergo
- /// K&R-style default argument promotion:
- ///
- /// C99 6.5.2.2.
- /// If the expression that denotes the called function has a type
- /// that does not include a prototype, the integer promotions are
- /// performed on each argument, and arguments that have type float
- /// are promoted to double.
- bool isKNRPromoted() const {
- return ParmVarDeclBits.IsKNRPromoted;
- }
- void setKNRPromoted(bool promoted) {
- ParmVarDeclBits.IsKNRPromoted = promoted;
- }
-
- Expr *getDefaultArg();
- const Expr *getDefaultArg() const {
- return const_cast<ParmVarDecl *>(this)->getDefaultArg();
- }
-
- void setDefaultArg(Expr *defarg);
-
- /// \brief Retrieve the source range that covers the entire default
- /// argument.
- SourceRange getDefaultArgRange() const;
- void setUninstantiatedDefaultArg(Expr *arg);
- Expr *getUninstantiatedDefaultArg();
- const Expr *getUninstantiatedDefaultArg() const {
- return const_cast<ParmVarDecl *>(this)->getUninstantiatedDefaultArg();
- }
-
- /// hasDefaultArg - Determines whether this parameter has a default argument,
- /// either parsed or not.
- bool hasDefaultArg() const;
-
- /// hasUnparsedDefaultArg - Determines whether this parameter has a
- /// default argument that has not yet been parsed. This will occur
- /// during the processing of a C++ class whose member functions have
- /// default arguments, e.g.,
- /// @code
- /// class X {
- /// public:
- /// void f(int x = 17); // x has an unparsed default argument now
- /// }; // x has a regular default argument now
- /// @endcode
- bool hasUnparsedDefaultArg() const {
- return ParmVarDeclBits.DefaultArgKind == DAK_Unparsed;
- }
-
- bool hasUninstantiatedDefaultArg() const {
- return ParmVarDeclBits.DefaultArgKind == DAK_Uninstantiated;
- }
-
- /// setUnparsedDefaultArg - Specify that this parameter has an
- /// unparsed default argument. The argument will be replaced with a
- /// real default argument via setDefaultArg when the class
- /// definition enclosing the function declaration that owns this
- /// default argument is completed.
- void setUnparsedDefaultArg() {
- ParmVarDeclBits.DefaultArgKind = DAK_Unparsed;
- }
-
- bool hasInheritedDefaultArg() const {
- return ParmVarDeclBits.HasInheritedDefaultArg;
- }
-
- void setHasInheritedDefaultArg(bool I = true) {
- ParmVarDeclBits.HasInheritedDefaultArg = I;
- }
-
- QualType getOriginalType() const;
-
- /// \brief Determine whether this parameter is actually a function
- /// parameter pack.
- bool isParameterPack() const;
-
- /// setOwningFunction - Sets the function declaration that owns this
- /// ParmVarDecl. Since ParmVarDecls are often created before the
- /// FunctionDecls that own them, this routine is required to update
- /// the DeclContext appropriately.
- void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ParmVar; }
-
-private:
- enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 };
-
- void setParameterIndex(unsigned parameterIndex) {
- if (parameterIndex >= ParameterIndexSentinel) {
- setParameterIndexLarge(parameterIndex);
- return;
- }
-
- ParmVarDeclBits.ParameterIndex = parameterIndex;
- assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");
- }
- unsigned getParameterIndex() const {
- unsigned d = ParmVarDeclBits.ParameterIndex;
- return d == ParameterIndexSentinel ? getParameterIndexLarge() : d;
- }
-
- void setParameterIndexLarge(unsigned parameterIndex);
- unsigned getParameterIndexLarge() const;
-};
-
-/// FunctionDecl - An instance of this class is created to represent a
-/// function declaration or definition.
-///
-/// Since a given function can be declared several times in a program,
-/// there may be several FunctionDecls that correspond to that
-/// function. Only one of those FunctionDecls will be found when
-/// traversing the list of declarations in the context of the
-/// FunctionDecl (e.g., the translation unit); this FunctionDecl
-/// contains all of the information known about the function. Other,
-/// previous declarations of the function are available via the
-/// getPreviousDecl() chain.
-class FunctionDecl : public DeclaratorDecl, public DeclContext,
- public Redeclarable<FunctionDecl> {
-public:
- /// \brief The kind of templated function a FunctionDecl can be.
- enum TemplatedKind {
- TK_NonTemplate,
- TK_FunctionTemplate,
- TK_MemberSpecialization,
- TK_FunctionTemplateSpecialization,
- TK_DependentFunctionTemplateSpecialization
- };
-
-private:
- /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
- /// parameters of this function. This is null if a prototype or if there are
- /// no formals.
- ParmVarDecl **ParamInfo;
-
- /// DeclsInPrototypeScope - Array of pointers to NamedDecls for
- /// decls defined in the function prototype that are not parameters. E.g.
- /// 'enum Y' in 'void f(enum Y {AA} x) {}'.
- ArrayRef<NamedDecl *> DeclsInPrototypeScope;
-
- LazyDeclStmtPtr Body;
-
- // FIXME: This can be packed into the bitfields in DeclContext.
- // NOTE: VC++ packs bitfields poorly if the types differ.
- unsigned SClass : 2;
- unsigned IsInline : 1;
- unsigned IsInlineSpecified : 1;
- unsigned IsVirtualAsWritten : 1;
- unsigned IsPure : 1;
- unsigned HasInheritedPrototype : 1;
- unsigned HasWrittenPrototype : 1;
- unsigned IsDeleted : 1;
- unsigned IsTrivial : 1; // sunk from CXXMethodDecl
- unsigned IsDefaulted : 1; // sunk from CXXMethoDecl
- unsigned IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl
- unsigned HasImplicitReturnZero : 1;
- unsigned IsLateTemplateParsed : 1;
- unsigned IsConstexpr : 1;
-
- /// \brief Indicates if the function uses __try.
- unsigned UsesSEHTry : 1;
-
- /// \brief Indicates if the function was a definition but its body was
- /// skipped.
- unsigned HasSkippedBody : 1;
-
- /// \brief End part of this FunctionDecl's source range.
- ///
- /// We could compute the full range in getSourceRange(). However, when we're
- /// dealing with a function definition deserialized from a PCH/AST file,
- /// we can only compute the full range once the function body has been
- /// de-serialized, so it's far better to have the (sometimes-redundant)
- /// EndRangeLoc.
- SourceLocation EndRangeLoc;
-
- /// \brief The template or declaration that this declaration
- /// describes or was instantiated from, respectively.
- ///
- /// For non-templates, this value will be NULL. For function
- /// declarations that describe a function template, this will be a
- /// pointer to a FunctionTemplateDecl. For member functions
- /// of class template specializations, this will be a MemberSpecializationInfo
- /// pointer containing information about the specialization.
- /// For function template specializations, this will be a
- /// FunctionTemplateSpecializationInfo, which contains information about
- /// the template being specialized and the template arguments involved in
- /// that specialization.
- llvm::PointerUnion4<FunctionTemplateDecl *,
- MemberSpecializationInfo *,
- FunctionTemplateSpecializationInfo *,
- DependentFunctionTemplateSpecializationInfo *>
- TemplateOrSpecialization;
-
- /// DNLoc - Provides source/type location info for the
- /// declaration name embedded in the DeclaratorDecl base class.
- DeclarationNameLoc DNLoc;
-
- /// \brief Specify that this function declaration is actually a function
- /// template specialization.
- ///
- /// \param C the ASTContext.
- ///
- /// \param Template the function template that this function template
- /// specialization specializes.
- ///
- /// \param TemplateArgs the template arguments that produced this
- /// function template specialization from the template.
- ///
- /// \param InsertPos If non-NULL, the position in the function template
- /// specialization set where the function template specialization data will
- /// be inserted.
- ///
- /// \param TSK the kind of template specialization this is.
- ///
- /// \param TemplateArgsAsWritten location info of template arguments.
- ///
- /// \param PointOfInstantiation point at which the function template
- /// specialization was first instantiated.
- void setFunctionTemplateSpecialization(ASTContext &C,
- FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs,
- void *InsertPos,
- TemplateSpecializationKind TSK,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation PointOfInstantiation);
-
- /// \brief Specify that this record is an instantiation of the
- /// member function FD.
- void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
- TemplateSpecializationKind TSK);
-
- void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo);
-
-protected:
- FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, bool isInlineSpecified,
- bool isConstexprSpecified)
- : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
- StartLoc),
- DeclContext(DK),
- redeclarable_base(C),
- ParamInfo(nullptr), Body(),
- SClass(S),
- IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
- IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
- HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
- IsDefaulted(false), IsExplicitlyDefaulted(false),
- HasImplicitReturnZero(false), IsLateTemplateParsed(false),
- IsConstexpr(isConstexprSpecified), UsesSEHTry(false),
- HasSkippedBody(false), EndRangeLoc(NameInfo.getEndLoc()),
- TemplateOrSpecialization(),
- DNLoc(NameInfo.getInfo()) {}
-
- typedef Redeclarable<FunctionDecl> redeclarable_base;
- FunctionDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- FunctionDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- FunctionDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation NLoc,
- DeclarationName N, QualType T,
- TypeSourceInfo *TInfo,
- StorageClass SC,
- bool isInlineSpecified = false,
- bool hasWrittenPrototype = true,
- bool isConstexprSpecified = false) {
- DeclarationNameInfo NameInfo(N, NLoc);
- return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo,
- SC,
- isInlineSpecified, hasWrittenPrototype,
- isConstexprSpecified);
- }
-
- static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass SC,
- bool isInlineSpecified,
- bool hasWrittenPrototype,
- bool isConstexprSpecified = false);
-
- static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
- }
-
- void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
- bool Qualified) const override;
-
- void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// \brief Returns true if the function has a body (definition). The
- /// function body might be in any of the (re-)declarations of this
- /// function. The variant that accepts a FunctionDecl pointer will
- /// set that function declaration to the actual declaration
- /// containing the body (if there is one).
- bool hasBody(const FunctionDecl *&Definition) const;
-
- bool hasBody() const override {
- const FunctionDecl* Definition;
- return hasBody(Definition);
- }
-
- /// hasTrivialBody - Returns whether the function has a trivial body that does
- /// not require any specific codegen.
- bool hasTrivialBody() const;
-
- /// isDefined - Returns true if the function is defined at all, including
- /// a deleted definition. Except for the behavior when the function is
- /// deleted, behaves like hasBody.
- bool isDefined(const FunctionDecl *&Definition) const;
-
- virtual bool isDefined() const {
- const FunctionDecl* Definition;
- return isDefined(Definition);
- }
-
- /// getBody - Retrieve the body (definition) of the function. The
- /// function body might be in any of the (re-)declarations of this
- /// function. The variant that accepts a FunctionDecl pointer will
- /// set that function declaration to the actual declaration
- /// containing the body (if there is one).
- /// NOTE: For checking if there is a body, use hasBody() instead, to avoid
- /// unnecessary AST de-serialization of the body.
- Stmt *getBody(const FunctionDecl *&Definition) const;
-
- Stmt *getBody() const override {
- const FunctionDecl* Definition;
- return getBody(Definition);
- }
-
- /// isThisDeclarationADefinition - Returns whether this specific
- /// declaration of the function is also a definition. This does not
- /// determine whether the function has been defined (e.g., in a
- /// previous definition); for that information, use isDefined. Note
- /// that this returns false for a defaulted function unless that function
- /// has been implicitly defined (possibly as deleted).
- bool isThisDeclarationADefinition() const {
- return IsDeleted || Body || IsLateTemplateParsed;
- }
-
- /// doesThisDeclarationHaveABody - Returns whether this specific
- /// declaration of the function has a body - that is, if it is a non-
- /// deleted definition.
- bool doesThisDeclarationHaveABody() const {
- return Body || IsLateTemplateParsed;
- }
-
- void setBody(Stmt *B);
- void setLazyBody(uint64_t Offset) { Body = Offset; }
-
- /// Whether this function is variadic.
- bool isVariadic() const;
-
- /// Whether this function is marked as virtual explicitly.
- bool isVirtualAsWritten() const { return IsVirtualAsWritten; }
- void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; }
-
- /// Whether this virtual function is pure, i.e. makes the containing class
- /// abstract.
- bool isPure() const { return IsPure; }
- void setPure(bool P = true);
-
- /// Whether this templated function will be late parsed.
- bool isLateTemplateParsed() const { return IsLateTemplateParsed; }
- void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; }
-
- /// Whether this function is "trivial" in some specialized C++ senses.
- /// Can only be true for default constructors, copy constructors,
- /// copy assignment operators, and destructors. Not meaningful until
- /// the class has been fully built by Sema.
- bool isTrivial() const { return IsTrivial; }
- void setTrivial(bool IT) { IsTrivial = IT; }
-
- /// Whether this function is defaulted per C++0x. Only valid for
- /// special member functions.
- bool isDefaulted() const { return IsDefaulted; }
- void setDefaulted(bool D = true) { IsDefaulted = D; }
-
- /// Whether this function is explicitly defaulted per C++0x. Only valid
- /// for special member functions.
- bool isExplicitlyDefaulted() const { return IsExplicitlyDefaulted; }
- void setExplicitlyDefaulted(bool ED = true) { IsExplicitlyDefaulted = ED; }
-
- /// Whether falling off this function implicitly returns null/zero.
- /// If a more specific implicit return value is required, front-ends
- /// should synthesize the appropriate return statements.
- bool hasImplicitReturnZero() const { return HasImplicitReturnZero; }
- void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; }
-
- /// \brief Whether this function has a prototype, either because one
- /// was explicitly written or because it was "inherited" by merging
- /// a declaration without a prototype with a declaration that has a
- /// prototype.
- bool hasPrototype() const {
- return HasWrittenPrototype || HasInheritedPrototype;
- }
-
- bool hasWrittenPrototype() const { return HasWrittenPrototype; }
-
- /// \brief Whether this function inherited its prototype from a
- /// previous declaration.
- bool hasInheritedPrototype() const { return HasInheritedPrototype; }
- void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; }
-
- /// Whether this is a (C++11) constexpr function or constexpr constructor.
- bool isConstexpr() const { return IsConstexpr; }
- void setConstexpr(bool IC) { IsConstexpr = IC; }
-
- /// \brief Indicates the function uses __try.
- bool usesSEHTry() const { return UsesSEHTry; }
- void setUsesSEHTry(bool UST) { UsesSEHTry = UST; }
-
- /// \brief Whether this function has been deleted.
- ///
- /// A function that is "deleted" (via the C++0x "= delete" syntax)
- /// acts like a normal function, except that it cannot actually be
- /// called or have its address taken. Deleted functions are
- /// typically used in C++ overload resolution to attract arguments
- /// whose type or lvalue/rvalue-ness would permit the use of a
- /// different overload that would behave incorrectly. For example,
- /// one might use deleted functions to ban implicit conversion from
- /// a floating-point number to an Integer type:
- ///
- /// @code
- /// struct Integer {
- /// Integer(long); // construct from a long
- /// Integer(double) = delete; // no construction from float or double
- /// Integer(long double) = delete; // no construction from long double
- /// };
- /// @endcode
- // If a function is deleted, its first declaration must be.
- bool isDeleted() const { return getCanonicalDecl()->IsDeleted; }
- bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; }
- void setDeletedAsWritten(bool D = true) { IsDeleted = D; }
-
- /// \brief Determines whether this function is "main", which is the
- /// entry point into an executable program.
- bool isMain() const;
-
- /// \brief Determines whether this function is a MSVCRT user defined entry
- /// point.
- bool isMSVCRTEntryPoint() const;
-
- /// \brief Determines whether this operator new or delete is one
- /// of the reserved global placement operators:
- /// void *operator new(size_t, void *);
- /// void *operator new[](size_t, void *);
- /// void operator delete(void *, void *);
- /// void operator delete[](void *, void *);
- /// These functions have special behavior under [new.delete.placement]:
- /// These functions are reserved, a C++ program may not define
- /// functions that displace the versions in the Standard C++ library.
- /// The provisions of [basic.stc.dynamic] do not apply to these
- /// reserved placement forms of operator new and operator delete.
- ///
- /// This function must be an allocation or deallocation function.
- bool isReservedGlobalPlacementOperator() const;
-
- /// \brief Determines whether this function is one of the replaceable
- /// global allocation functions:
- /// void *operator new(size_t);
- /// void *operator new(size_t, const std::nothrow_t &) noexcept;
- /// void *operator new[](size_t);
- /// void *operator new[](size_t, const std::nothrow_t &) noexcept;
- /// void operator delete(void *) noexcept;
- /// void operator delete(void *, std::size_t) noexcept; [C++1y]
- /// void operator delete(void *, const std::nothrow_t &) noexcept;
- /// void operator delete[](void *) noexcept;
- /// void operator delete[](void *, std::size_t) noexcept; [C++1y]
- /// void operator delete[](void *, const std::nothrow_t &) noexcept;
- /// These functions have special behavior under C++1y [expr.new]:
- /// An implementation is allowed to omit a call to a replaceable global
- /// allocation function. [...]
- bool isReplaceableGlobalAllocationFunction() const;
-
- /// Compute the language linkage.
- LanguageLinkage getLanguageLinkage() const;
-
- /// \brief Determines whether this function is a function with
- /// external, C linkage.
- bool isExternC() const;
-
- /// \brief Determines whether this function's context is, or is nested within,
- /// a C++ extern "C" linkage spec.
- bool isInExternCContext() const;
-
- /// \brief Determines whether this function's context is, or is nested within,
- /// a C++ extern "C++" linkage spec.
- bool isInExternCXXContext() const;
-
- /// \brief Determines whether this is a global function.
- bool isGlobal() const;
-
- /// \brief Determines whether this function is known to be 'noreturn', through
- /// an attribute on its declaration or its type.
- bool isNoReturn() const;
-
- /// \brief True if the function was a definition but its body was skipped.
- bool hasSkippedBody() const { return HasSkippedBody; }
- void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
-
- void setPreviousDeclaration(FunctionDecl * PrevDecl);
-
- FunctionDecl *getCanonicalDecl() override;
- const FunctionDecl *getCanonicalDecl() const {
- return const_cast<FunctionDecl*>(this)->getCanonicalDecl();
- }
-
- unsigned getBuiltinID() const;
-
- // Iterator access to formal parameters.
- unsigned param_size() const { return getNumParams(); }
- typedef ParmVarDecl **param_iterator;
- typedef ParmVarDecl * const *param_const_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
- typedef llvm::iterator_range<param_const_iterator> param_const_range;
-
- param_iterator param_begin() { return param_iterator(ParamInfo); }
- param_iterator param_end() {
- return param_iterator(ParamInfo + param_size());
- }
- param_range params() { return param_range(param_begin(), param_end()); }
-
- param_const_iterator param_begin() const {
- return param_const_iterator(ParamInfo);
- }
- param_const_iterator param_end() const {
- return param_const_iterator(ParamInfo + param_size());
- }
- param_const_range params() const {
- return param_const_range(param_begin(), param_end());
- }
-
- /// getNumParams - Return the number of parameters this function must have
- /// based on its FunctionType. This is the length of the ParamInfo array
- /// after it has been created.
- unsigned getNumParams() const;
-
- const ParmVarDecl *getParamDecl(unsigned i) const {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- ParmVarDecl *getParamDecl(unsigned i) {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- void setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
- setParams(getASTContext(), NewParamInfo);
- }
-
- // ArrayRef iterface to parameters.
- // FIXME: Should one day replace iterator interface.
- ArrayRef<ParmVarDecl*> parameters() const {
- return llvm::makeArrayRef(ParamInfo, getNumParams());
- }
-
- ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const {
- return DeclsInPrototypeScope;
- }
- void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
-
- /// getMinRequiredArguments - Returns the minimum number of arguments
- /// needed to call this function. This may be fewer than the number of
- /// function parameters, if some of the parameters have default
- /// arguments (in C++).
- unsigned getMinRequiredArguments() const;
-
- QualType getReturnType() const {
- return getType()->getAs<FunctionType>()->getReturnType();
- }
-
- /// \brief Attempt to compute an informative source range covering the
- /// function return type. This may omit qualifiers and other information with
- /// limited representation in the AST.
- SourceRange getReturnTypeSourceRange() const;
-
- /// \brief Determine the type of an expression that calls this function.
- QualType getCallResultType() const {
- return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
- }
-
- /// \brief Returns true if this function or its return type has the
- /// warn_unused_result attribute. If the return type has the attribute and
- /// this function is a method of the return type's class, then false will be
- /// returned to avoid spurious warnings on member methods such as assignment
- /// operators.
- bool hasUnusedResultAttr() const;
-
- /// \brief Returns the storage class as written in the source. For the
- /// computed linkage of symbol, see getLinkage.
- StorageClass getStorageClass() const { return StorageClass(SClass); }
-
- /// \brief Determine whether the "inline" keyword was specified for this
- /// function.
- bool isInlineSpecified() const { return IsInlineSpecified; }
-
- /// Set whether the "inline" keyword was specified for this function.
- void setInlineSpecified(bool I) {
- IsInlineSpecified = I;
- IsInline = I;
- }
-
- /// Flag that this function is implicitly inline.
- void setImplicitlyInline() {
- IsInline = true;
- }
-
- /// \brief Determine whether this function should be inlined, because it is
- /// either marked "inline" or "constexpr" or is a member function of a class
- /// that was defined in the class body.
- bool isInlined() const { return IsInline; }
-
- bool isInlineDefinitionExternallyVisible() const;
-
- bool isMSExternInline() const;
-
- bool doesDeclarationForceExternallyVisibleDefinition() const;
-
- /// isOverloadedOperator - Whether this function declaration
- /// represents an C++ overloaded operator, e.g., "operator+".
- bool isOverloadedOperator() const {
- return getOverloadedOperator() != OO_None;
- }
-
- OverloadedOperatorKind getOverloadedOperator() const;
-
- const IdentifierInfo *getLiteralIdentifier() const;
-
- /// \brief If this function is an instantiation of a member function
- /// of a class template specialization, retrieves the function from
- /// which it was instantiated.
- ///
- /// This routine will return non-NULL for (non-templated) member
- /// functions of class templates and for instantiations of function
- /// templates. For example, given:
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// void f(T);
- /// };
- /// \endcode
- ///
- /// The declaration for X<int>::f is a (non-templated) FunctionDecl
- /// whose parent is the class template specialization X<int>. For
- /// this declaration, getInstantiatedFromFunction() will return
- /// the FunctionDecl X<T>::A. When a complete definition of
- /// X<int>::A is required, it will be instantiated from the
- /// declaration returned by getInstantiatedFromMemberFunction().
- FunctionDecl *getInstantiatedFromMemberFunction() const;
-
- /// \brief What kind of templated function this is.
- TemplatedKind getTemplatedKind() const;
-
- /// \brief If this function is an instantiation of a member function of a
- /// class template specialization, retrieves the member specialization
- /// information.
- MemberSpecializationInfo *getMemberSpecializationInfo() const;
-
- /// \brief Specify that this record is an instantiation of the
- /// member function FD.
- void setInstantiationOfMemberFunction(FunctionDecl *FD,
- TemplateSpecializationKind TSK) {
- setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
- }
-
- /// \brief Retrieves the function template that is described by this
- /// function declaration.
- ///
- /// Every function template is represented as a FunctionTemplateDecl
- /// and a FunctionDecl (or something derived from FunctionDecl). The
- /// former contains template properties (such as the template
- /// parameter lists) while the latter contains the actual
- /// description of the template's
- /// contents. FunctionTemplateDecl::getTemplatedDecl() retrieves the
- /// FunctionDecl that describes the function template,
- /// getDescribedFunctionTemplate() retrieves the
- /// FunctionTemplateDecl from a FunctionDecl.
- FunctionTemplateDecl *getDescribedFunctionTemplate() const;
-
- void setDescribedFunctionTemplate(FunctionTemplateDecl *Template);
-
- /// \brief Determine whether this function is a function template
- /// specialization.
- bool isFunctionTemplateSpecialization() const {
- return getPrimaryTemplate() != nullptr;
- }
-
- /// \brief Retrieve the class scope template pattern that this function
- /// template specialization is instantiated from.
- FunctionDecl *getClassScopeSpecializationPattern() const;
-
- /// \brief If this function is actually a function template specialization,
- /// retrieve information about this function template specialization.
- /// Otherwise, returns NULL.
- FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const;
-
- /// \brief Determines whether this function is a function template
- /// specialization or a member of a class template specialization that can
- /// be implicitly instantiated.
- bool isImplicitlyInstantiable() const;
-
- /// \brief Determines if the given function was instantiated from a
- /// function template.
- bool isTemplateInstantiation() const;
-
- /// \brief Retrieve the function declaration from which this function could
- /// be instantiated, if it is an instantiation (rather than a non-template
- /// or a specialization, for example).
- FunctionDecl *getTemplateInstantiationPattern() const;
-
- /// \brief Retrieve the primary template that this function template
- /// specialization either specializes or was instantiated from.
- ///
- /// If this function declaration is not a function template specialization,
- /// returns NULL.
- FunctionTemplateDecl *getPrimaryTemplate() const;
-
- /// \brief Retrieve the template arguments used to produce this function
- /// template specialization from the primary template.
- ///
- /// If this function declaration is not a function template specialization,
- /// returns NULL.
- const TemplateArgumentList *getTemplateSpecializationArgs() const;
-
- /// \brief Retrieve the template argument list as written in the sources,
- /// if any.
- ///
- /// If this function declaration is not a function template specialization
- /// or if it had no explicit template argument list, returns NULL.
- /// Note that it an explicit template argument list may be written empty,
- /// e.g., template<> void foo<>(char* s);
- const ASTTemplateArgumentListInfo*
- getTemplateSpecializationArgsAsWritten() const;
-
- /// \brief Specify that this function declaration is actually a function
- /// template specialization.
- ///
- /// \param Template the function template that this function template
- /// specialization specializes.
- ///
- /// \param TemplateArgs the template arguments that produced this
- /// function template specialization from the template.
- ///
- /// \param InsertPos If non-NULL, the position in the function template
- /// specialization set where the function template specialization data will
- /// be inserted.
- ///
- /// \param TSK the kind of template specialization this is.
- ///
- /// \param TemplateArgsAsWritten location info of template arguments.
- ///
- /// \param PointOfInstantiation point at which the function template
- /// specialization was first instantiated.
- void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs,
- void *InsertPos,
- TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
- const TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr,
- SourceLocation PointOfInstantiation = SourceLocation()) {
- setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
- InsertPos, TSK, TemplateArgsAsWritten,
- PointOfInstantiation);
- }
-
- /// \brief Specifies that this function declaration is actually a
- /// dependent function template specialization.
- void setDependentTemplateSpecialization(ASTContext &Context,
- const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
-
- DependentFunctionTemplateSpecializationInfo *
- getDependentSpecializationInfo() const;
-
- /// \brief Determine what kind of template instantiation this function
- /// represents.
- TemplateSpecializationKind getTemplateSpecializationKind() const;
-
- /// \brief Determine what kind of template instantiation this function
- /// represents.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
- SourceLocation PointOfInstantiation = SourceLocation());
-
- /// \brief Retrieve the (first) point of instantiation of a function template
- /// specialization or a member of a class template specialization.
- ///
- /// \returns the first point of instantiation, if this function was
- /// instantiated from a template; otherwise, returns an invalid source
- /// location.
- SourceLocation getPointOfInstantiation() const;
-
- /// \brief Determine whether this is or was instantiated from an out-of-line
- /// definition of a member function.
- bool isOutOfLine() const override;
-
- /// \brief Identify a memory copying or setting function.
- /// If the given function is a memory copy or setting function, returns
- /// the corresponding Builtin ID. If the function is not a memory function,
- /// returns 0.
- unsigned getMemoryFunctionKind() const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstFunction && K <= lastFunction;
- }
- static DeclContext *castToDeclContext(const FunctionDecl *D) {
- return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
- }
- static FunctionDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-
-/// FieldDecl - An instance of this class is created by Sema::ActOnField to
-/// represent a member of a struct/union/class.
-class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
- // FIXME: This can be packed into the bitfields in Decl.
- bool Mutable : 1;
- mutable unsigned CachedFieldIndex : 31;
-
- /// The kinds of value we can store in InitializerOrBitWidth.
- ///
- /// Note that this is compatible with InClassInitStyle except for
- /// ISK_CapturedVLAType.
- enum InitStorageKind {
- /// If the pointer is null, there's nothing special. Otherwise,
- /// this is a bitfield and the pointer is the Expr* storing the
- /// bit-width.
- ISK_BitWidthOrNothing = (unsigned) ICIS_NoInit,
-
- /// The pointer is an (optional due to delayed parsing) Expr*
- /// holding the copy-initializer.
- ISK_InClassCopyInit = (unsigned) ICIS_CopyInit,
-
- /// The pointer is an (optional due to delayed parsing) Expr*
- /// holding the list-initializer.
- ISK_InClassListInit = (unsigned) ICIS_ListInit,
-
- /// The pointer is a VariableArrayType* that's been captured;
- /// the enclosing context is a lambda or captured statement.
- ISK_CapturedVLAType,
- };
-
- /// \brief Storage for either the bit-width, the in-class
- /// initializer, or the captured variable length array bound.
- ///
- /// We can safely combine these because in-class initializers are
- /// not permitted for bit-fields, and both are exclusive with VLA
- /// captures.
- ///
- /// If the storage kind is ISK_InClassCopyInit or
- /// ISK_InClassListInit, but the initializer is null, then this
- /// field has an in-class initializer which has not yet been parsed
- /// and attached.
- llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage;
-protected:
- FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
- InClassInitStyle InitStyle)
- : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
- Mutable(Mutable), CachedFieldIndex(0),
- InitStorage(BW, (InitStorageKind) InitStyle) {
- assert((!BW || InitStyle == ICIS_NoInit) && "got initializer for bitfield");
- }
-
-public:
- static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
- InClassInitStyle InitStyle);
-
- static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// getFieldIndex - Returns the index of this field within its record,
- /// as appropriate for passing to ASTRecordLayout::getFieldOffset.
- unsigned getFieldIndex() const;
-
- /// isMutable - Determines whether this field is mutable (C++ only).
- bool isMutable() const { return Mutable; }
-
- /// \brief Determines whether this field is a bitfield.
- bool isBitField() const {
- return InitStorage.getInt() == ISK_BitWidthOrNothing &&
- InitStorage.getPointer() != nullptr;
- }
-
- /// @brief Determines whether this is an unnamed bitfield.
- bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
-
- /// isAnonymousStructOrUnion - Determines whether this field is a
- /// representative for an anonymous struct or union. Such fields are
- /// unnamed and are implicitly generated by the implementation to
- /// store the data for the anonymous union or struct.
- bool isAnonymousStructOrUnion() const;
-
- Expr *getBitWidth() const {
- return isBitField()
- ? static_cast<Expr *>(InitStorage.getPointer())
- : nullptr;
- }
- unsigned getBitWidthValue(const ASTContext &Ctx) const;
-
- /// setBitWidth - Set the bit-field width for this member.
- // Note: used by some clients (i.e., do not remove it).
- void setBitWidth(Expr *Width) {
- assert(InitStorage.getInt() == ISK_BitWidthOrNothing &&
- InitStorage.getPointer() == nullptr &&
- "bit width, initializer or captured type already set");
- InitStorage.setPointerAndInt(Width, ISK_BitWidthOrNothing);
- }
-
- /// removeBitWidth - Remove the bit-field width from this member.
- // Note: used by some clients (i.e., do not remove it).
- void removeBitWidth() {
- assert(isBitField() && "no bitfield width to remove");
- InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
- }
-
- /// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
- /// this field has.
- InClassInitStyle getInClassInitStyle() const {
- InitStorageKind storageKind = InitStorage.getInt();
- return (storageKind == ISK_CapturedVLAType
- ? ICIS_NoInit : (InClassInitStyle) storageKind);
- }
-
- /// hasInClassInitializer - Determine whether this member has a C++11 in-class
- /// initializer.
- bool hasInClassInitializer() const {
- return getInClassInitStyle() != ICIS_NoInit;
- }
-
- /// getInClassInitializer - Get the C++11 in-class initializer for this
- /// member, or null if one has not been set. If a valid declaration has an
- /// in-class initializer, but this returns null, then we have not parsed and
- /// attached it yet.
- Expr *getInClassInitializer() const {
- return hasInClassInitializer()
- ? static_cast<Expr *>(InitStorage.getPointer())
- : nullptr;
- }
-
- /// setInClassInitializer - Set the C++11 in-class initializer for this
- /// member.
- void setInClassInitializer(Expr *Init) {
- assert(hasInClassInitializer() &&
- InitStorage.getPointer() == nullptr &&
- "bit width, initializer or captured type already set");
- InitStorage.setPointer(Init);
- }
-
- /// removeInClassInitializer - Remove the C++11 in-class initializer from this
- /// member.
- void removeInClassInitializer() {
- assert(hasInClassInitializer() && "no initializer to remove");
- InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing);
- }
-
- /// \brief Determine whether this member captures the variable length array
- /// type.
- bool hasCapturedVLAType() const {
- return InitStorage.getInt() == ISK_CapturedVLAType;
- }
-
- /// \brief Get the captured variable length array type.
- const VariableArrayType *getCapturedVLAType() const {
- return hasCapturedVLAType() ? static_cast<const VariableArrayType *>(
- InitStorage.getPointer())
- : nullptr;
- }
- /// \brief Set the captured variable length array type for this field.
- void setCapturedVLAType(const VariableArrayType *VLAType);
-
- /// getParent - Returns the parent of this field declaration, which
- /// is the struct in which this method is defined.
- const RecordDecl *getParent() const {
- return cast<RecordDecl>(getDeclContext());
- }
-
- RecordDecl *getParent() {
- return cast<RecordDecl>(getDeclContext());
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Retrieves the canonical declaration of this field.
- FieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// EnumConstantDecl - An instance of this object exists for each enum constant
-/// that is defined. For example, in "enum X {a,b}", each of a/b are
-/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
-/// TagType for the X EnumDecl.
-class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> {
- Stmt *Init; // an integer constant expression
- llvm::APSInt Val; // The value.
-protected:
- EnumConstantDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, Expr *E,
- const llvm::APSInt &V)
- : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {}
-
-public:
-
- static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, Expr *E,
- const llvm::APSInt &V);
- static EnumConstantDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- const Expr *getInitExpr() const { return (const Expr*) Init; }
- Expr *getInitExpr() { return (Expr*) Init; }
- const llvm::APSInt &getInitVal() const { return Val; }
-
- void setInitExpr(Expr *E) { Init = (Stmt*) E; }
- void setInitVal(const llvm::APSInt &V) { Val = V; }
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Retrieves the canonical declaration of this enumerator.
- EnumConstantDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == EnumConstant; }
-
- friend class StmtIteratorBase;
-};
-
-/// IndirectFieldDecl - An instance of this class is created to represent a
-/// field injected from an anonymous union/struct into the parent scope.
-/// IndirectFieldDecl are always implicit.
-class IndirectFieldDecl : public ValueDecl,
- public Mergeable<IndirectFieldDecl> {
- void anchor() override;
- NamedDecl **Chaining;
- unsigned ChainingSize;
-
- IndirectFieldDecl(DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T,
- NamedDecl **CH, unsigned CHS)
- : ValueDecl(IndirectField, DC, L, N, T), Chaining(CH), ChainingSize(CHS) {}
-
-public:
- static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- QualType T, NamedDecl **CH, unsigned CHS);
-
- static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- typedef NamedDecl * const *chain_iterator;
- typedef llvm::iterator_range<chain_iterator> chain_range;
-
- chain_range chain() const { return chain_range(chain_begin(), chain_end()); }
- chain_iterator chain_begin() const { return chain_iterator(Chaining); }
- chain_iterator chain_end() const {
- return chain_iterator(Chaining + ChainingSize);
- }
-
- unsigned getChainingSize() const { return ChainingSize; }
-
- FieldDecl *getAnonField() const {
- assert(ChainingSize >= 2);
- return cast<FieldDecl>(Chaining[ChainingSize - 1]);
- }
-
- VarDecl *getVarDecl() const {
- assert(ChainingSize >= 2);
- return dyn_cast<VarDecl>(*chain_begin());
- }
-
- IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const IndirectFieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == IndirectField; }
- friend class ASTDeclReader;
-};
-
-/// TypeDecl - Represents a declaration of a type.
-///
-class TypeDecl : public NamedDecl {
- void anchor() override;
- /// TypeForDecl - This indicates the Type object that represents
- /// this TypeDecl. It is a cache maintained by
- /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
- /// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
- mutable const Type *TypeForDecl;
- /// LocStart - The start of the source range for this declaration.
- SourceLocation LocStart;
- friend class ASTContext;
-
-protected:
- TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- SourceLocation StartL = SourceLocation())
- : NamedDecl(DK, DC, L, Id), TypeForDecl(nullptr), LocStart(StartL) {}
-
-public:
- // Low-level accessor. If you just want the type defined by this node,
- // check out ASTContext::getTypeDeclType or one of
- // ASTContext::getTypedefType, ASTContext::getRecordType, etc. if you
- // already know the specific kind of node this is.
- const Type *getTypeForDecl() const { return TypeForDecl; }
- void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
- void setLocStart(SourceLocation L) { LocStart = L; }
- SourceRange getSourceRange() const override LLVM_READONLY {
- if (LocStart.isValid())
- return SourceRange(LocStart, getLocation());
- else
- return SourceRange(getLocation());
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstType && K <= lastType; }
-};
-
-
-/// Base class for declarations which introduce a typedef-name.
-class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
- void anchor() override;
- typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
- llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
-
-protected:
- TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
- MaybeModedTInfo(TInfo) {}
-
- typedef Redeclarable<TypedefNameDecl> redeclarable_base;
- TypedefNameDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- TypedefNameDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- TypedefNameDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- bool isModed() const { return MaybeModedTInfo.is<ModedTInfo*>(); }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return isModed()
- ? MaybeModedTInfo.get<ModedTInfo*>()->first
- : MaybeModedTInfo.get<TypeSourceInfo*>();
- }
- QualType getUnderlyingType() const {
- return isModed()
- ? MaybeModedTInfo.get<ModedTInfo*>()->second
- : MaybeModedTInfo.get<TypeSourceInfo*>()->getType();
- }
- void setTypeSourceInfo(TypeSourceInfo *newType) {
- MaybeModedTInfo = newType;
- }
- void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) {
- MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy);
- }
-
- /// Retrieves the canonical declaration of this typedef-name.
- TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- /// Retrieves the tag declaration for which this is the typedef name for
- /// linkage purposes, if any.
- ///
- /// \param AnyRedecl Look for the tag declaration in any redeclaration of
- /// this typedef declaration.
- TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstTypedefName && K <= lastTypedefName;
- }
-};
-
-/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
-/// type specifier.
-class TypedefDecl : public TypedefNameDecl {
- TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {}
-
-public:
- static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo);
- static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Typedef; }
-};
-
-/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
-/// alias-declaration.
-class TypeAliasDecl : public TypedefNameDecl {
- /// The template for which this is the pattern, if any.
- TypeAliasTemplateDecl *Template;
-
- TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo),
- Template(nullptr) {}
-
-public:
- static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo);
- static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- TypeAliasTemplateDecl *getDescribedAliasTemplate() const { return Template; }
- void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT) { Template = TAT; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TypeAlias; }
-};
-
-/// TagDecl - Represents the declaration of a struct/union/class/enum.
-class TagDecl
- : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
-public:
- // This is really ugly.
- typedef TagTypeKind TagKind;
-
-private:
- // FIXME: This can be packed into the bitfields in Decl.
- /// TagDeclKind - The TagKind enum.
- unsigned TagDeclKind : 3;
-
- /// IsCompleteDefinition - True if this is a definition ("struct foo
- /// {};"), false if it is a declaration ("struct foo;"). It is not
- /// a definition until the definition has been fully processed.
- bool IsCompleteDefinition : 1;
-
-protected:
- /// IsBeingDefined - True if this is currently being defined.
- bool IsBeingDefined : 1;
-
-private:
- /// IsEmbeddedInDeclarator - True if this tag declaration is
- /// "embedded" (i.e., defined or declared for the very first time)
- /// in the syntax of a declarator.
- bool IsEmbeddedInDeclarator : 1;
-
- /// \brief True if this tag is free standing, e.g. "struct foo;".
- bool IsFreeStanding : 1;
-
-protected:
- // These are used by (and only defined for) EnumDecl.
- unsigned NumPositiveBits : 8;
- unsigned NumNegativeBits : 8;
-
- /// IsScoped - True if this tag declaration is a scoped enumeration. Only
- /// possible in C++11 mode.
- bool IsScoped : 1;
- /// IsScopedUsingClassTag - If this tag declaration is a scoped enum,
- /// then this is true if the scoped enum was declared using the class
- /// tag, false if it was declared with the struct tag. No meaning is
- /// associated if this tag declaration is not a scoped enum.
- bool IsScopedUsingClassTag : 1;
-
- /// IsFixed - True if this is an enumeration with fixed underlying type. Only
- /// possible in C++11, Microsoft extensions, or Objective C mode.
- bool IsFixed : 1;
-
- /// \brief Indicates whether it is possible for declarations of this kind
- /// to have an out-of-date definition.
- ///
- /// This option is only enabled when modules are enabled.
- bool MayHaveOutOfDateDef : 1;
-
- /// Has the full definition of this type been required by a use somewhere in
- /// the TU.
- bool IsCompleteDefinitionRequired : 1;
-private:
- SourceLocation RBraceLoc;
-
- // A struct representing syntactic qualifier info,
- // to be used for the (uncommon) case of out-of-line declarations.
- typedef QualifierInfo ExtInfo;
-
- /// \brief If the (out-of-line) tag declaration name
- /// is qualified, it points to the qualifier info (nns and range);
- /// otherwise, if the tag declaration is anonymous and it is part of
- /// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
- /// otherwise, if the tag declaration is anonymous and it is used as a
- /// declaration specifier for variables, it points to the first VarDecl (used
- /// for mangling);
- /// otherwise, it is a null (TypedefNameDecl) pointer.
- llvm::PointerUnion<TypedefNameDecl *, ExtInfo *> TypedefNameDeclOrQualifier;
-
- bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo *>(); }
- ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo *>(); }
- const ExtInfo *getExtInfo() const {
- return TypedefNameDeclOrQualifier.get<ExtInfo *>();
- }
-
-protected:
- TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
- SourceLocation StartL)
- : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C),
- TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false),
- IsEmbeddedInDeclarator(false), IsFreeStanding(false),
- IsCompleteDefinitionRequired(false),
- TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) {
- assert((DK != Enum || TK == TTK_Enum) &&
- "EnumDecl not matched with TTK_Enum");
- setPreviousDecl(PrevDecl);
- }
-
- typedef Redeclarable<TagDecl> redeclarable_base;
- TagDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- TagDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- TagDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
- /// @brief Completes the definition of this tag declaration.
- ///
- /// This is a helper function for derived classes.
- void completeDefinition();
-
-public:
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- SourceLocation getRBraceLoc() const { return RBraceLoc; }
- void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
-
- /// getInnerLocStart - Return SourceLocation representing start of source
- /// range ignoring outer template declarations.
- SourceLocation getInnerLocStart() const { return getLocStart(); }
-
- /// getOuterLocStart - Return SourceLocation representing start of source
- /// range taking into account any outer template declarations.
- SourceLocation getOuterLocStart() const;
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- TagDecl *getCanonicalDecl() override;
- const TagDecl *getCanonicalDecl() const {
- return const_cast<TagDecl*>(this)->getCanonicalDecl();
- }
-
- /// isThisDeclarationADefinition() - Return true if this declaration
- /// is a completion definition of the type. Provided for consistency.
- bool isThisDeclarationADefinition() const {
- return isCompleteDefinition();
- }
-
- /// isCompleteDefinition - Return true if this decl has its body
- /// fully specified.
- bool isCompleteDefinition() const {
- return IsCompleteDefinition;
- }
-
- /// \brief Return true if this complete decl is
- /// required to be complete for some existing use.
- bool isCompleteDefinitionRequired() const {
- return IsCompleteDefinitionRequired;
- }
-
- /// isBeingDefined - Return true if this decl is currently being defined.
- bool isBeingDefined() const {
- return IsBeingDefined;
- }
-
- bool isEmbeddedInDeclarator() const {
- return IsEmbeddedInDeclarator;
- }
- void setEmbeddedInDeclarator(bool isInDeclarator) {
- IsEmbeddedInDeclarator = isInDeclarator;
- }
-
- bool isFreeStanding() const { return IsFreeStanding; }
- void setFreeStanding(bool isFreeStanding = true) {
- IsFreeStanding = isFreeStanding;
- }
-
- /// \brief Whether this declaration declares a type that is
- /// dependent, i.e., a type that somehow depends on template
- /// parameters.
- bool isDependentType() const { return isDependentContext(); }
-
- /// @brief Starts the definition of this tag declaration.
- ///
- /// This method should be invoked at the beginning of the definition
- /// of this tag declaration. It will set the tag type into a state
- /// where it is in the process of being defined.
- void startDefinition();
-
- /// getDefinition - Returns the TagDecl that actually defines this
- /// struct/union/class/enum. When determining whether or not a
- /// struct/union/class/enum has a definition, one should use this
- /// method as opposed to 'isDefinition'. 'isDefinition' indicates
- /// whether or not a specific TagDecl is defining declaration, not
- /// whether or not the struct/union/class/enum type is defined.
- /// This method returns NULL if there is no TagDecl that defines
- /// the struct/union/class/enum.
- TagDecl *getDefinition() const;
-
- void setCompleteDefinition(bool V) { IsCompleteDefinition = V; }
-
- void setCompleteDefinitionRequired(bool V = true) {
- IsCompleteDefinitionRequired = V;
- }
-
- StringRef getKindName() const {
- return TypeWithKeyword::getTagTypeKindName(getTagKind());
- }
-
- TagKind getTagKind() const {
- return TagKind(TagDeclKind);
- }
-
- void setTagKind(TagKind TK) { TagDeclKind = TK; }
-
- bool isStruct() const { return getTagKind() == TTK_Struct; }
- bool isInterface() const { return getTagKind() == TTK_Interface; }
- bool isClass() const { return getTagKind() == TTK_Class; }
- bool isUnion() const { return getTagKind() == TTK_Union; }
- bool isEnum() const { return getTagKind() == TTK_Enum; }
-
- /// Is this tag type named, either directly or via being defined in
- /// a typedef of this type?
- ///
- /// C++11 [basic.link]p8:
- /// A type is said to have linkage if and only if:
- /// - it is a class or enumeration type that is named (or has a
- /// name for linkage purposes) and the name has linkage; ...
- /// C++11 [dcl.typedef]p9:
- /// If the typedef declaration defines an unnamed class (or enum),
- /// the first typedef-name declared by the declaration to be that
- /// class type (or enum type) is used to denote the class type (or
- /// enum type) for linkage purposes only.
- ///
- /// C does not have an analogous rule, but the same concept is
- /// nonetheless useful in some places.
- bool hasNameForLinkage() const {
- return (getDeclName() || getTypedefNameForAnonDecl());
- }
-
- TypedefNameDecl *getTypedefNameForAnonDecl() const {
- return hasExtInfo() ? nullptr
- : TypedefNameDeclOrQualifier.get<TypedefNameDecl *>();
- }
-
- void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
-
- /// \brief Retrieve the nested-name-specifier that qualifies the name of this
- /// declaration, if it was present in the source.
- NestedNameSpecifier *getQualifier() const {
- return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
- : nullptr;
- }
-
- /// \brief Retrieve the nested-name-specifier (with source-location
- /// information) that qualifies the name of this declaration, if it was
- /// present in the source.
- NestedNameSpecifierLoc getQualifierLoc() const {
- return hasExtInfo() ? getExtInfo()->QualifierLoc
- : NestedNameSpecifierLoc();
- }
-
- void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
-
- unsigned getNumTemplateParameterLists() const {
- return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
- }
- TemplateParameterList *getTemplateParameterList(unsigned i) const {
- assert(i < getNumTemplateParameterLists());
- return getExtInfo()->TemplParamLists[i];
- }
- void setTemplateParameterListsInfo(ASTContext &Context,
- ArrayRef<TemplateParameterList *> TPLists);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; }
-
- static DeclContext *castToDeclContext(const TagDecl *D) {
- return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
- }
- static TagDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// EnumDecl - Represents an enum. In C++11, enums can be forward-declared
-/// with a fixed underlying type, and in C we allow them to be forward-declared
-/// with no underlying type as an extension.
-class EnumDecl : public TagDecl {
- void anchor() override;
- /// IntegerType - This represent the integer type that the enum corresponds
- /// to for code generation purposes. Note that the enumerator constants may
- /// have a different type than this does.
- ///
- /// If the underlying integer type was explicitly stated in the source
- /// code, this is a TypeSourceInfo* for that type. Otherwise this type
- /// was automatically deduced somehow, and this is a Type*.
- ///
- /// Normally if IsFixed(), this would contain a TypeSourceInfo*, but in
- /// some cases it won't.
- ///
- /// The underlying type of an enumeration never has any qualifiers, so
- /// we can get away with just storing a raw Type*, and thus save an
- /// extra pointer when TypeSourceInfo is needed.
-
- llvm::PointerUnion<const Type*, TypeSourceInfo*> IntegerType;
-
- /// PromotionType - The integer type that values of this type should
- /// promote to. In C, enumerators are generally of an integer type
- /// directly, but gcc-style large enumerators (and all enumerators
- /// in C++) are of the enum type instead.
- QualType PromotionType;
-
- /// \brief If this enumeration is an instantiation of a member enumeration
- /// of a class template specialization, this is the member specialization
- /// information.
- MemberSpecializationInfo *SpecializationInfo;
-
- EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
- bool Scoped, bool ScopedUsingClassTag, bool Fixed)
- : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc),
- SpecializationInfo(nullptr) {
- assert(Scoped || !ScopedUsingClassTag);
- IntegerType = (const Type *)nullptr;
- NumNegativeBits = 0;
- NumPositiveBits = 0;
- IsScoped = Scoped;
- IsScopedUsingClassTag = ScopedUsingClassTag;
- IsFixed = Fixed;
- }
-
- void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
- TemplateSpecializationKind TSK);
-public:
- EnumDecl *getCanonicalDecl() override {
- return cast<EnumDecl>(TagDecl::getCanonicalDecl());
- }
- const EnumDecl *getCanonicalDecl() const {
- return const_cast<EnumDecl*>(this)->getCanonicalDecl();
- }
-
- EnumDecl *getPreviousDecl() {
- return cast_or_null<EnumDecl>(
- static_cast<TagDecl *>(this)->getPreviousDecl());
- }
- const EnumDecl *getPreviousDecl() const {
- return const_cast<EnumDecl*>(this)->getPreviousDecl();
- }
-
- EnumDecl *getMostRecentDecl() {
- return cast<EnumDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
- }
- const EnumDecl *getMostRecentDecl() const {
- return const_cast<EnumDecl*>(this)->getMostRecentDecl();
- }
-
- EnumDecl *getDefinition() const {
- return cast_or_null<EnumDecl>(TagDecl::getDefinition());
- }
-
- static EnumDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, EnumDecl *PrevDecl,
- bool IsScoped, bool IsScopedUsingClassTag,
- bool IsFixed);
- static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// completeDefinition - When created, the EnumDecl corresponds to a
- /// forward-declared enum. This method is used to mark the
- /// declaration as being defined; it's enumerators have already been
- /// added (via DeclContext::addDecl). NewType is the new underlying
- /// type of the enumeration type.
- void completeDefinition(QualType NewType,
- QualType PromotionType,
- unsigned NumPositiveBits,
- unsigned NumNegativeBits);
-
- // enumerator_iterator - Iterates through the enumerators of this
- // enumeration.
- typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>
- enumerator_range;
-
- enumerator_range enumerators() const {
- return enumerator_range(enumerator_begin(), enumerator_end());
- }
-
- enumerator_iterator enumerator_begin() const {
- const EnumDecl *E = getDefinition();
- if (!E)
- E = this;
- return enumerator_iterator(E->decls_begin());
- }
-
- enumerator_iterator enumerator_end() const {
- const EnumDecl *E = getDefinition();
- if (!E)
- E = this;
- return enumerator_iterator(E->decls_end());
- }
-
- /// getPromotionType - Return the integer type that enumerators
- /// should promote to.
- QualType getPromotionType() const { return PromotionType; }
-
- /// \brief Set the promotion type.
- void setPromotionType(QualType T) { PromotionType = T; }
-
- /// getIntegerType - Return the integer type this enum decl corresponds to.
- /// This returns a null QualType for an enum forward definition with no fixed
- /// underlying type.
- QualType getIntegerType() const {
- if (!IntegerType)
- return QualType();
- if (const Type *T = IntegerType.dyn_cast<const Type*>())
- return QualType(T, 0);
- return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType();
- }
-
- /// \brief Set the underlying integer type.
- void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
-
- /// \brief Set the underlying integer type source info.
- void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; }
-
- /// \brief Return the type source info for the underlying integer type,
- /// if no type source info exists, return 0.
- TypeSourceInfo *getIntegerTypeSourceInfo() const {
- return IntegerType.dyn_cast<TypeSourceInfo*>();
- }
-
- /// \brief Retrieve the source range that covers the underlying type if
- /// specified.
- SourceRange getIntegerTypeRange() const LLVM_READONLY;
-
- /// \brief Returns the width in bits required to store all the
- /// non-negative enumerators of this enum.
- unsigned getNumPositiveBits() const {
- return NumPositiveBits;
- }
- void setNumPositiveBits(unsigned Num) {
- NumPositiveBits = Num;
- assert(NumPositiveBits == Num && "can't store this bitcount");
- }
-
- /// \brief Returns the width in bits required to store all the
- /// negative enumerators of this enum. These widths include
- /// the rightmost leading 1; that is:
- ///
- /// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS
- /// ------------------------ ------- -----------------
- /// -1 1111111 1
- /// -10 1110110 5
- /// -101 1001011 8
- unsigned getNumNegativeBits() const {
- return NumNegativeBits;
- }
- void setNumNegativeBits(unsigned Num) {
- NumNegativeBits = Num;
- }
-
- /// \brief Returns true if this is a C++11 scoped enumeration.
- bool isScoped() const {
- return IsScoped;
- }
-
- /// \brief Returns true if this is a C++11 scoped enumeration.
- bool isScopedUsingClassTag() const {
- return IsScopedUsingClassTag;
- }
-
- /// \brief Returns true if this is an Objective-C, C++11, or
- /// Microsoft-style enumeration with a fixed underlying type.
- bool isFixed() const {
- return IsFixed;
- }
-
- /// \brief Returns true if this can be considered a complete type.
- bool isComplete() const {
- return isCompleteDefinition() || isFixed();
- }
-
- /// \brief Returns the enumeration (declared within the template)
- /// from which this enumeration type was instantiated, or NULL if
- /// this enumeration was not instantiated from any template.
- EnumDecl *getInstantiatedFromMemberEnum() const;
-
- /// \brief If this enumeration is a member of a specialization of a
- /// templated class, determine what kind of template specialization
- /// or instantiation this is.
- TemplateSpecializationKind getTemplateSpecializationKind() const;
-
- /// \brief For an enumeration member that was instantiated from a member
- /// enumeration of a templated class, set the template specialiation kind.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
- SourceLocation PointOfInstantiation = SourceLocation());
-
- /// \brief If this enumeration is an instantiation of a member enumeration of
- /// a class template specialization, retrieves the member specialization
- /// information.
- MemberSpecializationInfo *getMemberSpecializationInfo() const {
- return SpecializationInfo;
- }
-
- /// \brief Specify that this enumeration is an instantiation of the
- /// member enumeration ED.
- void setInstantiationOfMemberEnum(EnumDecl *ED,
- TemplateSpecializationKind TSK) {
- setInstantiationOfMemberEnum(getASTContext(), ED, TSK);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Enum; }
-
- friend class ASTDeclReader;
-};
-
-
-/// RecordDecl - Represents a struct/union/class. For example:
-/// struct X; // Forward declaration, no "body".
-/// union Y { int A, B; }; // Has body with members A and B (FieldDecls).
-/// This decl will be marked invalid if *any* members are invalid.
-///
-class RecordDecl : public TagDecl {
- // FIXME: This can be packed into the bitfields in Decl.
- /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
- /// array member (e.g. int X[]) or if this union contains a struct that does.
- /// If so, this cannot be contained in arrays or other structs as a member.
- bool HasFlexibleArrayMember : 1;
-
- /// AnonymousStructOrUnion - Whether this is the type of an anonymous struct
- /// or union.
- bool AnonymousStructOrUnion : 1;
-
- /// HasObjectMember - This is true if this struct has at least one member
- /// containing an Objective-C object pointer type.
- bool HasObjectMember : 1;
-
- /// HasVolatileMember - This is true if struct has at least one member of
- /// 'volatile' type.
- bool HasVolatileMember : 1;
-
- /// \brief Whether the field declarations of this record have been loaded
- /// from external storage. To avoid unnecessary deserialization of
- /// methods/nested types we allow deserialization of just the fields
- /// when needed.
- mutable bool LoadedFieldsFromExternalStorage : 1;
- friend class DeclContext;
-
-protected:
- RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, RecordDecl *PrevDecl);
-
-public:
- static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr);
- static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
-
- RecordDecl *getPreviousDecl() {
- return cast_or_null<RecordDecl>(
- static_cast<TagDecl *>(this)->getPreviousDecl());
- }
- const RecordDecl *getPreviousDecl() const {
- return const_cast<RecordDecl*>(this)->getPreviousDecl();
- }
-
- RecordDecl *getMostRecentDecl() {
- return cast<RecordDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
- }
- const RecordDecl *getMostRecentDecl() const {
- return const_cast<RecordDecl*>(this)->getMostRecentDecl();
- }
-
- bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
- void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
-
- /// isAnonymousStructOrUnion - Whether this is an anonymous struct
- /// or union. To be an anonymous struct or union, it must have been
- /// declared without a name and there must be no objects of this
- /// type declared, e.g.,
- /// @code
- /// union { int i; float f; };
- /// @endcode
- /// is an anonymous union but neither of the following are:
- /// @code
- /// union X { int i; float f; };
- /// union { int i; float f; } obj;
- /// @endcode
- bool isAnonymousStructOrUnion() const { return AnonymousStructOrUnion; }
- void setAnonymousStructOrUnion(bool Anon) {
- AnonymousStructOrUnion = Anon;
- }
-
- bool hasObjectMember() const { return HasObjectMember; }
- void setHasObjectMember (bool val) { HasObjectMember = val; }
-
- bool hasVolatileMember() const { return HasVolatileMember; }
- void setHasVolatileMember (bool val) { HasVolatileMember = val; }
-
- bool hasLoadedFieldsFromExternalStorage() const {
- return LoadedFieldsFromExternalStorage;
- }
- void setHasLoadedFieldsFromExternalStorage(bool val) {
- LoadedFieldsFromExternalStorage = val;
- }
-
- /// \brief Determines whether this declaration represents the
- /// injected class name.
- ///
- /// The injected class name in C++ is the name of the class that
- /// appears inside the class itself. For example:
- ///
- /// \code
- /// struct C {
- /// // C is implicitly declared here as a synonym for the class name.
- /// };
- ///
- /// C::C c; // same as "C c;"
- /// \endcode
- bool isInjectedClassName() const;
-
- /// \brief Determine whether this record is a class describing a lambda
- /// function object.
- bool isLambda() const;
-
- /// \brief Determine whether this record is a record for captured variables in
- /// CapturedStmt construct.
- bool isCapturedRecord() const;
- /// \brief Mark the record as a record for captured variables in CapturedStmt
- /// construct.
- void setCapturedRecord();
-
- /// getDefinition - Returns the RecordDecl that actually defines
- /// this struct/union/class. When determining whether or not a
- /// struct/union/class is completely defined, one should use this
- /// method as opposed to 'isCompleteDefinition'.
- /// 'isCompleteDefinition' indicates whether or not a specific
- /// RecordDecl is a completed definition, not whether or not the
- /// record type is defined. This method returns NULL if there is
- /// no RecordDecl that defines the struct/union/tag.
- RecordDecl *getDefinition() const {
- return cast_or_null<RecordDecl>(TagDecl::getDefinition());
- }
-
- // Iterator access to field members. The field iterator only visits
- // the non-static data members of this class, ignoring any static
- // data members, functions, constructors, destructors, etc.
- typedef specific_decl_iterator<FieldDecl> field_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<FieldDecl>> field_range;
-
- field_range fields() const { return field_range(field_begin(), field_end()); }
- field_iterator field_begin() const;
-
- field_iterator field_end() const {
- return field_iterator(decl_iterator());
- }
-
- // field_empty - Whether there are any fields (non-static data
- // members) in this record.
- bool field_empty() const {
- return field_begin() == field_end();
- }
-
- /// completeDefinition - Notes that the definition of this type is
- /// now complete.
- virtual void completeDefinition();
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstRecord && K <= lastRecord;
- }
-
- /// isMsStrust - Get whether or not this is an ms_struct which can
- /// be turned on with an attribute, pragma, or -mms-bitfields
- /// commandline option.
- bool isMsStruct(const ASTContext &C) const;
-
- /// \brief Whether we are allowed to insert extra padding between fields.
- /// These padding are added to help AddressSanitizer detect
- /// intra-object-overflow bugs.
- bool mayInsertExtraPadding(bool EmitRemark = false) const;
-
- /// Finds the first data member which has a name.
- /// nullptr is returned if no named data member exists.
- const FieldDecl *findFirstNamedDataMember() const;
-
-private:
- /// \brief Deserialize just the fields.
- void LoadFieldsFromExternalStorage() const;
-};
-
-class FileScopeAsmDecl : public Decl {
- virtual void anchor();
- StringLiteral *AsmString;
- SourceLocation RParenLoc;
- FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring,
- SourceLocation StartL, SourceLocation EndL)
- : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {}
-public:
- static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC,
- StringLiteral *Str, SourceLocation AsmLoc,
- SourceLocation RParenLoc);
-
- static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceLocation getAsmLoc() const { return getLocation(); }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getAsmLoc(), getRParenLoc());
- }
-
- const StringLiteral *getAsmString() const { return AsmString; }
- StringLiteral *getAsmString() { return AsmString; }
- void setAsmString(StringLiteral *Asm) { AsmString = Asm; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == FileScopeAsm; }
-};
-
-/// BlockDecl - This represents a block literal declaration, which is like an
-/// unnamed FunctionDecl. For example:
-/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
-///
-class BlockDecl : public Decl, public DeclContext {
-public:
- /// A class which contains all the information about a particular
- /// captured value.
- class Capture {
- enum {
- flag_isByRef = 0x1,
- flag_isNested = 0x2
- };
-
- /// The variable being captured.
- llvm::PointerIntPair<VarDecl*, 2> VariableAndFlags;
-
- /// The copy expression, expressed in terms of a DeclRef (or
- /// BlockDeclRef) to the captured variable. Only required if the
- /// variable has a C++ class type.
- Expr *CopyExpr;
-
- public:
- Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
- : VariableAndFlags(variable,
- (byRef ? flag_isByRef : 0) | (nested ? flag_isNested : 0)),
- CopyExpr(copy) {}
-
- /// The variable being captured.
- VarDecl *getVariable() const { return VariableAndFlags.getPointer(); }
-
- /// Whether this is a "by ref" capture, i.e. a capture of a __block
- /// variable.
- bool isByRef() const { return VariableAndFlags.getInt() & flag_isByRef; }
-
- /// Whether this is a nested capture, i.e. the variable captured
- /// is not from outside the immediately enclosing function/block.
- bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; }
-
- bool hasCopyExpr() const { return CopyExpr != nullptr; }
- Expr *getCopyExpr() const { return CopyExpr; }
- void setCopyExpr(Expr *e) { CopyExpr = e; }
- };
-
-private:
- // FIXME: This can be packed into the bitfields in Decl.
- bool IsVariadic : 1;
- bool CapturesCXXThis : 1;
- bool BlockMissingReturnType : 1;
- bool IsConversionFromLambda : 1;
- /// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal
- /// parameters of this function. This is null if a prototype or if there are
- /// no formals.
- ParmVarDecl **ParamInfo;
- unsigned NumParams;
-
- Stmt *Body;
- TypeSourceInfo *SignatureAsWritten;
-
- const Capture *Captures;
- unsigned NumCaptures;
-
- unsigned ManglingNumber;
- Decl *ManglingContextDecl;
-
-protected:
- BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
- : Decl(Block, DC, CaretLoc), DeclContext(Block),
- IsVariadic(false), CapturesCXXThis(false),
- BlockMissingReturnType(true), IsConversionFromLambda(false),
- ParamInfo(nullptr), NumParams(0), Body(nullptr),
- SignatureAsWritten(nullptr), Captures(nullptr), NumCaptures(0),
- ManglingNumber(0), ManglingContextDecl(nullptr) {}
-
-public:
- static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
- static BlockDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceLocation getCaretLocation() const { return getLocation(); }
-
- bool isVariadic() const { return IsVariadic; }
- void setIsVariadic(bool value) { IsVariadic = value; }
-
- CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
- Stmt *getBody() const override { return (Stmt*) Body; }
- void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
-
- void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
- TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; }
-
- // Iterator access to formal parameters.
- unsigned param_size() const { return getNumParams(); }
- typedef ParmVarDecl **param_iterator;
- typedef ParmVarDecl * const *param_const_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
- typedef llvm::iterator_range<param_const_iterator> param_const_range;
-
- // ArrayRef access to formal parameters.
- // FIXME: Should eventual replace iterator access.
- ArrayRef<ParmVarDecl*> parameters() const {
- return llvm::makeArrayRef(ParamInfo, param_size());
- }
-
- bool param_empty() const { return NumParams == 0; }
- param_range params() { return param_range(param_begin(), param_end()); }
- param_iterator param_begin() { return param_iterator(ParamInfo); }
- param_iterator param_end() {
- return param_iterator(ParamInfo + param_size());
- }
-
- param_const_range params() const {
- return param_const_range(param_begin(), param_end());
- }
- param_const_iterator param_begin() const {
- return param_const_iterator(ParamInfo);
- }
- param_const_iterator param_end() const {
- return param_const_iterator(ParamInfo + param_size());
- }
-
- unsigned getNumParams() const { return NumParams; }
- const ParmVarDecl *getParamDecl(unsigned i) const {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- ParmVarDecl *getParamDecl(unsigned i) {
- assert(i < getNumParams() && "Illegal param #");
- return ParamInfo[i];
- }
- void setParams(ArrayRef<ParmVarDecl *> NewParamInfo);
-
- /// hasCaptures - True if this block (or its nested blocks) captures
- /// anything of local storage from its enclosing scopes.
- bool hasCaptures() const { return NumCaptures != 0 || CapturesCXXThis; }
-
- /// getNumCaptures - Returns the number of captured variables.
- /// Does not include an entry for 'this'.
- unsigned getNumCaptures() const { return NumCaptures; }
-
- typedef const Capture *capture_iterator;
- typedef const Capture *capture_const_iterator;
- typedef llvm::iterator_range<capture_iterator> capture_range;
- typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
-
- capture_range captures() {
- return capture_range(capture_begin(), capture_end());
- }
- capture_const_range captures() const {
- return capture_const_range(capture_begin(), capture_end());
- }
-
- capture_iterator capture_begin() { return Captures; }
- capture_iterator capture_end() { return Captures + NumCaptures; }
- capture_const_iterator capture_begin() const { return Captures; }
- capture_const_iterator capture_end() const { return Captures + NumCaptures; }
-
- bool capturesCXXThis() const { return CapturesCXXThis; }
- bool blockMissingReturnType() const { return BlockMissingReturnType; }
- void setBlockMissingReturnType(bool val) { BlockMissingReturnType = val; }
-
- bool isConversionFromLambda() const { return IsConversionFromLambda; }
- void setIsConversionFromLambda(bool val) { IsConversionFromLambda = val; }
-
- bool capturesVariable(const VarDecl *var) const;
-
- void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures,
- bool CapturesCXXThis);
-
- unsigned getBlockManglingNumber() const {
- return ManglingNumber;
- }
- Decl *getBlockManglingContextDecl() const {
- return ManglingContextDecl;
- }
-
- void setBlockMangling(unsigned Number, Decl *Ctx) {
- ManglingNumber = Number;
- ManglingContextDecl = Ctx;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Block; }
- static DeclContext *castToDeclContext(const BlockDecl *D) {
- return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
- }
- static BlockDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<BlockDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// \brief This represents the body of a CapturedStmt, and serves as its
-/// DeclContext.
-class CapturedDecl final
- : public Decl,
- public DeclContext,
- private llvm::TrailingObjects<CapturedDecl, ImplicitParamDecl *> {
-protected:
- size_t numTrailingObjects(OverloadToken<ImplicitParamDecl>) {
- return NumParams;
- }
-
-private:
- /// \brief The number of parameters to the outlined function.
- unsigned NumParams;
- /// \brief The position of context parameter in list of parameters.
- unsigned ContextParam;
- /// \brief The body of the outlined function.
- llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
-
- explicit CapturedDecl(DeclContext *DC, unsigned NumParams);
-
- ImplicitParamDecl *const *getParams() const {
- return getTrailingObjects<ImplicitParamDecl *>();
- }
-
- ImplicitParamDecl **getParams() {
- return getTrailingObjects<ImplicitParamDecl *>();
- }
-
-public:
- static CapturedDecl *Create(ASTContext &C, DeclContext *DC,
- unsigned NumParams);
- static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID,
- unsigned NumParams);
-
- Stmt *getBody() const override;
- void setBody(Stmt *B);
-
- bool isNothrow() const;
- void setNothrow(bool Nothrow = true);
-
- unsigned getNumParams() const { return NumParams; }
-
- ImplicitParamDecl *getParam(unsigned i) const {
- assert(i < NumParams);
- return getParams()[i];
- }
- void setParam(unsigned i, ImplicitParamDecl *P) {
- assert(i < NumParams);
- getParams()[i] = P;
- }
-
- /// \brief Retrieve the parameter containing captured variables.
- ImplicitParamDecl *getContextParam() const {
- assert(ContextParam < NumParams);
- return getParam(ContextParam);
- }
- void setContextParam(unsigned i, ImplicitParamDecl *P) {
- assert(i < NumParams);
- ContextParam = i;
- setParam(i, P);
- }
- unsigned getContextParamPosition() const { return ContextParam; }
-
- typedef ImplicitParamDecl *const *param_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
-
- /// \brief Retrieve an iterator pointing to the first parameter decl.
- param_iterator param_begin() const { return getParams(); }
- /// \brief Retrieve an iterator one past the last parameter decl.
- param_iterator param_end() const { return getParams() + NumParams; }
-
- /// \brief Retrieve an iterator range for the parameter declarations.
- param_range params() const { return param_range(param_begin(), param_end()); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Captured; }
- static DeclContext *castToDeclContext(const CapturedDecl *D) {
- return static_cast<DeclContext *>(const_cast<CapturedDecl *>(D));
- }
- static CapturedDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
-};
-
-/// \brief Describes a module import declaration, which makes the contents
-/// of the named module visible in the current translation unit.
-///
-/// An import declaration imports the named module (or submodule). For example:
-/// \code
-/// @import std.vector;
-/// \endcode
-///
-/// Import declarations can also be implicitly generated from
-/// \#include/\#import directives.
-class ImportDecl final : public Decl,
- llvm::TrailingObjects<ImportDecl, SourceLocation> {
- /// \brief The imported module, along with a bit that indicates whether
- /// we have source-location information for each identifier in the module
- /// name.
- ///
- /// When the bit is false, we only have a single source location for the
- /// end of the import declaration.
- llvm::PointerIntPair<Module *, 1, bool> ImportedAndComplete;
-
- /// \brief The next import in the list of imports local to the translation
- /// unit being parsed (not loaded from an AST file).
- ImportDecl *NextLocalImport;
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTContext;
- friend TrailingObjects;
-
- ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
- ArrayRef<SourceLocation> IdentifierLocs);
-
- ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
- SourceLocation EndLoc);
-
- ImportDecl(EmptyShell Empty) : Decl(Import, Empty), NextLocalImport() { }
-
-public:
- /// \brief Create a new module import declaration.
- static ImportDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, Module *Imported,
- ArrayRef<SourceLocation> IdentifierLocs);
-
- /// \brief Create a new module import declaration for an implicitly-generated
- /// import.
- static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, Module *Imported,
- SourceLocation EndLoc);
-
- /// \brief Create a new, deserialized module import declaration.
- static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID,
- unsigned NumLocations);
-
- /// \brief Retrieve the module that was imported by the import declaration.
- Module *getImportedModule() const { return ImportedAndComplete.getPointer(); }
-
- /// \brief Retrieves the locations of each of the identifiers that make up
- /// the complete module name in the import declaration.
- ///
- /// This will return an empty array if the locations of the individual
- /// identifiers aren't available.
- ArrayRef<SourceLocation> getIdentifierLocs() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Import; }
-};
-
-/// \brief Represents an empty-declaration.
-class EmptyDecl : public Decl {
- virtual void anchor();
- EmptyDecl(DeclContext *DC, SourceLocation L)
- : Decl(Empty, DC, L) { }
-
-public:
- static EmptyDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L);
- static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Empty; }
-};
-
-/// Insertion operator for diagnostics. This allows sending NamedDecl's
-/// into a diagnostic with <<.
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const NamedDecl* ND) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
- DiagnosticsEngine::ak_nameddecl);
- return DB;
-}
-inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const NamedDecl* ND) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
- DiagnosticsEngine::ak_nameddecl);
- return PD;
-}
-
-template<typename decl_type>
-void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
- // Note: This routine is implemented here because we need both NamedDecl
- // and Redeclarable to be defined.
- assert(RedeclLink.NextIsLatest() &&
- "setPreviousDecl on a decl already in a redeclaration chain");
-
- if (PrevDecl) {
- // Point to previous. Make sure that this is actually the most recent
- // redeclaration, or we can build invalid chains. If the most recent
- // redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
- First = PrevDecl->getFirstDecl();
- assert(First->RedeclLink.NextIsLatest() && "Expected first");
- decl_type *MostRecent = First->getNextRedeclaration();
- RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
-
- // If the declaration was previously visible, a redeclaration of it remains
- // visible even if it wouldn't be visible by itself.
- static_cast<decl_type*>(this)->IdentifierNamespace |=
- MostRecent->getIdentifierNamespace() &
- (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
- } else {
- // Make this first.
- First = static_cast<decl_type*>(this);
- }
-
- // First one will point to this one as latest.
- First->RedeclLink.setLatest(static_cast<decl_type*>(this));
-
- assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) ||
- cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid());
-}
-
-// Inline function definitions.
-
-/// \brief Check if the given decl is complete.
-///
-/// We use this function to break a cycle between the inline definitions in
-/// Type.h and Decl.h.
-inline bool IsEnumDeclComplete(EnumDecl *ED) {
- return ED->isComplete();
-}
-
-/// \brief Check if the given decl is scoped.
-///
-/// We use this function to break a cycle between the inline definitions in
-/// Type.h and Decl.h.
-inline bool IsEnumDeclScoped(EnumDecl *ED) {
- return ED->isScoped();
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h
deleted file mode 100644
index 3c5056c..0000000
--- a/include/clang/AST/DeclAccessPair.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===--- DeclAccessPair.h - A decl bundled with its path access -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the DeclAccessPair class, which provides an
-// efficient representation of a pair of a NamedDecl* and an
-// AccessSpecifier. Generally the access specifier gives the
-// natural access of a declaration when named in a class, as
-// defined in C++ [class.access.base]p1.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
-#define LLVM_CLANG_AST_DECLACCESSPAIR_H
-
-#include "clang/Basic/Specifiers.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace clang {
-
-class NamedDecl;
-
-/// A POD class for pairing a NamedDecl* with an access specifier.
-/// Can be put into unions.
-class DeclAccessPair {
- uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
-
- enum { Mask = 0x3 };
-
-public:
- static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
- DeclAccessPair p;
- p.set(D, AS);
- return p;
- }
-
- NamedDecl *getDecl() const {
- return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
- }
- AccessSpecifier getAccess() const {
- return AccessSpecifier(Mask & Ptr);
- }
-
- void setDecl(NamedDecl *D) {
- set(D, getAccess());
- }
- void setAccess(AccessSpecifier AS) {
- set(getDecl(), AS);
- }
- void set(NamedDecl *D, AccessSpecifier AS) {
- Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
- }
-
- operator NamedDecl*() const { return getDecl(); }
- NamedDecl *operator->() const { return getDecl(); }
-};
-}
-
-// Take a moment to tell SmallVector that DeclAccessPair is POD.
-namespace llvm {
-template<typename> struct isPodLike;
-template<> struct isPodLike<clang::DeclAccessPair> {
- static const bool value = true;
-};
-}
-
-#endif
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
deleted file mode 100644
index 05b2a12..0000000
--- a/include/clang/AST/DeclBase.h
+++ /dev/null
@@ -1,1904 +0,0 @@
-//===-- DeclBase.h - Base Classes for representing declarations -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Decl and DeclContext interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLBASE_H
-#define LLVM_CLANG_AST_DECLBASE_H
-
-#include "clang/AST/AttrIterator.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/Basic/Specifiers.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/PrettyStackTrace.h"
-
-namespace clang {
-class ASTMutationListener;
-class BlockDecl;
-class CXXRecordDecl;
-class CompoundStmt;
-class DeclContext;
-class DeclarationName;
-class DependentDiagnostic;
-class EnumDecl;
-class FunctionDecl;
-class FunctionType;
-enum Linkage : unsigned char;
-class LinkageComputer;
-class LinkageSpecDecl;
-class Module;
-class NamedDecl;
-class NamespaceDecl;
-class ObjCCategoryDecl;
-class ObjCCategoryImplDecl;
-class ObjCContainerDecl;
-class ObjCImplDecl;
-class ObjCImplementationDecl;
-class ObjCInterfaceDecl;
-class ObjCMethodDecl;
-class ObjCProtocolDecl;
-struct PrintingPolicy;
-class RecordDecl;
-class Stmt;
-class StoredDeclsMap;
-class TranslationUnitDecl;
-class UsingDirectiveDecl;
-}
-
-namespace clang {
-
- /// \brief Captures the result of checking the availability of a
- /// declaration.
- enum AvailabilityResult {
- AR_Available = 0,
- AR_NotYetIntroduced,
- AR_Deprecated,
- AR_Unavailable
- };
-
-/// Decl - This represents one declaration (or definition), e.g. a variable,
-/// typedef, function, struct, etc.
-///
-/// Note: There are objects tacked on before the *beginning* of Decl
-/// (and its subclasses) in its Decl::operator new(). Proper alignment
-/// of all subclasses (not requiring more than DeclObjAlignment) is
-/// asserted in DeclBase.cpp.
-class Decl {
-public:
- /// \brief Alignment guaranteed when allocating Decl and any subtypes.
- enum { DeclObjAlignment = llvm::AlignOf<uint64_t>::Alignment };
-
- /// \brief Lists the kind of concrete classes of Decl.
- enum Kind {
-#define DECL(DERIVED, BASE) DERIVED,
-#define ABSTRACT_DECL(DECL)
-#define DECL_RANGE(BASE, START, END) \
- first##BASE = START, last##BASE = END,
-#define LAST_DECL_RANGE(BASE, START, END) \
- first##BASE = START, last##BASE = END
-#include "clang/AST/DeclNodes.inc"
- };
-
- /// \brief A placeholder type used to construct an empty shell of a
- /// decl-derived type that will be filled in later (e.g., by some
- /// deserialization method).
- struct EmptyShell { };
-
- /// IdentifierNamespace - The different namespaces in which
- /// declarations may appear. According to C99 6.2.3, there are
- /// four namespaces, labels, tags, members and ordinary
- /// identifiers. C++ describes lookup completely differently:
- /// certain lookups merely "ignore" certain kinds of declarations,
- /// usually based on whether the declaration is of a type, etc.
- ///
- /// These are meant as bitmasks, so that searches in
- /// C++ can look into the "tag" namespace during ordinary lookup.
- ///
- /// Decl currently provides 15 bits of IDNS bits.
- enum IdentifierNamespace {
- /// Labels, declared with 'x:' and referenced with 'goto x'.
- IDNS_Label = 0x0001,
-
- /// Tags, declared with 'struct foo;' and referenced with
- /// 'struct foo'. All tags are also types. This is what
- /// elaborated-type-specifiers look for in C.
- IDNS_Tag = 0x0002,
-
- /// Types, declared with 'struct foo', typedefs, etc.
- /// This is what elaborated-type-specifiers look for in C++,
- /// but note that it's ill-formed to find a non-tag.
- IDNS_Type = 0x0004,
-
- /// Members, declared with object declarations within tag
- /// definitions. In C, these can only be found by "qualified"
- /// lookup in member expressions. In C++, they're found by
- /// normal lookup.
- IDNS_Member = 0x0008,
-
- /// Namespaces, declared with 'namespace foo {}'.
- /// Lookup for nested-name-specifiers find these.
- IDNS_Namespace = 0x0010,
-
- /// Ordinary names. In C, everything that's not a label, tag,
- /// or member ends up here.
- IDNS_Ordinary = 0x0020,
-
- /// Objective C \@protocol.
- IDNS_ObjCProtocol = 0x0040,
-
- /// This declaration is a friend function. A friend function
- /// declaration is always in this namespace but may also be in
- /// IDNS_Ordinary if it was previously declared.
- IDNS_OrdinaryFriend = 0x0080,
-
- /// This declaration is a friend class. A friend class
- /// declaration is always in this namespace but may also be in
- /// IDNS_Tag|IDNS_Type if it was previously declared.
- IDNS_TagFriend = 0x0100,
-
- /// This declaration is a using declaration. A using declaration
- /// *introduces* a number of other declarations into the current
- /// scope, and those declarations use the IDNS of their targets,
- /// but the actual using declarations go in this namespace.
- IDNS_Using = 0x0200,
-
- /// This declaration is a C++ operator declared in a non-class
- /// context. All such operators are also in IDNS_Ordinary.
- /// C++ lexical operator lookup looks for these.
- IDNS_NonMemberOperator = 0x0400,
-
- /// This declaration is a function-local extern declaration of a
- /// variable or function. This may also be IDNS_Ordinary if it
- /// has been declared outside any function.
- IDNS_LocalExtern = 0x0800
- };
-
- /// ObjCDeclQualifier - 'Qualifiers' written next to the return and
- /// parameter types in method declarations. Other than remembering
- /// them and mangling them into the method's signature string, these
- /// are ignored by the compiler; they are consumed by certain
- /// remote-messaging frameworks.
- ///
- /// in, inout, and out are mutually exclusive and apply only to
- /// method parameters. bycopy and byref are mutually exclusive and
- /// apply only to method parameters (?). oneway applies only to
- /// results. All of these expect their corresponding parameter to
- /// have a particular type. None of this is currently enforced by
- /// clang.
- ///
- /// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier.
- enum ObjCDeclQualifier {
- OBJC_TQ_None = 0x0,
- OBJC_TQ_In = 0x1,
- OBJC_TQ_Inout = 0x2,
- OBJC_TQ_Out = 0x4,
- OBJC_TQ_Bycopy = 0x8,
- OBJC_TQ_Byref = 0x10,
- OBJC_TQ_Oneway = 0x20,
-
- /// The nullability qualifier is set when the nullability of the
- /// result or parameter was expressed via a context-sensitive
- /// keyword.
- OBJC_TQ_CSNullability = 0x40
- };
-
-protected:
- // Enumeration values used in the bits stored in NextInContextAndBits.
- enum {
- /// \brief Whether this declaration is a top-level declaration (function,
- /// global variable, etc.) that is lexically inside an objc container
- /// definition.
- TopLevelDeclInObjCContainerFlag = 0x01,
-
- /// \brief Whether this declaration is private to the module in which it was
- /// defined.
- ModulePrivateFlag = 0x02
- };
-
- /// \brief The next declaration within the same lexical
- /// DeclContext. These pointers form the linked list that is
- /// traversed via DeclContext's decls_begin()/decls_end().
- ///
- /// The extra two bits are used for the TopLevelDeclInObjCContainer and
- /// ModulePrivate bits.
- llvm::PointerIntPair<Decl *, 2, unsigned> NextInContextAndBits;
-
-private:
- friend class DeclContext;
-
- struct MultipleDC {
- DeclContext *SemanticDC;
- DeclContext *LexicalDC;
- };
-
-
- /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
- /// For declarations that don't contain C++ scope specifiers, it contains
- /// the DeclContext where the Decl was declared.
- /// For declarations with C++ scope specifiers, it contains a MultipleDC*
- /// with the context where it semantically belongs (SemanticDC) and the
- /// context where it was lexically declared (LexicalDC).
- /// e.g.:
- ///
- /// namespace A {
- /// void f(); // SemanticDC == LexicalDC == 'namespace A'
- /// }
- /// void A::f(); // SemanticDC == namespace 'A'
- /// // LexicalDC == global namespace
- llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
-
- inline bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
- inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
- inline MultipleDC *getMultipleDC() const {
- return DeclCtx.get<MultipleDC*>();
- }
- inline DeclContext *getSemanticDC() const {
- return DeclCtx.get<DeclContext*>();
- }
-
- /// Loc - The location of this decl.
- SourceLocation Loc;
-
- /// DeclKind - This indicates which class this is.
- unsigned DeclKind : 8;
-
- /// InvalidDecl - This indicates a semantic error occurred.
- unsigned InvalidDecl : 1;
-
- /// HasAttrs - This indicates whether the decl has attributes or not.
- unsigned HasAttrs : 1;
-
- /// Implicit - Whether this declaration was implicitly generated by
- /// the implementation rather than explicitly written by the user.
- unsigned Implicit : 1;
-
- /// \brief Whether this declaration was "used", meaning that a definition is
- /// required.
- unsigned Used : 1;
-
- /// \brief Whether this declaration was "referenced".
- /// The difference with 'Used' is whether the reference appears in a
- /// evaluated context or not, e.g. functions used in uninstantiated templates
- /// are regarded as "referenced" but not "used".
- unsigned Referenced : 1;
-
- /// \brief Whether statistic collection is enabled.
- static bool StatisticsEnabled;
-
-protected:
- /// Access - Used by C++ decls for the access specifier.
- // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
- unsigned Access : 2;
- friend class CXXClassMemberWrapper;
-
- /// \brief Whether this declaration was loaded from an AST file.
- unsigned FromASTFile : 1;
-
- /// \brief Whether this declaration is hidden from normal name lookup, e.g.,
- /// because it is was loaded from an AST file is either module-private or
- /// because its submodule has not been made visible.
- unsigned Hidden : 1;
-
- /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
- unsigned IdentifierNamespace : 12;
-
- /// \brief If 0, we have not computed the linkage of this declaration.
- /// Otherwise, it is the linkage + 1.
- mutable unsigned CacheValidAndLinkage : 3;
-
- friend class ASTDeclWriter;
- friend class ASTDeclReader;
- friend class ASTReader;
- friend class LinkageComputer;
-
- template<typename decl_type> friend class Redeclarable;
-
- /// \brief Allocate memory for a deserialized declaration.
- ///
- /// This routine must be used to allocate memory for any declaration that is
- /// deserialized from a module file.
- ///
- /// \param Size The size of the allocated object.
- /// \param Ctx The context in which we will allocate memory.
- /// \param ID The global ID of the deserialized declaration.
- /// \param Extra The amount of extra space to allocate after the object.
- void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID,
- std::size_t Extra = 0);
-
- /// \brief Allocate memory for a non-deserialized declaration.
- void *operator new(std::size_t Size, const ASTContext &Ctx,
- DeclContext *Parent, std::size_t Extra = 0);
-
-private:
- bool AccessDeclContextSanity() const;
-
-protected:
-
- Decl(Kind DK, DeclContext *DC, SourceLocation L)
- : NextInContextAndBits(), DeclCtx(DC),
- Loc(L), DeclKind(DK), InvalidDecl(0),
- HasAttrs(false), Implicit(false), Used(false), Referenced(false),
- Access(AS_none), FromASTFile(0), Hidden(DC && cast<Decl>(DC)->Hidden),
- IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- CacheValidAndLinkage(0)
- {
- if (StatisticsEnabled) add(DK);
- }
-
- Decl(Kind DK, EmptyShell Empty)
- : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0),
- HasAttrs(false), Implicit(false), Used(false), Referenced(false),
- Access(AS_none), FromASTFile(0), Hidden(0),
- IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- CacheValidAndLinkage(0)
- {
- if (StatisticsEnabled) add(DK);
- }
-
- virtual ~Decl();
-
- /// \brief Update a potentially out-of-date declaration.
- void updateOutOfDate(IdentifierInfo &II) const;
-
- Linkage getCachedLinkage() const {
- return Linkage(CacheValidAndLinkage - 1);
- }
-
- void setCachedLinkage(Linkage L) const {
- CacheValidAndLinkage = L + 1;
- }
-
- bool hasCachedLinkage() const {
- return CacheValidAndLinkage;
- }
-
-public:
-
- /// \brief Source range that this declaration covers.
- virtual SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocation(), getLocation());
- }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSourceRange().getBegin();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSourceRange().getEnd();
- }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- Kind getKind() const { return static_cast<Kind>(DeclKind); }
- const char *getDeclKindName() const;
-
- Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); }
- const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();}
-
- DeclContext *getDeclContext() {
- if (isInSemaDC())
- return getSemanticDC();
- return getMultipleDC()->SemanticDC;
- }
- const DeclContext *getDeclContext() const {
- return const_cast<Decl*>(this)->getDeclContext();
- }
-
- /// Find the innermost non-closure ancestor of this declaration,
- /// walking up through blocks, lambdas, etc. If that ancestor is
- /// not a code context (!isFunctionOrMethod()), returns null.
- ///
- /// A declaration may be its own non-closure context.
- Decl *getNonClosureContext();
- const Decl *getNonClosureContext() const {
- return const_cast<Decl*>(this)->getNonClosureContext();
- }
-
- TranslationUnitDecl *getTranslationUnitDecl();
- const TranslationUnitDecl *getTranslationUnitDecl() const {
- return const_cast<Decl*>(this)->getTranslationUnitDecl();
- }
-
- bool isInAnonymousNamespace() const;
-
- bool isInStdNamespace() const;
-
- ASTContext &getASTContext() const LLVM_READONLY;
-
- void setAccess(AccessSpecifier AS) {
- Access = AS;
- assert(AccessDeclContextSanity());
- }
-
- AccessSpecifier getAccess() const {
- assert(AccessDeclContextSanity());
- return AccessSpecifier(Access);
- }
-
- /// \brief Retrieve the access specifier for this declaration, even though
- /// it may not yet have been properly set.
- AccessSpecifier getAccessUnsafe() const {
- return AccessSpecifier(Access);
- }
-
- bool hasAttrs() const { return HasAttrs; }
- void setAttrs(const AttrVec& Attrs) {
- return setAttrsImpl(Attrs, getASTContext());
- }
- AttrVec &getAttrs() {
- return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
- }
- const AttrVec &getAttrs() const;
- void dropAttrs();
-
- void addAttr(Attr *A) {
- if (hasAttrs())
- getAttrs().push_back(A);
- else
- setAttrs(AttrVec(1, A));
- }
-
- typedef AttrVec::const_iterator attr_iterator;
- typedef llvm::iterator_range<attr_iterator> attr_range;
-
- attr_range attrs() const {
- return attr_range(attr_begin(), attr_end());
- }
-
- attr_iterator attr_begin() const {
- return hasAttrs() ? getAttrs().begin() : nullptr;
- }
- attr_iterator attr_end() const {
- return hasAttrs() ? getAttrs().end() : nullptr;
- }
-
- template <typename T>
- void dropAttr() {
- if (!HasAttrs) return;
-
- AttrVec &Vec = getAttrs();
- Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa<T, Attr*>), Vec.end());
-
- if (Vec.empty())
- HasAttrs = false;
- }
-
- template <typename T>
- llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
- return llvm::make_range(specific_attr_begin<T>(), specific_attr_end<T>());
- }
-
- template <typename T>
- specific_attr_iterator<T> specific_attr_begin() const {
- return specific_attr_iterator<T>(attr_begin());
- }
- template <typename T>
- specific_attr_iterator<T> specific_attr_end() const {
- return specific_attr_iterator<T>(attr_end());
- }
-
- template<typename T> T *getAttr() const {
- return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
- }
- template<typename T> bool hasAttr() const {
- return hasAttrs() && hasSpecificAttr<T>(getAttrs());
- }
-
- /// getMaxAlignment - return the maximum alignment specified by attributes
- /// on this decl, 0 if there are none.
- unsigned getMaxAlignment() const;
-
- /// setInvalidDecl - Indicates the Decl had a semantic error. This
- /// allows for graceful error recovery.
- void setInvalidDecl(bool Invalid = true);
- bool isInvalidDecl() const { return (bool) InvalidDecl; }
-
- /// isImplicit - Indicates whether the declaration was implicitly
- /// generated by the implementation. If false, this declaration
- /// was written explicitly in the source code.
- bool isImplicit() const { return Implicit; }
- void setImplicit(bool I = true) { Implicit = I; }
-
- /// \brief Whether this declaration was used, meaning that a definition
- /// is required.
- ///
- /// \param CheckUsedAttr When true, also consider the "used" attribute
- /// (in addition to the "used" bit set by \c setUsed()) when determining
- /// whether the function is used.
- bool isUsed(bool CheckUsedAttr = true) const;
-
- /// \brief Set whether the declaration is used, in the sense of odr-use.
- ///
- /// This should only be used immediately after creating a declaration.
- void setIsUsed() { Used = true; }
-
- /// \brief Mark the declaration used, in the sense of odr-use.
- ///
- /// This notifies any mutation listeners in addition to setting a bit
- /// indicating the declaration is used.
- void markUsed(ASTContext &C);
-
- /// \brief Whether any declaration of this entity was referenced.
- bool isReferenced() const;
-
- /// \brief Whether this declaration was referenced. This should not be relied
- /// upon for anything other than debugging.
- bool isThisDeclarationReferenced() const { return Referenced; }
-
- void setReferenced(bool R = true) { Referenced = R; }
-
- /// \brief Whether this declaration is a top-level declaration (function,
- /// global variable, etc.) that is lexically inside an objc container
- /// definition.
- bool isTopLevelDeclInObjCContainer() const {
- return NextInContextAndBits.getInt() & TopLevelDeclInObjCContainerFlag;
- }
-
- void setTopLevelDeclInObjCContainer(bool V = true) {
- unsigned Bits = NextInContextAndBits.getInt();
- if (V)
- Bits |= TopLevelDeclInObjCContainerFlag;
- else
- Bits &= ~TopLevelDeclInObjCContainerFlag;
- NextInContextAndBits.setInt(Bits);
- }
-
- /// \brief Whether this declaration was marked as being private to the
- /// module in which it was defined.
- bool isModulePrivate() const {
- return NextInContextAndBits.getInt() & ModulePrivateFlag;
- }
-
-protected:
- /// \brief Specify whether this declaration was marked as being private
- /// to the module in which it was defined.
- void setModulePrivate(bool MP = true) {
- unsigned Bits = NextInContextAndBits.getInt();
- if (MP)
- Bits |= ModulePrivateFlag;
- else
- Bits &= ~ModulePrivateFlag;
- NextInContextAndBits.setInt(Bits);
- }
-
- /// \brief Set the owning module ID.
- void setOwningModuleID(unsigned ID) {
- assert(isFromASTFile() && "Only works on a deserialized declaration");
- *((unsigned*)this - 2) = ID;
- }
-
-public:
-
- /// \brief Determine the availability of the given declaration.
- ///
- /// This routine will determine the most restrictive availability of
- /// the given declaration (e.g., preferring 'unavailable' to
- /// 'deprecated').
- ///
- /// \param Message If non-NULL and the result is not \c
- /// AR_Available, will be set to a (possibly empty) message
- /// describing why the declaration has not been introduced, is
- /// deprecated, or is unavailable.
- AvailabilityResult getAvailability(std::string *Message = nullptr) const;
-
- /// \brief Determine whether this declaration is marked 'deprecated'.
- ///
- /// \param Message If non-NULL and the declaration is deprecated,
- /// this will be set to the message describing why the declaration
- /// was deprecated (which may be empty).
- bool isDeprecated(std::string *Message = nullptr) const {
- return getAvailability(Message) == AR_Deprecated;
- }
-
- /// \brief Determine whether this declaration is marked 'unavailable'.
- ///
- /// \param Message If non-NULL and the declaration is unavailable,
- /// this will be set to the message describing why the declaration
- /// was made unavailable (which may be empty).
- bool isUnavailable(std::string *Message = nullptr) const {
- return getAvailability(Message) == AR_Unavailable;
- }
-
- /// \brief Determine whether this is a weak-imported symbol.
- ///
- /// Weak-imported symbols are typically marked with the
- /// 'weak_import' attribute, but may also be marked with an
- /// 'availability' attribute where we're targing a platform prior to
- /// the introduction of this feature.
- bool isWeakImported() const;
-
- /// \brief Determines whether this symbol can be weak-imported,
- /// e.g., whether it would be well-formed to add the weak_import
- /// attribute.
- ///
- /// \param IsDefinition Set to \c true to indicate that this
- /// declaration cannot be weak-imported because it has a definition.
- bool canBeWeakImported(bool &IsDefinition) const;
-
- /// \brief Determine whether this declaration came from an AST file (such as
- /// a precompiled header or module) rather than having been parsed.
- bool isFromASTFile() const { return FromASTFile; }
-
- /// \brief Retrieve the global declaration ID associated with this
- /// declaration, which specifies where in the
- unsigned getGlobalID() const {
- if (isFromASTFile())
- return *((const unsigned*)this - 1);
- return 0;
- }
-
- /// \brief Retrieve the global ID of the module that owns this particular
- /// declaration.
- unsigned getOwningModuleID() const {
- if (isFromASTFile())
- return *((const unsigned*)this - 2);
-
- return 0;
- }
-
-private:
- Module *getOwningModuleSlow() const;
-protected:
- bool hasLocalOwningModuleStorage() const;
-
-public:
- /// \brief Get the imported owning module, if this decl is from an imported
- /// (non-local) module.
- Module *getImportedOwningModule() const {
- if (!isFromASTFile())
- return nullptr;
-
- return getOwningModuleSlow();
- }
-
- /// \brief Get the local owning module, if known. Returns nullptr if owner is
- /// not yet known or declaration is not from a module.
- Module *getLocalOwningModule() const {
- if (isFromASTFile() || !Hidden)
- return nullptr;
- return reinterpret_cast<Module *const *>(this)[-1];
- }
- void setLocalOwningModule(Module *M) {
- assert(!isFromASTFile() && Hidden && hasLocalOwningModuleStorage() &&
- "should not have a cached owning module");
- reinterpret_cast<Module **>(this)[-1] = M;
- }
-
- unsigned getIdentifierNamespace() const {
- return IdentifierNamespace;
- }
- bool isInIdentifierNamespace(unsigned NS) const {
- return getIdentifierNamespace() & NS;
- }
- static unsigned getIdentifierNamespaceForKind(Kind DK);
-
- bool hasTagIdentifierNamespace() const {
- return isTagIdentifierNamespace(getIdentifierNamespace());
- }
- static bool isTagIdentifierNamespace(unsigned NS) {
- // TagDecls have Tag and Type set and may also have TagFriend.
- return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type);
- }
-
- /// getLexicalDeclContext - The declaration context where this Decl was
- /// lexically declared (LexicalDC). May be different from
- /// getDeclContext() (SemanticDC).
- /// e.g.:
- ///
- /// namespace A {
- /// void f(); // SemanticDC == LexicalDC == 'namespace A'
- /// }
- /// void A::f(); // SemanticDC == namespace 'A'
- /// // LexicalDC == global namespace
- DeclContext *getLexicalDeclContext() {
- if (isInSemaDC())
- return getSemanticDC();
- return getMultipleDC()->LexicalDC;
- }
- const DeclContext *getLexicalDeclContext() const {
- return const_cast<Decl*>(this)->getLexicalDeclContext();
- }
-
- /// Determine whether this declaration is declared out of line (outside its
- /// semantic context).
- virtual bool isOutOfLine() const;
-
- /// setDeclContext - Set both the semantic and lexical DeclContext
- /// to DC.
- void setDeclContext(DeclContext *DC);
-
- void setLexicalDeclContext(DeclContext *DC);
-
- /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
- /// scoped decl is defined outside the current function or method. This is
- /// roughly global variables and functions, but also handles enums (which
- /// could be defined inside or outside a function etc).
- bool isDefinedOutsideFunctionOrMethod() const {
- return getParentFunctionOrMethod() == nullptr;
- }
-
- /// \brief Returns true if this declaration lexically is inside a function.
- /// It recognizes non-defining declarations as well as members of local
- /// classes:
- /// \code
- /// void foo() { void bar(); }
- /// void foo2() { class ABC { void bar(); }; }
- /// \endcode
- bool isLexicallyWithinFunctionOrMethod() const;
-
- /// \brief If this decl is defined inside a function/method/block it returns
- /// the corresponding DeclContext, otherwise it returns null.
- const DeclContext *getParentFunctionOrMethod() const;
- DeclContext *getParentFunctionOrMethod() {
- return const_cast<DeclContext*>(
- const_cast<const Decl*>(this)->getParentFunctionOrMethod());
- }
-
- /// \brief Retrieves the "canonical" declaration of the given declaration.
- virtual Decl *getCanonicalDecl() { return this; }
- const Decl *getCanonicalDecl() const {
- return const_cast<Decl*>(this)->getCanonicalDecl();
- }
-
- /// \brief Whether this particular Decl is a canonical one.
- bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
-
-protected:
- /// \brief Returns the next redeclaration or itself if this is the only decl.
- ///
- /// Decl subclasses that can be redeclared should override this method so that
- /// Decl::redecl_iterator can iterate over them.
- virtual Decl *getNextRedeclarationImpl() { return this; }
-
- /// \brief Implementation of getPreviousDecl(), to be overridden by any
- /// subclass that has a redeclaration chain.
- virtual Decl *getPreviousDeclImpl() { return nullptr; }
-
- /// \brief Implementation of getMostRecentDecl(), to be overridden by any
- /// subclass that has a redeclaration chain.
- virtual Decl *getMostRecentDeclImpl() { return this; }
-
-public:
- /// \brief Iterates through all the redeclarations of the same decl.
- class redecl_iterator {
- /// Current - The current declaration.
- Decl *Current;
- Decl *Starter;
-
- public:
- typedef Decl *value_type;
- typedef const value_type &reference;
- typedef const value_type *pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- redecl_iterator() : Current(nullptr) { }
- explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
-
- reference operator*() const { return Current; }
- value_type operator->() const { return Current; }
-
- redecl_iterator& operator++() {
- assert(Current && "Advancing while iterator has reached end");
- // Get either previous decl or latest decl.
- Decl *Next = Current->getNextRedeclarationImpl();
- assert(Next && "Should return next redeclaration or itself, never null!");
- Current = (Next != Starter) ? Next : nullptr;
- return *this;
- }
-
- redecl_iterator operator++(int) {
- redecl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(redecl_iterator x, redecl_iterator y) {
- return x.Current == y.Current;
- }
- friend bool operator!=(redecl_iterator x, redecl_iterator y) {
- return x.Current != y.Current;
- }
- };
-
- typedef llvm::iterator_range<redecl_iterator> redecl_range;
-
- /// \brief Returns an iterator range for all the redeclarations of the same
- /// decl. It will iterate at least once (when this decl is the only one).
- redecl_range redecls() const {
- return redecl_range(redecls_begin(), redecls_end());
- }
-
- redecl_iterator redecls_begin() const {
- return redecl_iterator(const_cast<Decl *>(this));
- }
- redecl_iterator redecls_end() const { return redecl_iterator(); }
-
- /// \brief Retrieve the previous declaration that declares the same entity
- /// as this declaration, or NULL if there is no previous declaration.
- Decl *getPreviousDecl() { return getPreviousDeclImpl(); }
-
- /// \brief Retrieve the most recent 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();
- }
-
- /// \brief True if this is the first declaration in its redeclaration chain.
- bool isFirstDecl() const {
- return getPreviousDecl() == nullptr;
- }
-
- /// \brief Retrieve the most recent declaration that declares the same entity
- /// as this declaration (which may be this declaration).
- Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); }
-
- /// \brief Retrieve the most recent declaration that declares the same entity
- /// as this declaration (which may be this declaration).
- const Decl *getMostRecentDecl() const {
- return const_cast<Decl *>(this)->getMostRecentDeclImpl();
- }
-
- /// getBody - If this Decl represents a declaration for a body of code,
- /// such as a function or method definition, this method returns the
- /// top-level Stmt* of that body. Otherwise this method returns null.
- virtual Stmt* getBody() const { return nullptr; }
-
- /// \brief Returns true if this \c Decl represents a declaration for a body of
- /// code, such as a function or method definition.
- /// Note that \c hasBody can also return true if any redeclaration of this
- /// \c Decl represents a declaration for a body of code.
- virtual bool hasBody() const { return getBody() != nullptr; }
-
- /// getBodyRBrace - Gets the right brace of the body, if a body exists.
- /// This works whether the body is a CompoundStmt or a CXXTryStmt.
- SourceLocation getBodyRBrace() const;
-
- // global temp stats (until we have a per-module visitor)
- static void add(Kind k);
- static void EnableStatistics();
- static void PrintStats();
-
- /// isTemplateParameter - Determines whether this declaration is a
- /// template parameter.
- bool isTemplateParameter() const;
-
- /// isTemplateParameter - Determines whether this declaration is a
- /// template parameter pack.
- bool isTemplateParameterPack() const;
-
- /// \brief Whether this declaration is a parameter pack.
- bool isParameterPack() const;
-
- /// \brief returns true if this declaration is a template
- bool isTemplateDecl() const;
-
- /// \brief Whether this declaration is a function or function template.
- bool isFunctionOrFunctionTemplate() const {
- return (DeclKind >= Decl::firstFunction &&
- DeclKind <= Decl::lastFunction) ||
- DeclKind == FunctionTemplate;
- }
-
- /// \brief Returns the function itself, or the templated function if this is a
- /// function template.
- FunctionDecl *getAsFunction() LLVM_READONLY;
-
- const FunctionDecl *getAsFunction() const {
- return const_cast<Decl *>(this)->getAsFunction();
- }
-
- /// \brief Changes the namespace of this declaration to reflect that it's
- /// a function-local extern declaration.
- ///
- /// These declarations appear in the lexical context of the extern
- /// declaration, but in the semantic context of the enclosing namespace
- /// scope.
- void setLocalExternDecl() {
- assert((IdentifierNamespace == IDNS_Ordinary ||
- IdentifierNamespace == IDNS_OrdinaryFriend) &&
- "namespace is not ordinary");
-
- Decl *Prev = getPreviousDecl();
- IdentifierNamespace &= ~IDNS_Ordinary;
-
- IdentifierNamespace |= IDNS_LocalExtern;
- if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)
- IdentifierNamespace |= IDNS_Ordinary;
- }
-
- /// \brief Determine whether this is a block-scope declaration with linkage.
- /// This will either be a local variable declaration declared 'extern', or a
- /// local function declaration.
- bool isLocalExternDecl() {
- return IdentifierNamespace & IDNS_LocalExtern;
- }
-
- /// \brief Changes the namespace of this declaration to reflect that it's
- /// the object of a friend declaration.
- ///
- /// These declarations appear in the lexical context of the friending
- /// class, but in the semantic context of the actual entity. This property
- /// applies only to a specific decl object; other redeclarations of the
- /// same entity may not (and probably don't) share this property.
- void setObjectOfFriendDecl(bool PerformFriendInjection = false) {
- unsigned OldNS = IdentifierNamespace;
- assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
- IDNS_TagFriend | IDNS_OrdinaryFriend |
- IDNS_LocalExtern)) &&
- "namespace includes neither ordinary nor tag");
- assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
- IDNS_TagFriend | IDNS_OrdinaryFriend |
- IDNS_LocalExtern)) &&
- "namespace includes other than ordinary or tag");
-
- Decl *Prev = getPreviousDecl();
- IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type);
-
- if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
- IdentifierNamespace |= IDNS_TagFriend;
- if (PerformFriendInjection ||
- (Prev && Prev->getIdentifierNamespace() & IDNS_Tag))
- IdentifierNamespace |= IDNS_Tag | IDNS_Type;
- }
-
- if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) {
- IdentifierNamespace |= IDNS_OrdinaryFriend;
- if (PerformFriendInjection ||
- (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))
- IdentifierNamespace |= IDNS_Ordinary;
- }
- }
-
- enum FriendObjectKind {
- FOK_None, ///< Not a friend object.
- FOK_Declared, ///< A friend of a previously-declared entity.
- FOK_Undeclared ///< A friend of a previously-undeclared entity.
- };
-
- /// \brief Determines whether this declaration is the object of a
- /// friend declaration and, if so, what kind.
- ///
- /// There is currently no direct way to find the associated FriendDecl.
- FriendObjectKind getFriendObjectKind() const {
- unsigned mask =
- (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend));
- if (!mask) return FOK_None;
- return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? FOK_Declared
- : FOK_Undeclared);
- }
-
- /// Specifies that this declaration is a C++ overloaded non-member.
- void setNonMemberOperator() {
- assert(getKind() == Function || getKind() == FunctionTemplate);
- assert((IdentifierNamespace & IDNS_Ordinary) &&
- "visible non-member operators should be in ordinary namespace");
- IdentifierNamespace |= IDNS_NonMemberOperator;
- }
-
- static bool classofKind(Kind K) { return true; }
- static DeclContext *castToDeclContext(const Decl *);
- static Decl *castFromDeclContext(const DeclContext *);
-
- void print(raw_ostream &Out, unsigned Indentation = 0,
- bool PrintInstantiation = false) const;
- void print(raw_ostream &Out, const PrintingPolicy &Policy,
- unsigned Indentation = 0, bool PrintInstantiation = false) const;
- static void printGroup(Decl** Begin, unsigned NumDecls,
- raw_ostream &Out, const PrintingPolicy &Policy,
- unsigned Indentation = 0);
- // Debuggers don't usually respect default arguments.
- void dump() const;
- // Same as dump(), but forces color printing.
- void dumpColor() const;
- void dump(raw_ostream &Out) const;
-
- /// \brief Looks through the Decl's underlying type to extract a FunctionType
- /// when possible. Will return null if the type underlying the Decl does not
- /// have a FunctionType.
- const FunctionType *getFunctionType(bool BlocksToo = true) const;
-
-private:
- void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
- void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
- ASTContext &Ctx);
-
-protected:
- ASTMutationListener *getASTMutationListener() const;
-};
-
-/// \brief Determine whether two declarations declare the same entity.
-inline bool declaresSameEntity(const Decl *D1, const Decl *D2) {
- if (!D1 || !D2)
- return false;
-
- if (D1 == D2)
- return true;
-
- return D1->getCanonicalDecl() == D2->getCanonicalDecl();
-}
-
-/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
-/// doing something to a specific decl.
-class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
- const Decl *TheDecl;
- SourceLocation Loc;
- SourceManager &SM;
- const char *Message;
-public:
- PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
- SourceManager &sm, const char *Msg)
- : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
-
- void print(raw_ostream &OS) const override;
-};
-
-/// \brief The results of name lookup within a DeclContext. This is either a
-/// single result (with no stable storage) or a collection of results (with
-/// stable storage provided by the lookup table).
-class DeclContextLookupResult {
- typedef ArrayRef<NamedDecl *> ResultTy;
- ResultTy Result;
- // If there is only one lookup result, it would be invalidated by
- // reallocations of the name table, so store it separately.
- NamedDecl *Single;
-
- static NamedDecl *const SingleElementDummyList;
-
-public:
- DeclContextLookupResult() : Result(), Single() {}
- DeclContextLookupResult(ArrayRef<NamedDecl *> Result)
- : Result(Result), Single() {}
- DeclContextLookupResult(NamedDecl *Single)
- : Result(SingleElementDummyList), Single(Single) {}
-
- class iterator;
- typedef llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
- std::random_access_iterator_tag,
- NamedDecl *const> IteratorBase;
- class iterator : public IteratorBase {
- value_type SingleElement;
-
- public:
- iterator() : IteratorBase(), SingleElement() {}
- explicit iterator(pointer Pos, value_type Single = nullptr)
- : IteratorBase(Pos), SingleElement(Single) {}
-
- reference operator*() const {
- return SingleElement ? SingleElement : IteratorBase::operator*();
- }
- };
- typedef iterator const_iterator;
- typedef iterator::pointer pointer;
- typedef iterator::reference reference;
-
- iterator begin() const { return iterator(Result.begin(), Single); }
- iterator end() const { return iterator(Result.end(), Single); }
-
- bool empty() const { return Result.empty(); }
- pointer data() const { return Single ? &Single : Result.data(); }
- size_t size() const { return Single ? 1 : Result.size(); }
- reference front() const { return Single ? Single : Result.front(); }
- reference back() const { return Single ? Single : Result.back(); }
- reference operator[](size_t N) const { return Single ? Single : Result[N]; }
-
- // FIXME: Remove this from the interface
- DeclContextLookupResult slice(size_t N) const {
- DeclContextLookupResult Sliced = Result.slice(N);
- Sliced.Single = Single;
- return Sliced;
- }
-};
-
-/// DeclContext - This is used only as base class of specific decl types that
-/// can act as declaration contexts. These decls are (only the top classes
-/// that directly derive from DeclContext are mentioned, not their subclasses):
-///
-/// TranslationUnitDecl
-/// NamespaceDecl
-/// FunctionDecl
-/// TagDecl
-/// ObjCMethodDecl
-/// ObjCContainerDecl
-/// LinkageSpecDecl
-/// BlockDecl
-///
-class DeclContext {
- /// DeclKind - This indicates which class this is.
- unsigned DeclKind : 8;
-
- /// \brief Whether this declaration context also has some external
- /// storage that contains additional declarations that are lexically
- /// part of this context.
- mutable bool ExternalLexicalStorage : 1;
-
- /// \brief Whether this declaration context also has some external
- /// storage that contains additional declarations that are visible
- /// in this context.
- mutable bool ExternalVisibleStorage : 1;
-
- /// \brief Whether this declaration context has had external visible
- /// storage added since the last lookup. In this case, \c LookupPtr's
- /// invariant may not hold and needs to be fixed before we perform
- /// another lookup.
- mutable bool NeedToReconcileExternalVisibleStorage : 1;
-
- /// \brief If \c true, this context may have local lexical declarations
- /// that are missing from the lookup table.
- mutable bool HasLazyLocalLexicalLookups : 1;
-
- /// \brief If \c true, the external source may have lexical declarations
- /// that are missing from the lookup table.
- mutable bool HasLazyExternalLexicalLookups : 1;
-
- /// \brief If \c true, lookups should only return identifier from
- /// DeclContext scope (for example TranslationUnit). Used in
- /// LookupQualifiedName()
- mutable bool UseQualifiedLookup : 1;
-
- /// \brief Pointer to the data structure used to lookup declarations
- /// within this context (or a DependentStoredDeclsMap if this is a
- /// dependent context). We maintain the invariant that, if the map
- /// contains an entry for a DeclarationName (and we haven't lazily
- /// omitted anything), then it contains all relevant entries for that
- /// name (modulo the hasExternalDecls() flag).
- mutable StoredDeclsMap *LookupPtr;
-
-protected:
- /// FirstDecl - The first declaration stored within this declaration
- /// context.
- mutable Decl *FirstDecl;
-
- /// LastDecl - The last declaration stored within this declaration
- /// context. FIXME: We could probably cache this value somewhere
- /// outside of the DeclContext, to reduce the size of DeclContext by
- /// another pointer.
- mutable Decl *LastDecl;
-
- friend class ExternalASTSource;
- friend class ASTDeclReader;
- friend class ASTWriter;
-
- /// \brief Build up a chain of declarations.
- ///
- /// \returns the first/last pair of declarations.
- static std::pair<Decl *, Decl *>
- BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded);
-
- DeclContext(Decl::Kind K)
- : DeclKind(K), ExternalLexicalStorage(false),
- ExternalVisibleStorage(false),
- NeedToReconcileExternalVisibleStorage(false),
- HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false),
- UseQualifiedLookup(false),
- LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {}
-
-public:
- ~DeclContext();
-
- Decl::Kind getDeclKind() const {
- return static_cast<Decl::Kind>(DeclKind);
- }
- const char *getDeclKindName() const;
-
- /// getParent - Returns the containing DeclContext.
- DeclContext *getParent() {
- return cast<Decl>(this)->getDeclContext();
- }
- const DeclContext *getParent() const {
- return const_cast<DeclContext*>(this)->getParent();
- }
-
- /// getLexicalParent - Returns the containing lexical DeclContext. May be
- /// different from getParent, e.g.:
- ///
- /// namespace A {
- /// struct S;
- /// }
- /// struct A::S {}; // getParent() == namespace 'A'
- /// // getLexicalParent() == translation unit
- ///
- DeclContext *getLexicalParent() {
- return cast<Decl>(this)->getLexicalDeclContext();
- }
- const DeclContext *getLexicalParent() const {
- return const_cast<DeclContext*>(this)->getLexicalParent();
- }
-
- DeclContext *getLookupParent();
-
- const DeclContext *getLookupParent() const {
- return const_cast<DeclContext*>(this)->getLookupParent();
- }
-
- ASTContext &getParentASTContext() const {
- return cast<Decl>(this)->getASTContext();
- }
-
- bool isClosure() const {
- return DeclKind == Decl::Block;
- }
-
- bool isObjCContainer() const {
- switch (DeclKind) {
- case Decl::ObjCCategory:
- case Decl::ObjCCategoryImpl:
- case Decl::ObjCImplementation:
- case Decl::ObjCInterface:
- case Decl::ObjCProtocol:
- return true;
- }
- return false;
- }
-
- bool isFunctionOrMethod() const {
- switch (DeclKind) {
- case Decl::Block:
- case Decl::Captured:
- case Decl::ObjCMethod:
- return true;
- default:
- return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction;
- }
- }
-
- /// \brief Test whether the context supports looking up names.
- bool isLookupContext() const {
- return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec;
- }
-
- bool isFileContext() const {
- return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
- }
-
- bool isTranslationUnit() const {
- return DeclKind == Decl::TranslationUnit;
- }
-
- bool isRecord() const {
- return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord;
- }
-
- bool isNamespace() const {
- return DeclKind == Decl::Namespace;
- }
-
- bool isStdNamespace() const;
-
- bool isInlineNamespace() const;
-
- /// \brief Determines whether this context is dependent on a
- /// template parameter.
- bool isDependentContext() const;
-
- /// isTransparentContext - Determines whether this context is a
- /// "transparent" context, meaning that the members declared in this
- /// context are semantically declared in the nearest enclosing
- /// non-transparent (opaque) context but are lexically declared in
- /// this context. For example, consider the enumerators of an
- /// enumeration type:
- /// @code
- /// enum E {
- /// Val1
- /// };
- /// @endcode
- /// Here, E is a transparent context, so its enumerator (Val1) will
- /// appear (semantically) that it is in the same context of E.
- /// Examples of transparent contexts include: enumerations (except for
- /// C++0x scoped enums), and C++ linkage specifications.
- bool isTransparentContext() const;
-
- /// \brief Determines whether this context or some of its ancestors is a
- /// linkage specification context that specifies C linkage.
- bool isExternCContext() const;
-
- /// \brief Determines whether this context or some of its ancestors is a
- /// linkage specification context that specifies C++ linkage.
- bool isExternCXXContext() const;
-
- /// \brief Determine whether this declaration context is equivalent
- /// to the declaration context DC.
- bool Equals(const DeclContext *DC) const {
- return DC && this->getPrimaryContext() == DC->getPrimaryContext();
- }
-
- /// \brief Determine whether this declaration context encloses the
- /// declaration context DC.
- bool Encloses(const DeclContext *DC) const;
-
- /// \brief Find the nearest non-closure ancestor of this context,
- /// i.e. the innermost semantic parent of this context which is not
- /// a closure. A context may be its own non-closure ancestor.
- Decl *getNonClosureAncestor();
- const Decl *getNonClosureAncestor() const {
- return const_cast<DeclContext*>(this)->getNonClosureAncestor();
- }
-
- /// getPrimaryContext - There may be many different
- /// declarations of the same entity (including forward declarations
- /// of classes, multiple definitions of namespaces, etc.), each with
- /// a different set of declarations. This routine returns the
- /// "primary" DeclContext structure, which will contain the
- /// information needed to perform name lookup into this context.
- DeclContext *getPrimaryContext();
- const DeclContext *getPrimaryContext() const {
- return const_cast<DeclContext*>(this)->getPrimaryContext();
- }
-
- /// getRedeclContext - Retrieve the context in which an entity conflicts with
- /// other entities of the same name, or where it is a redeclaration if the
- /// two entities are compatible. This skips through transparent contexts.
- DeclContext *getRedeclContext();
- const DeclContext *getRedeclContext() const {
- return const_cast<DeclContext *>(this)->getRedeclContext();
- }
-
- /// \brief Retrieve the nearest enclosing namespace context.
- DeclContext *getEnclosingNamespaceContext();
- const DeclContext *getEnclosingNamespaceContext() const {
- return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
- }
-
- /// \brief Retrieve the outermost lexically enclosing record context.
- RecordDecl *getOuterLexicalRecordContext();
- const RecordDecl *getOuterLexicalRecordContext() const {
- return const_cast<DeclContext *>(this)->getOuterLexicalRecordContext();
- }
-
- /// \brief Test if this context is part of the enclosing namespace set of
- /// the context NS, as defined in C++0x [namespace.def]p9. If either context
- /// isn't a namespace, this is equivalent to Equals().
- ///
- /// The enclosing namespace set of a namespace is the namespace and, if it is
- /// inline, its enclosing namespace, recursively.
- bool InEnclosingNamespaceSetOf(const DeclContext *NS) const;
-
- /// \brief Collects all of the declaration contexts that are semantically
- /// connected to this declaration context.
- ///
- /// For declaration contexts that have multiple semantically connected but
- /// syntactically distinct contexts, such as C++ namespaces, this routine
- /// retrieves the complete set of such declaration contexts in source order.
- /// For example, given:
- ///
- /// \code
- /// namespace N {
- /// int x;
- /// }
- /// namespace N {
- /// int y;
- /// }
- /// \endcode
- ///
- /// The \c Contexts parameter will contain both definitions of N.
- ///
- /// \param Contexts Will be cleared and set to the set of declaration
- /// contexts that are semanticaly connected to this declaration context,
- /// in source order, including this context (which may be the only result,
- /// for non-namespace contexts).
- void collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts);
-
- /// decl_iterator - Iterates through the declarations stored
- /// within this context.
- class decl_iterator {
- /// Current - The current declaration.
- Decl *Current;
-
- public:
- typedef Decl *value_type;
- typedef const value_type &reference;
- typedef const value_type *pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- decl_iterator() : Current(nullptr) { }
- explicit decl_iterator(Decl *C) : Current(C) { }
-
- reference operator*() const { return Current; }
- // This doesn't meet the iterator requirements, but it's convenient
- value_type operator->() const { return Current; }
-
- decl_iterator& operator++() {
- Current = Current->getNextDeclInContext();
- return *this;
- }
-
- decl_iterator operator++(int) {
- decl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(decl_iterator x, decl_iterator y) {
- return x.Current == y.Current;
- }
- friend bool operator!=(decl_iterator x, decl_iterator y) {
- return x.Current != y.Current;
- }
- };
-
- typedef llvm::iterator_range<decl_iterator> decl_range;
-
- /// decls_begin/decls_end - Iterate over the declarations stored in
- /// this context.
- decl_range decls() const { return decl_range(decls_begin(), decls_end()); }
- decl_iterator decls_begin() const;
- decl_iterator decls_end() const { return decl_iterator(); }
- bool decls_empty() const;
-
- /// noload_decls_begin/end - Iterate over the declarations stored in this
- /// context that are currently loaded; don't attempt to retrieve anything
- /// from an external source.
- decl_range noload_decls() const {
- return decl_range(noload_decls_begin(), noload_decls_end());
- }
- decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); }
- decl_iterator noload_decls_end() const { return decl_iterator(); }
-
- /// specific_decl_iterator - Iterates over a subrange of
- /// declarations stored in a DeclContext, providing only those that
- /// are of type SpecificDecl (or a class derived from it). This
- /// iterator is used, for example, to provide iteration over just
- /// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
- template<typename SpecificDecl>
- class specific_decl_iterator {
- /// Current - The current, underlying declaration iterator, which
- /// will either be NULL or will point to a declaration of
- /// type SpecificDecl.
- DeclContext::decl_iterator Current;
-
- /// SkipToNextDecl - Advances the current position up to the next
- /// declaration of type SpecificDecl that also meets the criteria
- /// required by Acceptable.
- void SkipToNextDecl() {
- while (*Current && !isa<SpecificDecl>(*Current))
- ++Current;
- }
-
- public:
- typedef SpecificDecl *value_type;
- // TODO: Add reference and pointer typedefs (with some appropriate proxy
- // type) if we ever have a need for them.
- typedef void reference;
- typedef void pointer;
- typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
- difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- specific_decl_iterator() : Current() { }
-
- /// specific_decl_iterator - Construct a new iterator over a
- /// subset of the declarations the range [C,
- /// end-of-declarations). If A is non-NULL, it is a pointer to a
- /// member function of SpecificDecl that should return true for
- /// all of the SpecificDecl instances that will be in the subset
- /// of iterators. For example, if you want Objective-C instance
- /// methods, SpecificDecl will be ObjCMethodDecl and A will be
- /// &ObjCMethodDecl::isInstanceMethod.
- explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
- SkipToNextDecl();
- }
-
- value_type operator*() const { return cast<SpecificDecl>(*Current); }
- // This doesn't meet the iterator requirements, but it's convenient
- value_type operator->() const { return **this; }
-
- specific_decl_iterator& operator++() {
- ++Current;
- SkipToNextDecl();
- return *this;
- }
-
- specific_decl_iterator operator++(int) {
- specific_decl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(const specific_decl_iterator& x,
- const specific_decl_iterator& y) {
- return x.Current == y.Current;
- }
-
- friend bool operator!=(const specific_decl_iterator& x,
- const specific_decl_iterator& y) {
- return x.Current != y.Current;
- }
- };
-
- /// \brief Iterates over a filtered subrange of declarations stored
- /// in a DeclContext.
- ///
- /// This iterator visits only those declarations that are of type
- /// SpecificDecl (or a class derived from it) and that meet some
- /// additional run-time criteria. This iterator is used, for
- /// example, to provide access to the instance methods within an
- /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
- /// Acceptable = ObjCMethodDecl::isInstanceMethod).
- template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
- class filtered_decl_iterator {
- /// Current - The current, underlying declaration iterator, which
- /// will either be NULL or will point to a declaration of
- /// type SpecificDecl.
- DeclContext::decl_iterator Current;
-
- /// SkipToNextDecl - Advances the current position up to the next
- /// declaration of type SpecificDecl that also meets the criteria
- /// required by Acceptable.
- void SkipToNextDecl() {
- while (*Current &&
- (!isa<SpecificDecl>(*Current) ||
- (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
- ++Current;
- }
-
- public:
- typedef SpecificDecl *value_type;
- // TODO: Add reference and pointer typedefs (with some appropriate proxy
- // type) if we ever have a need for them.
- typedef void reference;
- typedef void pointer;
- typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
- difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- filtered_decl_iterator() : Current() { }
-
- /// filtered_decl_iterator - Construct a new iterator over a
- /// subset of the declarations the range [C,
- /// end-of-declarations). If A is non-NULL, it is a pointer to a
- /// member function of SpecificDecl that should return true for
- /// all of the SpecificDecl instances that will be in the subset
- /// of iterators. For example, if you want Objective-C instance
- /// methods, SpecificDecl will be ObjCMethodDecl and A will be
- /// &ObjCMethodDecl::isInstanceMethod.
- explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
- SkipToNextDecl();
- }
-
- value_type operator*() const { return cast<SpecificDecl>(*Current); }
- value_type operator->() const { return cast<SpecificDecl>(*Current); }
-
- filtered_decl_iterator& operator++() {
- ++Current;
- SkipToNextDecl();
- return *this;
- }
-
- filtered_decl_iterator operator++(int) {
- filtered_decl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(const filtered_decl_iterator& x,
- const filtered_decl_iterator& y) {
- return x.Current == y.Current;
- }
-
- friend bool operator!=(const filtered_decl_iterator& x,
- const filtered_decl_iterator& y) {
- return x.Current != y.Current;
- }
- };
-
- /// @brief Add the declaration D into this context.
- ///
- /// This routine should be invoked when the declaration D has first
- /// been declared, to place D into the context where it was
- /// (lexically) defined. Every declaration must be added to one
- /// (and only one!) context, where it can be visited via
- /// [decls_begin(), decls_end()). Once a declaration has been added
- /// to its lexical context, the corresponding DeclContext owns the
- /// declaration.
- ///
- /// If D is also a NamedDecl, it will be made visible within its
- /// semantic context via makeDeclVisibleInContext.
- void addDecl(Decl *D);
-
- /// @brief Add the declaration D into this context, but suppress
- /// searches for external declarations with the same name.
- ///
- /// Although analogous in function to addDecl, this removes an
- /// important check. This is only useful if the Decl is being
- /// added in response to an external search; in all other cases,
- /// addDecl() is the right function to use.
- /// See the ASTImporter for use cases.
- void addDeclInternal(Decl *D);
-
- /// @brief Add the declaration D to this context without modifying
- /// any lookup tables.
- ///
- /// This is useful for some operations in dependent contexts where
- /// the semantic context might not be dependent; this basically
- /// only happens with friends.
- void addHiddenDecl(Decl *D);
-
- /// @brief Removes a declaration from this context.
- void removeDecl(Decl *D);
-
- /// @brief Checks whether a declaration is in this context.
- bool containsDecl(Decl *D) const;
-
- typedef DeclContextLookupResult lookup_result;
- typedef lookup_result::iterator lookup_iterator;
-
- /// lookup - Find the declarations (if any) with the given Name in
- /// this context. Returns a range of iterators that contains all of
- /// the declarations with this name, with object, function, member,
- /// and enumerator names preceding any tag name. Note that this
- /// routine will not look into parent contexts.
- lookup_result lookup(DeclarationName Name) const;
-
- /// \brief Find the declarations with the given name that are visible
- /// within this context; don't attempt to retrieve anything from an
- /// external source.
- lookup_result noload_lookup(DeclarationName Name);
-
- /// \brief A simplistic name lookup mechanism that performs name lookup
- /// into this declaration context without consulting the external source.
- ///
- /// This function should almost never be used, because it subverts the
- /// usual relationship between a DeclContext and the external source.
- /// See the ASTImporter for the (few, but important) use cases.
- ///
- /// FIXME: This is very inefficient; replace uses of it with uses of
- /// noload_lookup.
- void localUncachedLookup(DeclarationName Name,
- SmallVectorImpl<NamedDecl *> &Results);
-
- /// @brief Makes a declaration visible within this context.
- ///
- /// This routine makes the declaration D visible to name lookup
- /// within this context and, if this is a transparent context,
- /// within its parent contexts up to the first enclosing
- /// non-transparent context. Making a declaration visible within a
- /// context does not transfer ownership of a declaration, and a
- /// declaration can be visible in many contexts that aren't its
- /// lexical context.
- ///
- /// If D is a redeclaration of an existing declaration that is
- /// visible from this context, as determined by
- /// NamedDecl::declarationReplaces, the previous declaration will be
- /// replaced with D.
- void makeDeclVisibleInContext(NamedDecl *D);
-
- /// all_lookups_iterator - An iterator that provides a view over the results
- /// of looking up every possible name.
- class all_lookups_iterator;
-
- typedef llvm::iterator_range<all_lookups_iterator> lookups_range;
-
- lookups_range lookups() const;
- lookups_range noload_lookups() const;
-
- /// \brief Iterators over all possible lookups within this context.
- all_lookups_iterator lookups_begin() const;
- all_lookups_iterator lookups_end() const;
-
- /// \brief Iterators over all possible lookups within this context that are
- /// currently loaded; don't attempt to retrieve anything from an external
- /// source.
- all_lookups_iterator noload_lookups_begin() const;
- all_lookups_iterator noload_lookups_end() const;
-
- struct udir_iterator;
- typedef llvm::iterator_adaptor_base<udir_iterator, lookup_iterator,
- std::random_access_iterator_tag,
- UsingDirectiveDecl *> udir_iterator_base;
- struct udir_iterator : udir_iterator_base {
- udir_iterator(lookup_iterator I) : udir_iterator_base(I) {}
- UsingDirectiveDecl *operator*() const;
- };
-
- typedef llvm::iterator_range<udir_iterator> udir_range;
-
- udir_range using_directives() const;
-
- // These are all defined in DependentDiagnostic.h.
- class ddiag_iterator;
- typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range;
-
- inline ddiag_range ddiags() const;
-
- // Low-level accessors
-
- /// \brief Mark that there are external lexical declarations that we need
- /// to include in our lookup table (and that are not available as external
- /// visible lookups). These extra lookup results will be found by walking
- /// the lexical declarations of this context. This should be used only if
- /// setHasExternalLexicalStorage() has been called on any decl context for
- /// which this is the primary context.
- void setMustBuildLookupTable() {
- assert(this == getPrimaryContext() &&
- "should only be called on primary context");
- HasLazyExternalLexicalLookups = true;
- }
-
- /// \brief Retrieve the internal representation of the lookup structure.
- /// This may omit some names if we are lazily building the structure.
- StoredDeclsMap *getLookupPtr() const { return LookupPtr; }
-
- /// \brief Ensure the lookup structure is fully-built and return it.
- StoredDeclsMap *buildLookup();
-
- /// \brief Whether this DeclContext has external storage containing
- /// additional declarations that are lexically in this context.
- bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; }
-
- /// \brief State whether this DeclContext has external storage for
- /// declarations lexically in this context.
- void setHasExternalLexicalStorage(bool ES = true) {
- ExternalLexicalStorage = ES;
- }
-
- /// \brief Whether this DeclContext has external storage containing
- /// additional declarations that are visible in this context.
- bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; }
-
- /// \brief State whether this DeclContext has external storage for
- /// declarations visible in this context.
- void setHasExternalVisibleStorage(bool ES = true) {
- ExternalVisibleStorage = ES;
- if (ES && LookupPtr)
- NeedToReconcileExternalVisibleStorage = true;
- }
-
- /// \brief Determine whether the given declaration is stored in the list of
- /// declarations lexically within this context.
- bool isDeclInLexicalTraversal(const Decl *D) const {
- return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl ||
- D == LastDecl);
- }
-
- bool setUseQualifiedLookup(bool use = true) {
- bool old_value = UseQualifiedLookup;
- UseQualifiedLookup = use;
- return old_value;
- }
-
- bool shouldUseQualifiedLookup() const {
- return UseQualifiedLookup;
- }
-
- static bool classof(const Decl *D);
- static bool classof(const DeclContext *D) { return true; }
-
- void dumpDeclContext() const;
- void dumpLookups() const;
- void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false) const;
-
-private:
- void reconcileExternalVisibleStorage() const;
- bool LoadLexicalDeclsFromExternalStorage() const;
-
- /// @brief Makes a declaration visible within this context, but
- /// suppresses searches for external declarations with the same
- /// name.
- ///
- /// Analogous to makeDeclVisibleInContext, but for the exclusive
- /// use of addDeclInternal().
- void makeDeclVisibleInContextInternal(NamedDecl *D);
-
- friend class DependentDiagnostic;
- StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
-
- void buildLookupImpl(DeclContext *DCtx, bool Internal);
- void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
- bool Rediscoverable);
- void makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal);
-};
-
-inline bool Decl::isTemplateParameter() const {
- return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm ||
- getKind() == TemplateTemplateParm;
-}
-
-// Specialization selected when ToTy is not a known subclass of DeclContext.
-template <class ToTy,
- bool IsKnownSubtype = ::std::is_base_of<DeclContext, ToTy>::value>
-struct cast_convert_decl_context {
- static const ToTy *doit(const DeclContext *Val) {
- return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
- }
-
- static ToTy *doit(DeclContext *Val) {
- return static_cast<ToTy*>(Decl::castFromDeclContext(Val));
- }
-};
-
-// Specialization selected when ToTy is a known subclass of DeclContext.
-template <class ToTy>
-struct cast_convert_decl_context<ToTy, true> {
- static const ToTy *doit(const DeclContext *Val) {
- return static_cast<const ToTy*>(Val);
- }
-
- static ToTy *doit(DeclContext *Val) {
- return static_cast<ToTy*>(Val);
- }
-};
-
-
-} // end clang.
-
-namespace llvm {
-
-/// isa<T>(DeclContext*)
-template <typename To>
-struct isa_impl<To, ::clang::DeclContext> {
- static bool doit(const ::clang::DeclContext &Val) {
- return To::classofKind(Val.getDeclKind());
- }
-};
-
-/// cast<T>(DeclContext*)
-template<class ToTy>
-struct cast_convert_val<ToTy,
- const ::clang::DeclContext,const ::clang::DeclContext> {
- static const ToTy &doit(const ::clang::DeclContext &Val) {
- return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
- static ToTy &doit(::clang::DeclContext &Val) {
- return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy,
- const ::clang::DeclContext*, const ::clang::DeclContext*> {
- static const ToTy *doit(const ::clang::DeclContext *Val) {
- return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
- }
-};
-template<class ToTy>
-struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
- static ToTy *doit(::clang::DeclContext *Val) {
- return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
- }
-};
-
-/// Implement cast_convert_val for Decl -> DeclContext conversions.
-template<class FromTy>
-struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
- static ::clang::DeclContext &doit(const FromTy &Val) {
- return *FromTy::castToDeclContext(&Val);
- }
-};
-
-template<class FromTy>
-struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
- static ::clang::DeclContext *doit(const FromTy *Val) {
- return FromTy::castToDeclContext(Val);
- }
-};
-
-template<class FromTy>
-struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
- static const ::clang::DeclContext &doit(const FromTy &Val) {
- return *FromTy::castToDeclContext(&Val);
- }
-};
-
-template<class FromTy>
-struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
- static const ::clang::DeclContext *doit(const FromTy *Val) {
- return FromTy::castToDeclContext(Val);
- }
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
deleted file mode 100644
index 7c54901..0000000
--- a/include/clang/AST/DeclCXX.h
+++ /dev/null
@@ -1,3249 +0,0 @@
-//===-- DeclCXX.h - Classes for representing C++ declarations -*- C++ -*-=====//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the C++ Decl subclasses, other than those for templates
-/// (found in DeclTemplate.h) and friends (in DeclFriend.h).
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLCXX_H
-#define LLVM_CLANG_AST_DECLCXX_H
-
-#include "clang/AST/ASTUnresolvedSet.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/LambdaCapture.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-class ClassTemplateDecl;
-class ClassTemplateSpecializationDecl;
-class CXXBasePath;
-class CXXBasePaths;
-class CXXConstructorDecl;
-class CXXConversionDecl;
-class CXXDestructorDecl;
-class CXXMethodDecl;
-class CXXRecordDecl;
-class CXXMemberLookupCriteria;
-class CXXFinalOverriderMap;
-class CXXIndirectPrimaryBaseSet;
-class FriendDecl;
-class LambdaExpr;
-class UsingDecl;
-
-/// \brief 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);
-
- /// \brief Implicily converts any function or function template into a
- /// named declaration.
- operator NamedDecl *() const { return Function; }
-
- /// \brief Retrieve the underlying function or function template.
- NamedDecl *get() const { return Function; }
-
- static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
- return AnyFunctionDecl(ND);
- }
-};
-
-} // end namespace clang
-
-namespace llvm {
- // Provide PointerLikeTypeTraits for non-cvr pointers.
- template<>
- class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
- public:
- static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
- return F.get();
- }
- static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
- return ::clang::AnyFunctionDecl::getFromNamedDecl(
- static_cast< ::clang::NamedDecl*>(P));
- }
-
- enum { NumLowBitsAvailable = 2 };
- };
-
-} // end namespace llvm
-
-namespace clang {
-
-/// \brief Represents an access specifier followed by colon ':'.
-///
-/// An objects of this class represents sugar for the syntactic occurrence
-/// of an access specifier followed by a colon in the list of member
-/// specifiers of a C++ class definition.
-///
-/// Note that they do not represent other uses of access specifiers,
-/// such as those occurring in a list of base specifiers.
-/// Also note that this class has nothing to do with so-called
-/// "access declarations" (C++98 11.3 [class.access.dcl]).
-class AccessSpecDecl : public Decl {
- virtual void anchor();
- /// \brief The location of the ':'.
- SourceLocation ColonLoc;
-
- AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
- SourceLocation ASLoc, SourceLocation ColonLoc)
- : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
- setAccess(AS);
- }
- AccessSpecDecl(EmptyShell Empty)
- : Decl(AccessSpec, Empty) { }
-public:
- /// \brief The location of the access specifier.
- SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
- /// \brief Sets the location of the access specifier.
- void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
-
- /// \brief The location of the colon following the access specifier.
- SourceLocation getColonLoc() const { return ColonLoc; }
- /// \brief Sets the location of the colon.
- void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getAccessSpecifierLoc(), getColonLoc());
- }
-
- static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
- DeclContext *DC, SourceLocation ASLoc,
- SourceLocation ColonLoc) {
- return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
- }
- static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == AccessSpec; }
-};
-
-
-/// \brief Represents a base class of a C++ class.
-///
-/// Each CXXBaseSpecifier represents a single, direct base class (or
-/// struct) of a C++ class (or struct). It specifies the type of that
-/// base class, whether it is a virtual or non-virtual base, and what
-/// level of access (public, protected, private) is used for the
-/// derivation. For example:
-///
-/// \code
-/// class A { };
-/// class B { };
-/// class C : public virtual A, protected B { };
-/// \endcode
-///
-/// In this code, C will have two CXXBaseSpecifiers, one for "public
-/// virtual A" and the other for "protected B".
-class CXXBaseSpecifier {
- /// \brief The source code range that covers the full base
- /// specifier, including the "virtual" (if present) and access
- /// specifier (if present).
- SourceRange Range;
-
- /// \brief The source location of the ellipsis, if this is a pack
- /// expansion.
- SourceLocation EllipsisLoc;
-
- /// \brief Whether this is a virtual base class or not.
- bool Virtual : 1;
-
- /// \brief Whether this is the base of a class (true) or of a struct (false).
- ///
- /// This determines the mapping from the access specifier as written in the
- /// source code to the access specifier used for semantic analysis.
- bool BaseOfClass : 1;
-
- /// \brief Access specifier as written in the source code (may be AS_none).
- ///
- /// The actual type of data stored here is an AccessSpecifier, but we use
- /// "unsigned" here to work around a VC++ bug.
- unsigned Access : 2;
-
- /// \brief Whether the class contains a using declaration
- /// to inherit the named class's constructors.
- bool InheritConstructors : 1;
-
- /// \brief The type of the base class.
- ///
- /// This will be a class or struct (or a typedef of such). The source code
- /// range does not include the \c virtual or the access specifier.
- TypeSourceInfo *BaseTypeInfo;
-
-public:
- CXXBaseSpecifier() { }
-
- CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
- TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)
- : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC),
- Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { }
-
- /// \brief Retrieves the source range that contains the entire base specifier.
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
-
- /// \brief Determines whether the base class is a virtual base class (or not).
- bool isVirtual() const { return Virtual; }
-
- /// \brief Determine whether this base class is a base of a class declared
- /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
- bool isBaseOfClass() const { return BaseOfClass; }
-
- /// \brief Determine whether this base specifier is a pack expansion.
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-
- /// \brief Determine whether this base class's constructors get inherited.
- bool getInheritConstructors() const { return InheritConstructors; }
-
- /// \brief Set that this base class's constructors should be inherited.
- void setInheritConstructors(bool Inherit = true) {
- InheritConstructors = Inherit;
- }
-
- /// \brief For a pack expansion, determine the location of the ellipsis.
- SourceLocation getEllipsisLoc() const {
- return EllipsisLoc;
- }
-
- /// \brief Returns the access specifier for this base specifier.
- ///
- /// This is the actual base specifier as used for semantic analysis, so
- /// the result can never be AS_none. To retrieve the access specifier as
- /// written in the source code, use getAccessSpecifierAsWritten().
- AccessSpecifier getAccessSpecifier() const {
- if ((AccessSpecifier)Access == AS_none)
- return BaseOfClass? AS_private : AS_public;
- else
- return (AccessSpecifier)Access;
- }
-
- /// \brief Retrieves the access specifier as written in the source code
- /// (which may mean that no access specifier was explicitly written).
- ///
- /// Use getAccessSpecifier() to retrieve the access specifier for use in
- /// semantic analysis.
- AccessSpecifier getAccessSpecifierAsWritten() const {
- return (AccessSpecifier)Access;
- }
-
- /// \brief Retrieves the type of the base class.
- ///
- /// This type will always be an unqualified class type.
- QualType getType() const {
- return BaseTypeInfo->getType().getUnqualifiedType();
- }
-
- /// \brief Retrieves the type and source location of the base class.
- TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
-};
-
-/// \brief A lazy pointer to the definition data for a declaration.
-/// FIXME: This is a little CXXRecordDecl-specific that the moment.
-template<typename Decl, typename T> class LazyDefinitionDataPtr {
- llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
-
- LazyDefinitionDataPtr update() {
- if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
- if (Canon->isCanonicalDecl())
- Canon->getMostRecentDecl();
- else
- // Declaration isn't canonical any more;
- // update it and perform path compression.
- *this = Canon->getPreviousDecl()->DefinitionData.update();
- }
- return *this;
- }
-
-public:
- LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
- LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
- T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
- T *get() { return update().getNotUpdated(); }
-};
-
-/// \brief Represents a C++ struct/union/class.
-class CXXRecordDecl : public RecordDecl {
-
- friend void TagDecl::startDefinition();
-
- /// Values used in DefinitionData fields to represent special members.
- enum SpecialMemberFlags {
- SMF_DefaultConstructor = 0x1,
- SMF_CopyConstructor = 0x2,
- SMF_MoveConstructor = 0x4,
- SMF_CopyAssignment = 0x8,
- SMF_MoveAssignment = 0x10,
- SMF_Destructor = 0x20,
- SMF_All = 0x3f
- };
-
- struct DefinitionData {
- DefinitionData(CXXRecordDecl *D);
-
- /// \brief True if this class has any user-declared constructors.
- bool UserDeclaredConstructor : 1;
-
- /// \brief The user-declared special members which this class has.
- unsigned UserDeclaredSpecialMembers : 6;
-
- /// \brief True when this class is an aggregate.
- bool Aggregate : 1;
-
- /// \brief True when this class is a POD-type.
- bool PlainOldData : 1;
-
- /// true when this class is empty for traits purposes,
- /// i.e. has no data members other than 0-width bit-fields, has no
- /// virtual function/base, and doesn't inherit from a non-empty
- /// class. Doesn't take union-ness into account.
- bool Empty : 1;
-
- /// \brief True when this class is polymorphic, i.e., has at
- /// least one virtual member or derives from a polymorphic class.
- bool Polymorphic : 1;
-
- /// \brief True when this class is abstract, i.e., has at least
- /// one pure virtual function, (that can come from a base class).
- bool Abstract : 1;
-
- /// \brief True when this class has standard layout.
- ///
- /// 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.
- bool IsStandardLayout : 1;
-
- /// \brief True when there are no non-empty base classes.
- ///
- /// This is a helper bit of state used to implement IsStandardLayout more
- /// efficiently.
- bool HasNoNonEmptyBases : 1;
-
- /// \brief True when there are private non-static data members.
- bool HasPrivateFields : 1;
-
- /// \brief True when there are protected non-static data members.
- bool HasProtectedFields : 1;
-
- /// \brief True when there are private non-static data members.
- bool HasPublicFields : 1;
-
- /// \brief True if this class (or any subobject) has mutable fields.
- bool HasMutableFields : 1;
-
- /// \brief True if this class (or any nested anonymous struct or union)
- /// has variant members.
- bool HasVariantMembers : 1;
-
- /// \brief True if there no non-field members declared by the user.
- bool HasOnlyCMembers : 1;
-
- /// \brief True if any field has an in-class initializer, including those
- /// within anonymous unions or structs.
- bool HasInClassInitializer : 1;
-
- /// \brief 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.
- bool HasUninitializedReferenceMember : 1;
-
- /// \brief These flags are \c true if a defaulted corresponding special
- /// member can't be fully analyzed without performing overload resolution.
- /// @{
- bool NeedOverloadResolutionForMoveConstructor : 1;
- bool NeedOverloadResolutionForMoveAssignment : 1;
- bool NeedOverloadResolutionForDestructor : 1;
- /// @}
-
- /// \brief These flags are \c true if an implicit defaulted corresponding
- /// special member would be defined as deleted.
- /// @{
- bool DefaultedMoveConstructorIsDeleted : 1;
- bool DefaultedMoveAssignmentIsDeleted : 1;
- bool DefaultedDestructorIsDeleted : 1;
- /// @}
-
- /// \brief 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;
-
- /// \brief 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;
-
- /// \brief True when this class has a destructor with no semantic effect.
- bool HasIrrelevantDestructor : 1;
-
- /// \brief True when this class has at least one user-declared constexpr
- /// constructor which is neither the copy nor move constructor.
- bool HasConstexprNonCopyMoveConstructor : 1;
-
- /// \brief True if a defaulted default constructor for this class would
- /// be constexpr.
- bool DefaultedDefaultConstructorIsConstexpr : 1;
-
- /// \brief 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.
- bool HasConstexprDefaultConstructor : 1;
-
- /// \brief True when this class contains at least one non-static data
- /// member or base class of non-literal or volatile type.
- bool HasNonLiteralTypeFieldsOrBases : 1;
-
- /// \brief True when visible conversion functions are already computed
- /// and are available.
- bool ComputedVisibleConversions : 1;
-
- /// \brief Whether we have a C++11 user-provided default constructor (not
- /// explicitly deleted or defaulted).
- bool UserProvidedDefaultConstructor : 1;
-
- /// \brief The special members which have been declared for this class,
- /// either by the user or implicitly.
- unsigned DeclaredSpecialMembers : 6;
-
- /// \brief Whether an implicit copy constructor would have a const-qualified
- /// parameter.
- bool ImplicitCopyConstructorHasConstParam : 1;
-
- /// \brief Whether an implicit copy assignment operator would have a
- /// const-qualified parameter.
- bool ImplicitCopyAssignmentHasConstParam : 1;
-
- /// \brief Whether any declared copy constructor has a const-qualified
- /// parameter.
- bool HasDeclaredCopyConstructorWithConstParam : 1;
-
- /// \brief Whether any declared copy assignment operator has either a
- /// const-qualified reference parameter or a non-reference parameter.
- bool HasDeclaredCopyAssignmentWithConstParam : 1;
-
- /// \brief Whether this class describes a C++ lambda.
- bool IsLambda : 1;
-
- /// \brief Whether we are currently parsing base specifiers.
- bool IsParsingBaseSpecifiers : 1;
-
- /// \brief The number of base class specifiers in Bases.
- unsigned NumBases;
-
- /// \brief The number of virtual base class specifiers in VBases.
- unsigned NumVBases;
-
- /// \brief Base classes of this class.
- ///
- /// FIXME: This is wasted space for a union.
- LazyCXXBaseSpecifiersPtr Bases;
-
- /// \brief direct and indirect virtual base classes of this class.
- LazyCXXBaseSpecifiersPtr VBases;
-
- /// \brief The conversion functions of this C++ class (but not its
- /// inherited conversion functions).
- ///
- /// Each of the entries in this overload set is a CXXConversionDecl.
- LazyASTUnresolvedSet Conversions;
-
- /// \brief The conversion functions of this C++ class and all those
- /// inherited conversion functions that are visible in this class.
- ///
- /// Each of the entries in this overload set is a CXXConversionDecl or a
- /// FunctionTemplateDecl.
- LazyASTUnresolvedSet VisibleConversions;
-
- /// \brief The declaration which defines this record.
- CXXRecordDecl *Definition;
-
- /// \brief The first friend declaration in this class, or null if there
- /// aren't any.
- ///
- /// This is actually currently stored in reverse order.
- LazyDeclPtr FirstFriend;
-
- /// \brief Retrieve the set of direct base classes.
- CXXBaseSpecifier *getBases() const {
- if (!Bases.isOffset())
- return Bases.get(nullptr);
- return getBasesSlowCase();
- }
-
- /// \brief Retrieve the set of virtual base classes.
- CXXBaseSpecifier *getVBases() const {
- if (!VBases.isOffset())
- return VBases.get(nullptr);
- return getVBasesSlowCase();
- }
-
- private:
- CXXBaseSpecifier *getBasesSlowCase() const;
- CXXBaseSpecifier *getVBasesSlowCase() const;
- };
-
- typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
- DefinitionDataPtr;
- friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
-
- mutable DefinitionDataPtr DefinitionData;
-
- /// \brief Describes a C++ closure type (generated by a lambda expression).
- struct LambdaDefinitionData : public DefinitionData {
- typedef LambdaCapture Capture;
-
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
- bool Dependent, bool IsGeneric,
- LambdaCaptureDefault CaptureDefault)
- : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
- CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0),
- ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
- MethodTyInfo(Info) {
- IsLambda = true;
-
- // C++11 [expr.prim.lambda]p3:
- // This class type is neither an aggregate nor a literal type.
- Aggregate = false;
- PlainOldData = false;
- HasNonLiteralTypeFieldsOrBases = true;
- }
-
- /// \brief Whether this lambda is known to be dependent, even if its
- /// context isn't dependent.
- ///
- /// A lambda with a non-dependent context can be dependent if it occurs
- /// within the default argument of a function template, because the
- /// lambda will have been created with the enclosing context as its
- /// declaration context, rather than function. This is an unfortunate
- /// artifact of having to parse the default arguments before.
- unsigned Dependent : 1;
-
- /// \brief Whether this lambda is a generic lambda.
- unsigned IsGenericLambda : 1;
-
- /// \brief The Default Capture.
- unsigned CaptureDefault : 2;
-
- /// \brief The number of captures in this lambda is limited 2^NumCaptures.
- unsigned NumCaptures : 15;
-
- /// \brief The number of explicit captures in this lambda.
- unsigned NumExplicitCaptures : 13;
-
- /// \brief The number used to indicate this lambda expression for name
- /// mangling in the Itanium C++ ABI.
- unsigned ManglingNumber;
-
- /// \brief The declaration that provides context for this lambda, if the
- /// actual DeclContext does not suffice. This is used for lambdas that
- /// occur within default arguments of function parameters within the class
- /// or within a data member initializer.
- Decl *ContextDecl;
-
- /// \brief The list of captures, both explicit and implicit, for this
- /// lambda.
- Capture *Captures;
-
- /// \brief The type of the call method.
- TypeSourceInfo *MethodTyInfo;
-
- };
-
- struct DefinitionData &data() const {
- auto *DD = DefinitionData.get();
- assert(DD && "queried property of class with no definition");
- return *DD;
- }
-
- struct LambdaDefinitionData &getLambdaData() const {
- // No update required: a merged definition cannot change any lambda
- // properties.
- auto *DD = DefinitionData.getNotUpdated();
- assert(DD && DD->IsLambda && "queried lambda property of non-lambda class");
- return static_cast<LambdaDefinitionData&>(*DD);
- }
-
- /// \brief The template or declaration that this declaration
- /// describes or was instantiated from, respectively.
- ///
- /// For non-templates, this value will be null. For record
- /// declarations that describe a class template, this will be a
- /// pointer to a ClassTemplateDecl. For member
- /// classes of class template specializations, this will be the
- /// MemberSpecializationInfo referring to the member class that was
- /// instantiated or specialized.
- llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
- TemplateOrInstantiation;
-
- friend class DeclContext;
- friend class LambdaExpr;
-
- /// \brief Called from setBases and addedMember to notify the class that a
- /// direct or virtual base class or a member of class type has been added.
- void addedClassSubobject(CXXRecordDecl *Base);
-
- /// \brief Notify the class that member has been added.
- ///
- /// This routine helps maintain information about the class based on which
- /// members have been added. It will be invoked by DeclContext::addDecl()
- /// whenever a member is added to this record.
- void addedMember(Decl *D);
-
- void markedVirtualFunctionPure();
- friend void FunctionDecl::setPure(bool);
-
- friend class ASTNodeImporter;
-
- /// \brief Get the head of our list of friend declarations, possibly
- /// deserializing the friends from an external AST source.
- FriendDecl *getFirstFriend() const;
-
-protected:
- CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
-
-public:
- /// \brief Iterator that traverses the base classes of a class.
- typedef CXXBaseSpecifier* base_class_iterator;
-
- /// \brief Iterator that traverses the base classes of a class.
- typedef const CXXBaseSpecifier* base_class_const_iterator;
-
- CXXRecordDecl *getCanonicalDecl() override {
- return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
- }
- const CXXRecordDecl *getCanonicalDecl() const {
- return const_cast<CXXRecordDecl*>(this)->getCanonicalDecl();
- }
-
- CXXRecordDecl *getPreviousDecl() {
- return cast_or_null<CXXRecordDecl>(
- static_cast<RecordDecl *>(this)->getPreviousDecl());
- }
- const CXXRecordDecl *getPreviousDecl() const {
- return const_cast<CXXRecordDecl*>(this)->getPreviousDecl();
- }
-
- CXXRecordDecl *getMostRecentDecl() {
- return cast<CXXRecordDecl>(
- static_cast<RecordDecl *>(this)->getMostRecentDecl());
- }
-
- const CXXRecordDecl *getMostRecentDecl() const {
- return const_cast<CXXRecordDecl*>(this)->getMostRecentDecl();
- }
-
- CXXRecordDecl *getDefinition() const {
- auto *DD = DefinitionData.get();
- return DD ? DD->Definition : nullptr;
- }
-
- bool hasDefinition() const { return DefinitionData.get(); }
-
- static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id,
- CXXRecordDecl *PrevDecl = nullptr,
- bool DelayTypeCreation = false);
- static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
- TypeSourceInfo *Info, SourceLocation Loc,
- bool DependentLambda, bool IsGeneric,
- LambdaCaptureDefault CaptureDefault);
- static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
-
- bool isDynamicClass() const {
- return data().Polymorphic || data().NumVBases != 0;
- }
-
- void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
-
- bool isParsingBaseSpecifiers() const {
- return data().IsParsingBaseSpecifiers;
- }
-
- /// \brief Sets the base classes of this struct or class.
- void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
-
- /// \brief Retrieves the number of base classes of this class.
- unsigned getNumBases() const { return data().NumBases; }
-
- typedef llvm::iterator_range<base_class_iterator> base_class_range;
- typedef llvm::iterator_range<base_class_const_iterator>
- base_class_const_range;
-
- base_class_range bases() {
- return base_class_range(bases_begin(), bases_end());
- }
- base_class_const_range bases() const {
- return base_class_const_range(bases_begin(), bases_end());
- }
-
- base_class_iterator bases_begin() { return data().getBases(); }
- base_class_const_iterator bases_begin() const { return data().getBases(); }
- base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
- base_class_const_iterator bases_end() const {
- return bases_begin() + data().NumBases;
- }
-
- /// \brief Retrieves the number of virtual base classes of this class.
- unsigned getNumVBases() const { return data().NumVBases; }
-
- base_class_range vbases() {
- return base_class_range(vbases_begin(), vbases_end());
- }
- base_class_const_range vbases() const {
- return base_class_const_range(vbases_begin(), vbases_end());
- }
-
- base_class_iterator vbases_begin() { return data().getVBases(); }
- base_class_const_iterator vbases_begin() const { return data().getVBases(); }
- base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
- base_class_const_iterator vbases_end() const {
- return vbases_begin() + data().NumVBases;
- }
-
- /// \brief Determine whether this class has any dependent base classes which
- /// are not the current instantiation.
- bool hasAnyDependentBases() const;
-
- /// Iterator access to method members. The method iterator visits
- /// all method members of the class, including non-instance methods,
- /// special methods, etc.
- typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>
- method_range;
-
- method_range methods() const {
- return method_range(method_begin(), method_end());
- }
-
- /// \brief Method begin iterator. Iterates in the order the methods
- /// were declared.
- method_iterator method_begin() const {
- return method_iterator(decls_begin());
- }
- /// \brief Method past-the-end iterator.
- method_iterator method_end() const {
- return method_iterator(decls_end());
- }
-
- /// Iterator access to constructor members.
- typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>
- ctor_range;
-
- ctor_range ctors() const { return ctor_range(ctor_begin(), ctor_end()); }
-
- ctor_iterator ctor_begin() const {
- return ctor_iterator(decls_begin());
- }
- ctor_iterator ctor_end() const {
- return ctor_iterator(decls_end());
- }
-
- /// An iterator over friend declarations. All of these are defined
- /// in DeclFriend.h.
- class friend_iterator;
- typedef llvm::iterator_range<friend_iterator> friend_range;
-
- friend_range friends() const;
- friend_iterator friend_begin() const;
- friend_iterator friend_end() const;
- void pushFriendDecl(FriendDecl *FD);
-
- /// Determines whether this record has any friends.
- bool hasFriends() const {
- return data().FirstFriend.isValid();
- }
-
- /// \brief \c true if we know for sure that this class has a single,
- /// accessible, unambiguous move constructor that is not deleted.
- bool hasSimpleMoveConstructor() const {
- return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() &&
- !data().DefaultedMoveConstructorIsDeleted;
- }
- /// \brief \c true if we know for sure that this class has a single,
- /// accessible, unambiguous move assignment operator that is not deleted.
- bool hasSimpleMoveAssignment() const {
- return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
- !data().DefaultedMoveAssignmentIsDeleted;
- }
- /// \brief \c true if we know for sure that this class has an accessible
- /// destructor that is not deleted.
- bool hasSimpleDestructor() const {
- return !hasUserDeclaredDestructor() &&
- !data().DefaultedDestructorIsDeleted;
- }
-
- /// \brief Determine whether this class has any default constructors.
- bool hasDefaultConstructor() const {
- return (data().DeclaredSpecialMembers & SMF_DefaultConstructor) ||
- needsImplicitDefaultConstructor();
- }
-
- /// \brief Determine if we need to declare a default constructor for
- /// this class.
- ///
- /// This value is used for lazy creation of default constructors.
- bool needsImplicitDefaultConstructor() const {
- return !data().UserDeclaredConstructor &&
- !(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
- // C++14 [expr.prim.lambda]p20:
- // The closure type associated with a lambda-expression has no
- // default constructor.
- !isLambda();
- }
-
- /// \brief Determine whether this class has any user-declared constructors.
- ///
- /// When true, a default constructor will not be implicitly declared.
- bool hasUserDeclaredConstructor() const {
- return data().UserDeclaredConstructor;
- }
-
- /// \brief Whether this class has a user-provided default constructor
- /// per C++11.
- bool hasUserProvidedDefaultConstructor() const {
- return data().UserProvidedDefaultConstructor;
- }
-
- /// \brief Determine whether this class has a user-declared copy constructor.
- ///
- /// When false, a copy constructor will be implicitly declared.
- bool hasUserDeclaredCopyConstructor() const {
- return data().UserDeclaredSpecialMembers & SMF_CopyConstructor;
- }
-
- /// \brief Determine whether this class needs an implicit copy
- /// constructor to be lazily declared.
- bool needsImplicitCopyConstructor() const {
- return !(data().DeclaredSpecialMembers & SMF_CopyConstructor);
- }
-
- /// \brief Determine whether we need to eagerly declare a defaulted copy
- /// constructor for this class.
- bool needsOverloadResolutionForCopyConstructor() const {
- return data().HasMutableFields;
- }
-
- /// \brief Determine whether an implicit copy constructor for this type
- /// would have a parameter with a const-qualified reference type.
- bool implicitCopyConstructorHasConstParam() const {
- return data().ImplicitCopyConstructorHasConstParam;
- }
-
- /// \brief Determine whether this class has a copy constructor with
- /// a parameter type which is a reference to a const-qualified type.
- bool hasCopyConstructorWithConstParam() const {
- return data().HasDeclaredCopyConstructorWithConstParam ||
- (needsImplicitCopyConstructor() &&
- implicitCopyConstructorHasConstParam());
- }
-
- /// \brief Whether this class has a user-declared move constructor or
- /// assignment operator.
- ///
- /// When false, a move constructor and assignment operator may be
- /// implicitly declared.
- bool hasUserDeclaredMoveOperation() const {
- return data().UserDeclaredSpecialMembers &
- (SMF_MoveConstructor | SMF_MoveAssignment);
- }
-
- /// \brief Determine whether this class has had a move constructor
- /// declared by the user.
- bool hasUserDeclaredMoveConstructor() const {
- return data().UserDeclaredSpecialMembers & SMF_MoveConstructor;
- }
-
- /// \brief Determine whether this class has a move constructor.
- bool hasMoveConstructor() const {
- return (data().DeclaredSpecialMembers & SMF_MoveConstructor) ||
- needsImplicitMoveConstructor();
- }
-
- /// \brief Set that we attempted to declare an implicitly move
- /// constructor, but overload resolution failed so we deleted it.
- void setImplicitMoveConstructorIsDeleted() {
- assert((data().DefaultedMoveConstructorIsDeleted ||
- needsOverloadResolutionForMoveConstructor()) &&
- "move constructor should not be deleted");
- data().DefaultedMoveConstructorIsDeleted = true;
- }
-
- /// \brief Determine whether this class should get an implicit move
- /// constructor or if any existing special member function inhibits this.
- bool needsImplicitMoveConstructor() const {
- return !(data().DeclaredSpecialMembers & SMF_MoveConstructor) &&
- !hasUserDeclaredCopyConstructor() &&
- !hasUserDeclaredCopyAssignment() &&
- !hasUserDeclaredMoveAssignment() &&
- !hasUserDeclaredDestructor();
- }
-
- /// \brief Determine whether we need to eagerly declare a defaulted move
- /// constructor for this class.
- bool needsOverloadResolutionForMoveConstructor() const {
- return data().NeedOverloadResolutionForMoveConstructor;
- }
-
- /// \brief Determine whether this class has a user-declared copy assignment
- /// operator.
- ///
- /// When false, a copy assigment operator will be implicitly declared.
- bool hasUserDeclaredCopyAssignment() const {
- return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
- }
-
- /// \brief Determine whether this class needs an implicit copy
- /// assignment operator to be lazily declared.
- bool needsImplicitCopyAssignment() const {
- return !(data().DeclaredSpecialMembers & SMF_CopyAssignment);
- }
-
- /// \brief Determine whether we need to eagerly declare a defaulted copy
- /// assignment operator for this class.
- bool needsOverloadResolutionForCopyAssignment() const {
- return data().HasMutableFields;
- }
-
- /// \brief Determine whether an implicit copy assignment operator for this
- /// type would have a parameter with a const-qualified reference type.
- bool implicitCopyAssignmentHasConstParam() const {
- return data().ImplicitCopyAssignmentHasConstParam;
- }
-
- /// \brief Determine whether this class has a copy assignment operator with
- /// a parameter type which is a reference to a const-qualified type or is not
- /// a reference.
- bool hasCopyAssignmentWithConstParam() const {
- return data().HasDeclaredCopyAssignmentWithConstParam ||
- (needsImplicitCopyAssignment() &&
- implicitCopyAssignmentHasConstParam());
- }
-
- /// \brief Determine whether this class has had a move assignment
- /// declared by the user.
- bool hasUserDeclaredMoveAssignment() const {
- return data().UserDeclaredSpecialMembers & SMF_MoveAssignment;
- }
-
- /// \brief Determine whether this class has a move assignment operator.
- bool hasMoveAssignment() const {
- return (data().DeclaredSpecialMembers & SMF_MoveAssignment) ||
- needsImplicitMoveAssignment();
- }
-
- /// \brief Set that we attempted to declare an implicit move assignment
- /// operator, but overload resolution failed so we deleted it.
- void setImplicitMoveAssignmentIsDeleted() {
- assert((data().DefaultedMoveAssignmentIsDeleted ||
- needsOverloadResolutionForMoveAssignment()) &&
- "move assignment should not be deleted");
- data().DefaultedMoveAssignmentIsDeleted = true;
- }
-
- /// \brief Determine whether this class should get an implicit move
- /// assignment operator or if any existing special member function inhibits
- /// this.
- bool needsImplicitMoveAssignment() const {
- return !(data().DeclaredSpecialMembers & SMF_MoveAssignment) &&
- !hasUserDeclaredCopyConstructor() &&
- !hasUserDeclaredCopyAssignment() &&
- !hasUserDeclaredMoveConstructor() &&
- !hasUserDeclaredDestructor();
- }
-
- /// \brief Determine whether we need to eagerly declare a move assignment
- /// operator for this class.
- bool needsOverloadResolutionForMoveAssignment() const {
- return data().NeedOverloadResolutionForMoveAssignment;
- }
-
- /// \brief Determine whether this class has a user-declared destructor.
- ///
- /// When false, a destructor will be implicitly declared.
- bool hasUserDeclaredDestructor() const {
- return data().UserDeclaredSpecialMembers & SMF_Destructor;
- }
-
- /// \brief Determine whether this class needs an implicit destructor to
- /// be lazily declared.
- bool needsImplicitDestructor() const {
- return !(data().DeclaredSpecialMembers & SMF_Destructor);
- }
-
- /// \brief Determine whether we need to eagerly declare a destructor for this
- /// class.
- bool needsOverloadResolutionForDestructor() const {
- return data().NeedOverloadResolutionForDestructor;
- }
-
- /// \brief Determine whether this class describes a lambda function object.
- bool isLambda() const {
- // An update record can't turn a non-lambda into a lambda.
- auto *DD = DefinitionData.getNotUpdated();
- return DD && DD->IsLambda;
- }
-
- /// \brief Determine whether this class describes a generic
- /// lambda function object (i.e. function call operator is
- /// a template).
- bool isGenericLambda() const;
-
- /// \brief Retrieve the lambda call operator of the closure type
- /// if this is a closure type.
- CXXMethodDecl *getLambdaCallOperator() const;
-
- /// \brief 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.
- CXXMethodDecl *getLambdaStaticInvoker() const;
-
- /// \brief Retrieve the generic lambda's template parameter list.
- /// Returns null if the class does not represent a lambda or a generic
- /// lambda.
- TemplateParameterList *getGenericLambdaTemplateParameterList() const;
-
- LambdaCaptureDefault getLambdaCaptureDefault() const {
- assert(isLambda());
- return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
- }
-
- /// \brief For a closure type, retrieve the mapping from captured
- /// variables and \c this to the non-static data members that store the
- /// values or references of the captures.
- ///
- /// \param Captures Will be populated with the mapping from captured
- /// variables to the corresponding fields.
- ///
- /// \param ThisCapture Will be set to the field declaration for the
- /// \c this capture.
- ///
- /// \note No entries will be added for init-captures, as they do not capture
- /// variables.
- void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
- FieldDecl *&ThisCapture) const;
-
- typedef const LambdaCapture *capture_const_iterator;
- typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
-
- capture_const_range captures() const {
- return capture_const_range(captures_begin(), captures_end());
- }
- capture_const_iterator captures_begin() const {
- return isLambda() ? getLambdaData().Captures : nullptr;
- }
- capture_const_iterator captures_end() const {
- return isLambda() ? captures_begin() + getLambdaData().NumCaptures
- : nullptr;
- }
-
- typedef UnresolvedSetIterator conversion_iterator;
- conversion_iterator conversion_begin() const {
- return data().Conversions.get(getASTContext()).begin();
- }
- conversion_iterator conversion_end() const {
- return data().Conversions.get(getASTContext()).end();
- }
-
- /// Removes a conversion function from this class. The conversion
- /// function must currently be a member of this class. Furthermore,
- /// this class must currently be in the process of being defined.
- void removeConversion(const NamedDecl *Old);
-
- /// \brief Get all conversion functions visible in current class,
- /// including conversion function templates.
- llvm::iterator_range<conversion_iterator> getVisibleConversionFunctions();
-
- /// Determine whether this class is an aggregate (C++ [dcl.init.aggr]),
- /// which is a class with no user-declared constructors, no private
- /// or protected non-static data members, no base classes, and no virtual
- /// functions (C++ [dcl.init.aggr]p1).
- bool isAggregate() const { return data().Aggregate; }
-
- /// \brief Whether this class has any in-class initializers
- /// for non-static data members (including those in anonymous unions or
- /// structs).
- bool hasInClassInitializer() const { return data().HasInClassInitializer; }
-
- /// \brief Whether this class or any of its subobjects has any members of
- /// reference type which would make value-initialization ill-formed.
- ///
- /// Per C++03 [dcl.init]p5:
- /// - if T is a non-union class type without a user-declared constructor,
- /// then every non-static data member and base-class component of T is
- /// value-initialized [...] A program that calls for [...]
- /// value-initialization of an entity of reference type is ill-formed.
- bool hasUninitializedReferenceMember() const {
- return !isUnion() && !hasUserDeclaredConstructor() &&
- data().HasUninitializedReferenceMember;
- }
-
- /// \brief Whether this class is a POD-type (C++ [class]p4)
- ///
- /// For purposes of this function a class is POD if it is an aggregate
- /// that has no non-static non-POD data members, no reference data
- /// members, no user-defined copy assignment operator and no
- /// user-defined destructor.
- ///
- /// Note that this is the C++ TR1 definition of POD.
- bool isPOD() const { return data().PlainOldData; }
-
- /// \brief True if this class is C-like, without C++-specific features, e.g.
- /// it contains only public fields, no bases, tag kind is not 'class', etc.
- bool isCLike() const;
-
- /// \brief Determine whether this is an empty class in the sense of
- /// (C++11 [meta.unary.prop]).
- ///
- /// A non-union class is empty iff it has a virtual function, virtual base,
- /// data member (other than 0-width bit-field) or inherits from a non-empty
- /// class.
- ///
- /// \note This does NOT include a check for union-ness.
- bool isEmpty() const { return data().Empty; }
-
- /// Whether this class is polymorphic (C++ [class.virtual]),
- /// which means that the class contains or inherits a virtual function.
- bool isPolymorphic() const { return data().Polymorphic; }
-
- /// \brief Determine whether this class has a pure virtual function.
- ///
- /// The class is is abstract per (C++ [class.abstract]p2) if it declares
- /// a pure virtual function or inherits a pure virtual function that is
- /// not overridden.
- bool isAbstract() const { return data().Abstract; }
-
- /// \brief Determine whether this class has standard layout per
- /// (C++ [class]p7)
- bool isStandardLayout() const { return data().IsStandardLayout; }
-
- /// \brief Determine whether this class, or any of its class subobjects,
- /// contains a mutable field.
- bool hasMutableFields() const { return data().HasMutableFields; }
-
- /// \brief Determine whether this class has any variant members.
- bool hasVariantMembers() const { return data().HasVariantMembers; }
-
- /// \brief Determine whether this class has a trivial default constructor
- /// (C++11 [class.ctor]p5).
- bool hasTrivialDefaultConstructor() const {
- return hasDefaultConstructor() &&
- (data().HasTrivialSpecialMembers & SMF_DefaultConstructor);
- }
-
- /// \brief Determine whether this class has a non-trivial default constructor
- /// (C++11 [class.ctor]p5).
- bool hasNonTrivialDefaultConstructor() const {
- return (data().DeclaredNonTrivialSpecialMembers & SMF_DefaultConstructor) ||
- (needsImplicitDefaultConstructor() &&
- !(data().HasTrivialSpecialMembers & SMF_DefaultConstructor));
- }
-
- /// \brief Determine whether this class has at least one constexpr constructor
- /// other than the copy or move constructors.
- bool hasConstexprNonCopyMoveConstructor() const {
- return data().HasConstexprNonCopyMoveConstructor ||
- (needsImplicitDefaultConstructor() &&
- defaultedDefaultConstructorIsConstexpr());
- }
-
- /// \brief Determine whether a defaulted default constructor for this class
- /// would be constexpr.
- bool defaultedDefaultConstructorIsConstexpr() const {
- return data().DefaultedDefaultConstructorIsConstexpr &&
- (!isUnion() || hasInClassInitializer() || !hasVariantMembers());
- }
-
- /// \brief Determine whether this class has a constexpr default constructor.
- bool hasConstexprDefaultConstructor() const {
- return data().HasConstexprDefaultConstructor ||
- (needsImplicitDefaultConstructor() &&
- defaultedDefaultConstructorIsConstexpr());
- }
-
- /// \brief Determine whether this class has a trivial copy constructor
- /// (C++ [class.copy]p6, C++11 [class.copy]p12)
- bool hasTrivialCopyConstructor() const {
- return data().HasTrivialSpecialMembers & SMF_CopyConstructor;
- }
-
- /// \brief Determine whether this class has a non-trivial copy constructor
- /// (C++ [class.copy]p6, C++11 [class.copy]p12)
- bool hasNonTrivialCopyConstructor() const {
- return data().DeclaredNonTrivialSpecialMembers & SMF_CopyConstructor ||
- !hasTrivialCopyConstructor();
- }
-
- /// \brief Determine whether this class has a trivial move constructor
- /// (C++11 [class.copy]p12)
- bool hasTrivialMoveConstructor() const {
- return hasMoveConstructor() &&
- (data().HasTrivialSpecialMembers & SMF_MoveConstructor);
- }
-
- /// \brief Determine whether this class has a non-trivial move constructor
- /// (C++11 [class.copy]p12)
- bool hasNonTrivialMoveConstructor() const {
- return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveConstructor) ||
- (needsImplicitMoveConstructor() &&
- !(data().HasTrivialSpecialMembers & SMF_MoveConstructor));
- }
-
- /// \brief Determine whether this class has a trivial copy assignment operator
- /// (C++ [class.copy]p11, C++11 [class.copy]p25)
- bool hasTrivialCopyAssignment() const {
- return data().HasTrivialSpecialMembers & SMF_CopyAssignment;
- }
-
- /// \brief Determine whether this class has a non-trivial copy assignment
- /// operator (C++ [class.copy]p11, C++11 [class.copy]p25)
- bool hasNonTrivialCopyAssignment() const {
- return data().DeclaredNonTrivialSpecialMembers & SMF_CopyAssignment ||
- !hasTrivialCopyAssignment();
- }
-
- /// \brief Determine whether this class has a trivial move assignment operator
- /// (C++11 [class.copy]p25)
- bool hasTrivialMoveAssignment() const {
- return hasMoveAssignment() &&
- (data().HasTrivialSpecialMembers & SMF_MoveAssignment);
- }
-
- /// \brief Determine whether this class has a non-trivial move assignment
- /// operator (C++11 [class.copy]p25)
- bool hasNonTrivialMoveAssignment() const {
- return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveAssignment) ||
- (needsImplicitMoveAssignment() &&
- !(data().HasTrivialSpecialMembers & SMF_MoveAssignment));
- }
-
- /// \brief Determine whether this class has a trivial destructor
- /// (C++ [class.dtor]p3)
- bool hasTrivialDestructor() const {
- return data().HasTrivialSpecialMembers & SMF_Destructor;
- }
-
- /// \brief Determine whether this class has a non-trivial destructor
- /// (C++ [class.dtor]p3)
- bool hasNonTrivialDestructor() const {
- return !(data().HasTrivialSpecialMembers & SMF_Destructor);
- }
-
- /// \brief Determine whether this class has a destructor which has no
- /// semantic effect.
- ///
- /// Any such destructor will be trivial, public, defaulted and not deleted,
- /// and will call only irrelevant destructors.
- bool hasIrrelevantDestructor() const {
- return data().HasIrrelevantDestructor;
- }
-
- /// \brief Determine whether this class has a non-literal or/ volatile type
- /// non-static data member or base class.
- bool hasNonLiteralTypeFieldsOrBases() const {
- return data().HasNonLiteralTypeFieldsOrBases;
- }
-
- /// \brief Determine whether this class is considered trivially copyable per
- /// (C++11 [class]p6).
- bool isTriviallyCopyable() const;
-
- /// \brief Determine whether this class is considered trivial.
- ///
- /// C++11 [class]p6:
- /// "A trivial class is a class that has a trivial default constructor and
- /// is trivially copiable."
- bool isTrivial() const {
- return isTriviallyCopyable() && hasTrivialDefaultConstructor();
- }
-
- /// \brief Determine whether this class is a literal type.
- ///
- /// C++11 [basic.types]p10:
- /// A class type that has all the following properties:
- /// - it has a trivial destructor
- /// - every constructor call and full-expression in the
- /// brace-or-equal-intializers for non-static data members (if any) is
- /// a constant expression.
- /// - it is an aggregate type or has at least one constexpr constructor
- /// or constructor template that is not a copy or move constructor, and
- /// - all of its non-static data members and base classes are of literal
- /// types
- ///
- /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
- /// treating types with trivial default constructors as literal types.
- bool isLiteral() const {
- return hasTrivialDestructor() &&
- (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
- hasTrivialDefaultConstructor()) &&
- !hasNonLiteralTypeFieldsOrBases();
- }
-
- /// \brief If this record is an instantiation of a member class,
- /// retrieves the member class from which it was instantiated.
- ///
- /// This routine will return non-null for (non-templated) member
- /// classes of class templates. For example, given:
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// struct A { };
- /// };
- /// \endcode
- ///
- /// The declaration for X<int>::A is a (non-templated) CXXRecordDecl
- /// whose parent is the class template specialization X<int>. For
- /// this declaration, getInstantiatedFromMemberClass() will return
- /// the CXXRecordDecl X<T>::A. When a complete definition of
- /// X<int>::A is required, it will be instantiated from the
- /// declaration returned by getInstantiatedFromMemberClass().
- CXXRecordDecl *getInstantiatedFromMemberClass() const;
-
- /// \brief If this class is an instantiation of a member class of a
- /// class template specialization, retrieves the member specialization
- /// information.
- MemberSpecializationInfo *getMemberSpecializationInfo() const;
-
- /// \brief Specify that this record is an instantiation of the
- /// member class \p RD.
- void setInstantiationOfMemberClass(CXXRecordDecl *RD,
- TemplateSpecializationKind TSK);
-
- /// \brief Retrieves the class template that is described by this
- /// class declaration.
- ///
- /// Every class template is represented as a ClassTemplateDecl and a
- /// CXXRecordDecl. The former contains template properties (such as
- /// the template parameter lists) while the latter contains the
- /// actual description of the template's
- /// contents. ClassTemplateDecl::getTemplatedDecl() retrieves the
- /// CXXRecordDecl that from a ClassTemplateDecl, while
- /// getDescribedClassTemplate() retrieves the ClassTemplateDecl from
- /// a CXXRecordDecl.
- ClassTemplateDecl *getDescribedClassTemplate() const;
-
- void setDescribedClassTemplate(ClassTemplateDecl *Template);
-
- /// \brief Determine whether this particular class is a specialization or
- /// instantiation of a class template or member class of a class template,
- /// and how it was instantiated or specialized.
- TemplateSpecializationKind getTemplateSpecializationKind() const;
-
- /// \brief Set the kind of specialization or template instantiation this is.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
-
- /// \brief Retrieve the record declaration from which this record could be
- /// instantiated. Returns null if this class is not a template instantiation.
- const CXXRecordDecl *getTemplateInstantiationPattern() const;
-
- CXXRecordDecl *getTemplateInstantiationPattern() {
- return const_cast<CXXRecordDecl *>(const_cast<const CXXRecordDecl *>(this)
- ->getTemplateInstantiationPattern());
- }
-
- /// \brief Returns the destructor decl for this class.
- CXXDestructorDecl *getDestructor() const;
-
- /// \brief Returns true if the class destructor, or any implicitly invoked
- /// destructors are marked noreturn.
- bool isAnyDestructorNoReturn() const;
-
- /// \brief If the class is a local class [class.local], returns
- /// the enclosing function declaration.
- const FunctionDecl *isLocalClass() const {
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
- return RD->isLocalClass();
-
- return dyn_cast<FunctionDecl>(getDeclContext());
- }
-
- FunctionDecl *isLocalClass() {
- return const_cast<FunctionDecl*>(
- const_cast<const CXXRecordDecl*>(this)->isLocalClass());
- }
-
- /// \brief Determine whether this dependent class is a current instantiation,
- /// when viewed from within the given context.
- bool isCurrentInstantiation(const DeclContext *CurContext) const;
-
- /// \brief Determine whether this class is derived from the class \p Base.
- ///
- /// This routine only determines whether this class is derived from \p Base,
- /// but does not account for factors that may make a Derived -> Base class
- /// ill-formed, such as private/protected inheritance or multiple, ambiguous
- /// base class subobjects.
- ///
- /// \param Base the base class we are searching for.
- ///
- /// \returns true if this class is derived from Base, false otherwise.
- bool isDerivedFrom(const CXXRecordDecl *Base) const;
-
- /// \brief Determine whether this class is derived from the type \p Base.
- ///
- /// This routine only determines whether this class is derived from \p Base,
- /// but does not account for factors that may make a Derived -> Base class
- /// ill-formed, such as private/protected inheritance or multiple, ambiguous
- /// base class subobjects.
- ///
- /// \param Base the base class we are searching for.
- ///
- /// \param Paths will contain the paths taken from the current class to the
- /// given \p Base class.
- ///
- /// \returns true if this class is derived from \p Base, false otherwise.
- ///
- /// \todo add a separate parameter to configure IsDerivedFrom, rather than
- /// tangling input and output in \p Paths
- bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const;
-
- /// \brief Determine whether this class is virtually derived from
- /// the class \p Base.
- ///
- /// This routine only determines whether this class is virtually
- /// derived from \p Base, but does not account for factors that may
- /// make a Derived -> Base class ill-formed, such as
- /// private/protected inheritance or multiple, ambiguous base class
- /// subobjects.
- ///
- /// \param Base the base class we are searching for.
- ///
- /// \returns true if this class is virtually derived from Base,
- /// false otherwise.
- bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const;
-
- /// \brief Determine whether this class is provably not derived from
- /// the type \p Base.
- bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const;
-
- /// \brief Function type used by forallBases() as a callback.
- ///
- /// \param BaseDefinition the definition of the base class
- ///
- /// \returns true if this base matched the search criteria
- typedef llvm::function_ref<bool(const CXXRecordDecl *BaseDefinition)>
- ForallBasesCallback;
-
- /// \brief Determines if the given callback holds for all the direct
- /// or indirect base classes of this type.
- ///
- /// The class itself does not count as a base class. This routine
- /// returns false if the class has non-computable base classes.
- ///
- /// \param BaseMatches Callback invoked for each (direct or indirect) base
- /// class of this type, or if \p AllowShortCircuit is true then until a call
- /// returns false.
- ///
- /// \param AllowShortCircuit if false, forces the callback to be called
- /// for every base class, even if a dependent or non-matching base was
- /// found.
- bool forallBases(ForallBasesCallback BaseMatches,
- bool AllowShortCircuit = true) const;
-
- /// \brief Function type used by lookupInBases() to determine whether a
- /// specific base class subobject matches the lookup criteria.
- ///
- /// \param Specifier the base-class specifier that describes the inheritance
- /// from the base class we are trying to match.
- ///
- /// \param Path the current path, from the most-derived class down to the
- /// base named by the \p Specifier.
- ///
- /// \returns true if this base matched the search criteria, false otherwise.
- typedef llvm::function_ref<bool(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path)> BaseMatchesCallback;
-
- /// \brief Look for entities within the base classes of this C++ class,
- /// transitively searching all base class subobjects.
- ///
- /// This routine uses the callback function \p BaseMatches to find base
- /// classes meeting some search criteria, walking all base class subobjects
- /// and populating the given \p Paths structure with the paths through the
- /// inheritance hierarchy that resulted in a match. On a successful search,
- /// the \p Paths structure can be queried to retrieve the matching paths and
- /// to determine if there were any ambiguities.
- ///
- /// \param BaseMatches callback function used to determine whether a given
- /// base matches the user-defined search criteria.
- ///
- /// \param Paths used to record the paths from this class to its base class
- /// subobjects that match the search criteria.
- ///
- /// \returns true if there exists any path from this class to a base class
- /// subobject that matches the search criteria.
- bool lookupInBases(BaseMatchesCallback BaseMatches,
- CXXBasePaths &Paths) const;
-
- /// \brief Base-class lookup callback that determines whether the given
- /// base class specifier refers to a specific class declaration.
- ///
- /// This callback can be used with \c lookupInBases() to determine whether
- /// a given derived class has is a base class subobject of a particular type.
- /// The base record pointer should refer to the canonical CXXRecordDecl of the
- /// base class that we are searching for.
- static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path, const CXXRecordDecl *BaseRecord);
-
- /// \brief Base-class lookup callback that determines whether the
- /// given base class specifier refers to a specific class
- /// declaration and describes virtual derivation.
- ///
- /// This callback can be used with \c lookupInBases() to determine
- /// whether a given derived class has is a virtual base class
- /// subobject of a particular type. The base record pointer should
- /// refer to the canonical CXXRecordDecl of the base class that we
- /// are searching for.
- static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path,
- const CXXRecordDecl *BaseRecord);
-
- /// \brief Base-class lookup callback that determines whether there exists
- /// a tag with the given name.
- ///
- /// This callback can be used with \c lookupInBases() to find tag members
- /// of the given name within a C++ class hierarchy.
- static bool FindTagMember(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path, DeclarationName Name);
-
- /// \brief Base-class lookup callback that determines whether there exists
- /// a member with the given name.
- ///
- /// This callback can be used with \c lookupInBases() to find members
- /// of the given name within a C++ class hierarchy.
- static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path, DeclarationName Name);
-
- /// \brief Base-class lookup callback that determines whether there exists
- /// a member with the given name that can be used in a nested-name-specifier.
- ///
- /// This callback can be used with \c lookupInBases() to find members of
- /// the given name within a C++ class hierarchy that can occur within
- /// nested-name-specifiers.
- static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path,
- DeclarationName Name);
-
- /// \brief Retrieve the final overriders for each virtual member
- /// function in the class hierarchy where this class is the
- /// most-derived class in the class hierarchy.
- void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const;
-
- /// \brief Get the indirect primary bases for this class.
- void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
-
- /// Renders and displays an inheritance diagram
- /// for this C++ class and all of its base classes (transitively) using
- /// GraphViz.
- void viewInheritance(ASTContext& Context) const;
-
- /// \brief Calculates the access of a decl that is reached
- /// along a path.
- static AccessSpecifier MergeAccess(AccessSpecifier PathAccess,
- AccessSpecifier DeclAccess) {
- assert(DeclAccess != AS_none);
- if (DeclAccess == AS_private) return AS_none;
- return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
- }
-
- /// \brief Indicates that the declaration of a defaulted or deleted special
- /// member function is now complete.
- void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD);
-
- /// \brief Indicates that the definition of this class is now complete.
- void completeDefinition() override;
-
- /// \brief Indicates that the definition of this class is now complete,
- /// and provides a final overrider map to help determine
- ///
- /// \param FinalOverriders The final overrider map for this class, which can
- /// be provided as an optimization for abstract-class checking. If NULL,
- /// final overriders will be computed if they are needed to complete the
- /// definition.
- void completeDefinition(CXXFinalOverriderMap *FinalOverriders);
-
- /// \brief Determine whether this class may end up being abstract, even though
- /// it is not yet known to be abstract.
- ///
- /// \returns true if this class is not known to be abstract but has any
- /// base classes that are abstract. In this case, \c completeDefinition()
- /// will need to compute final overriders to determine whether the class is
- /// actually abstract.
- bool mayBeAbstract() const;
-
- /// \brief If this is the closure type of a lambda expression, retrieve the
- /// number to be used for name mangling in the Itanium C++ ABI.
- ///
- /// Zero indicates that this closure type has internal linkage, so the
- /// mangling number does not matter, while a non-zero value indicates which
- /// lambda expression this is in this particular context.
- unsigned getLambdaManglingNumber() const {
- assert(isLambda() && "Not a lambda closure type!");
- return getLambdaData().ManglingNumber;
- }
-
- /// \brief Retrieve the declaration that provides additional context for a
- /// lambda, when the normal declaration context is not specific enough.
- ///
- /// Certain contexts (default arguments of in-class function parameters and
- /// the initializers of data members) have separate name mangling rules for
- /// lambdas within the Itanium C++ ABI. For these cases, this routine provides
- /// the declaration in which the lambda occurs, e.g., the function parameter
- /// or the non-static data member. Otherwise, it returns NULL to imply that
- /// the declaration context suffices.
- Decl *getLambdaContextDecl() const {
- assert(isLambda() && "Not a lambda closure type!");
- return getLambdaData().ContextDecl;
- }
-
- /// \brief Set the mangling number and context declaration for a lambda
- /// class.
- void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl) {
- getLambdaData().ManglingNumber = ManglingNumber;
- getLambdaData().ContextDecl = ContextDecl;
- }
-
- /// \brief Returns the inheritance model used for this record.
- MSInheritanceAttr::Spelling getMSInheritanceModel() const;
- /// \brief Calculate what the inheritance model would be for this class.
- MSInheritanceAttr::Spelling calculateInheritanceModel() const;
-
- /// In the Microsoft C++ ABI, use zero for the field offset of a null data
- /// member pointer if we can guarantee that zero is not a valid field offset,
- /// or if the member pointer has multiple fields. Polymorphic classes have a
- /// vfptr at offset zero, so we can use zero for null. If there are multiple
- /// fields, we can use zero even if it is a valid field offset because
- /// null-ness testing will check the other fields.
- bool nullFieldOffsetIsZero() const {
- return !MSInheritanceAttr::hasOnlyOneField(/*IsMemberFunction=*/false,
- getMSInheritanceModel()) ||
- (hasDefinition() && isPolymorphic());
- }
-
- /// \brief Controls when vtordisps will be emitted if this record is used as a
- /// virtual base.
- MSVtorDispAttr::Mode getMSVtorDispMode() const;
-
- /// \brief Determine whether this lambda expression was known to be dependent
- /// at the time it was created, even if its context does not appear to be
- /// dependent.
- ///
- /// This flag is a workaround for an issue with parsing, where default
- /// arguments are parsed before their enclosing function declarations have
- /// been created. This means that any lambda expressions within those
- /// default arguments will have as their DeclContext the context enclosing
- /// the function declaration, which may be non-dependent even when the
- /// function declaration itself is dependent. This flag indicates when we
- /// know that the lambda is dependent despite that.
- bool isDependentLambda() const {
- return isLambda() && getLambdaData().Dependent;
- }
-
- TypeSourceInfo *getLambdaTypeInfo() const {
- return getLambdaData().MethodTyInfo;
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstCXXRecord && K <= lastCXXRecord;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend class ASTReader;
- friend class ASTWriter;
-};
-
-/// \brief Represents a static or instance method of a struct/union/class.
-///
-/// In the terminology of the C++ Standard, these are the (static and
-/// non-static) member functions, whether virtual or not.
-class CXXMethodDecl : public FunctionDecl {
- void anchor() override;
-protected:
- CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass SC, bool isInline,
- bool isConstexpr, SourceLocation EndLocation)
- : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo,
- SC, isInline, isConstexpr) {
- if (EndLocation.isValid())
- setRangeEnd(EndLocation);
- }
-
-public:
- static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass SC,
- bool isInline,
- bool isConstexpr,
- SourceLocation EndLocation);
-
- static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- bool isStatic() const;
- bool isInstance() const { return !isStatic(); }
-
- /// Returns true if the given operator is implicitly static in a record
- /// context.
- static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK) {
- // [class.free]p1:
- // Any allocation function for a class T is a static member
- // (even if not explicitly declared static).
- // [class.free]p6 Any deallocation function for a class X is a static member
- // (even if not explicitly declared static).
- return OOK == OO_New || OOK == OO_Array_New || OOK == OO_Delete ||
- OOK == OO_Array_Delete;
- }
-
- bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); }
- bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); }
-
- bool isVirtual() const {
- CXXMethodDecl *CD =
- cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
-
- // Member function is virtual if it is marked explicitly so, or if it is
- // declared in __interface -- then it is automatically pure virtual.
- if (CD->isVirtualAsWritten() || CD->isPure())
- return true;
-
- return (CD->begin_overridden_methods() != CD->end_overridden_methods());
- }
-
- /// \brief Determine whether this is a usual deallocation function
- /// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
- /// delete or delete[] operator with a particular signature.
- bool isUsualDeallocationFunction() const;
-
- /// \brief Determine whether this is a copy-assignment operator, regardless
- /// of whether it was declared implicitly or explicitly.
- bool isCopyAssignmentOperator() const;
-
- /// \brief Determine whether this is a move assignment operator.
- bool isMoveAssignmentOperator() const;
-
- CXXMethodDecl *getCanonicalDecl() override {
- return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
- }
- const CXXMethodDecl *getCanonicalDecl() const {
- return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
- }
-
- CXXMethodDecl *getMostRecentDecl() {
- return cast<CXXMethodDecl>(
- static_cast<FunctionDecl *>(this)->getMostRecentDecl());
- }
- const CXXMethodDecl *getMostRecentDecl() const {
- return const_cast<CXXMethodDecl*>(this)->getMostRecentDecl();
- }
-
- /// True if this method is user-declared and was not
- /// deleted or defaulted on its first declaration.
- bool isUserProvided() const {
- return !(isDeleted() || getCanonicalDecl()->isDefaulted());
- }
-
- ///
- void addOverriddenMethod(const CXXMethodDecl *MD);
-
- typedef const CXXMethodDecl *const* method_iterator;
-
- method_iterator begin_overridden_methods() const;
- method_iterator end_overridden_methods() const;
- unsigned size_overridden_methods() const;
-
- /// Returns the parent of this method declaration, which
- /// is the class in which this method is defined.
- const CXXRecordDecl *getParent() const {
- return cast<CXXRecordDecl>(FunctionDecl::getParent());
- }
-
- /// Returns the parent of this method declaration, which
- /// is the class in which this method is defined.
- CXXRecordDecl *getParent() {
- return const_cast<CXXRecordDecl *>(
- cast<CXXRecordDecl>(FunctionDecl::getParent()));
- }
-
- /// \brief Returns the type of the \c this pointer.
- ///
- /// Should only be called for instance (i.e., non-static) methods.
- QualType getThisType(ASTContext &C) const;
-
- unsigned getTypeQualifiers() const {
- return getType()->getAs<FunctionProtoType>()->getTypeQuals();
- }
-
- /// \brief Retrieve the ref-qualifier associated with this method.
- ///
- /// In the following example, \c f() has an lvalue ref-qualifier, \c g()
- /// has an rvalue ref-qualifier, and \c h() has no ref-qualifier.
- /// @code
- /// struct X {
- /// void f() &;
- /// void g() &&;
- /// void h();
- /// };
- /// @endcode
- RefQualifierKind getRefQualifier() const {
- return getType()->getAs<FunctionProtoType>()->getRefQualifier();
- }
-
- bool hasInlineBody() const;
-
- /// \brief Determine whether this is a lambda closure type's static member
- /// function that is used for the result of the lambda's conversion to
- /// function pointer (for a lambda with no captures).
- ///
- /// The function itself, if used, will have a placeholder body that will be
- /// supplied by IR generation to either forward to the function call operator
- /// or clone the function call operator.
- bool isLambdaStaticInvoker() const;
-
- /// \brief Find the method in \p RD that corresponds to this one.
- ///
- /// Find if \p RD or one of the classes it inherits from override this method.
- /// If so, return it. \p RD is assumed to be a subclass of the class defining
- /// this method (or be the class itself), unless \p MayBeBase is set to true.
- CXXMethodDecl *
- getCorrespondingMethodInClass(const CXXRecordDecl *RD,
- bool MayBeBase = false);
-
- const CXXMethodDecl *
- getCorrespondingMethodInClass(const CXXRecordDecl *RD,
- bool MayBeBase = false) const {
- return const_cast<CXXMethodDecl *>(this)
- ->getCorrespondingMethodInClass(RD, MayBeBase);
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstCXXMethod && K <= lastCXXMethod;
- }
-};
-
-/// \brief Represents a C++ base or member initializer.
-///
-/// This is part of a constructor initializer that
-/// initializes one non-static member variable or one base class. For
-/// example, in the following, both 'A(a)' and 'f(3.14159)' are member
-/// initializers:
-///
-/// \code
-/// class A { };
-/// class B : public A {
-/// float f;
-/// public:
-/// B(A& a) : A(a), f(3.14159) { }
-/// };
-/// \endcode
-class CXXCtorInitializer final
- : private llvm::TrailingObjects<CXXCtorInitializer, VarDecl *> {
- /// \brief Either the base class name/delegating constructor type (stored as
- /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
- /// (IndirectFieldDecl*) being initialized.
- llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
- Initializee;
-
- /// \brief The source location for the field name or, for a base initializer
- /// pack expansion, the location of the ellipsis.
- ///
- /// In the case of a delegating
- /// constructor, it will still include the type's source location as the
- /// Initializee points to the CXXConstructorDecl (to allow loop detection).
- SourceLocation MemberOrEllipsisLocation;
-
- /// \brief The argument used to initialize the base or member, which may
- /// end up constructing an object (when multiple arguments are involved).
- Stmt *Init;
-
- /// \brief Location of the left paren of the ctor-initializer.
- SourceLocation LParenLoc;
-
- /// \brief Location of the right paren of the ctor-initializer.
- SourceLocation RParenLoc;
-
- /// \brief If the initializee is a type, whether that type makes this
- /// a delegating initialization.
- bool IsDelegating : 1;
-
- /// \brief If the initializer is a base initializer, this keeps track
- /// of whether the base is virtual or not.
- bool IsVirtual : 1;
-
- /// \brief Whether or not the initializer is explicitly written
- /// in the sources.
- bool IsWritten : 1;
-
- /// If IsWritten is true, then this number keeps track of the textual order
- /// of this initializer in the original sources, counting from 0; otherwise,
- /// it stores the number of array index variables stored after this object
- /// in memory.
- unsigned SourceOrderOrNumArrayIndices : 13;
-
- CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
- SourceLocation MemberLoc, SourceLocation L, Expr *Init,
- SourceLocation R, VarDecl **Indices, unsigned NumIndices);
-
-public:
- /// \brief Creates a new base-class initializer.
- explicit
- CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual,
- SourceLocation L, Expr *Init, SourceLocation R,
- SourceLocation EllipsisLoc);
-
- /// \brief Creates a new member initializer.
- explicit
- CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
- SourceLocation MemberLoc, SourceLocation L, Expr *Init,
- SourceLocation R);
-
- /// \brief Creates a new anonymous field initializer.
- explicit
- CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
- SourceLocation MemberLoc, SourceLocation L, Expr *Init,
- SourceLocation R);
-
- /// \brief Creates a new delegating initializer.
- explicit
- CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
- SourceLocation L, Expr *Init, SourceLocation R);
-
- /// \brief Creates a new member initializer that optionally contains
- /// array indices used to describe an elementwise initialization.
- static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
- SourceLocation MemberLoc, SourceLocation L,
- Expr *Init, SourceLocation R,
- VarDecl **Indices, unsigned NumIndices);
-
- /// \brief Determine whether this initializer is initializing a base class.
- bool isBaseInitializer() const {
- return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
- }
-
- /// \brief Determine whether this initializer is initializing a non-static
- /// data member.
- bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); }
-
- bool isAnyMemberInitializer() const {
- return isMemberInitializer() || isIndirectMemberInitializer();
- }
-
- bool isIndirectMemberInitializer() const {
- return Initializee.is<IndirectFieldDecl*>();
- }
-
- /// \brief Determine whether this initializer is an implicit initializer
- /// generated for a field with an initializer defined on the member
- /// declaration.
- ///
- /// In-class member initializers (also known as "non-static data member
- /// initializations", NSDMIs) were introduced in C++11.
- bool isInClassMemberInitializer() const {
- return Init->getStmtClass() == Stmt::CXXDefaultInitExprClass;
- }
-
- /// \brief Determine whether this initializer is creating a delegating
- /// constructor.
- bool isDelegatingInitializer() const {
- return Initializee.is<TypeSourceInfo*>() && IsDelegating;
- }
-
- /// \brief Determine whether this initializer is a pack expansion.
- bool isPackExpansion() const {
- return isBaseInitializer() && MemberOrEllipsisLocation.isValid();
- }
-
- // \brief For a pack expansion, returns the location of the ellipsis.
- SourceLocation getEllipsisLoc() const {
- assert(isPackExpansion() && "Initializer is not a pack expansion");
- return MemberOrEllipsisLocation;
- }
-
- /// If this is a base class initializer, returns the type of the
- /// base class with location information. Otherwise, returns an NULL
- /// type location.
- TypeLoc getBaseClassLoc() const;
-
- /// If this is a base class initializer, returns the type of the base class.
- /// Otherwise, returns null.
- const Type *getBaseClass() const;
-
- /// Returns whether the base is virtual or not.
- bool isBaseVirtual() const {
- assert(isBaseInitializer() && "Must call this on base initializer!");
-
- return IsVirtual;
- }
-
- /// \brief Returns the declarator information for a base class or delegating
- /// initializer.
- TypeSourceInfo *getTypeSourceInfo() const {
- return Initializee.dyn_cast<TypeSourceInfo *>();
- }
-
- /// \brief If this is a member initializer, returns the declaration of the
- /// non-static data member being initialized. Otherwise, returns null.
- FieldDecl *getMember() const {
- if (isMemberInitializer())
- return Initializee.get<FieldDecl*>();
- return nullptr;
- }
- FieldDecl *getAnyMember() const {
- if (isMemberInitializer())
- return Initializee.get<FieldDecl*>();
- if (isIndirectMemberInitializer())
- return Initializee.get<IndirectFieldDecl*>()->getAnonField();
- return nullptr;
- }
-
- IndirectFieldDecl *getIndirectMember() const {
- if (isIndirectMemberInitializer())
- return Initializee.get<IndirectFieldDecl*>();
- return nullptr;
- }
-
- SourceLocation getMemberLocation() const {
- return MemberOrEllipsisLocation;
- }
-
- /// \brief Determine the source location of the initializer.
- SourceLocation getSourceLocation() const;
-
- /// \brief Determine the source range covering the entire initializer.
- SourceRange getSourceRange() const LLVM_READONLY;
-
- /// \brief Determine whether this initializer is explicitly written
- /// in the source code.
- bool isWritten() const { return IsWritten; }
-
- /// \brief Return the source position of the initializer, counting from 0.
- /// If the initializer was implicit, -1 is returned.
- int getSourceOrder() const {
- return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
- }
-
- /// \brief Set the source order of this initializer.
- ///
- /// This can only be called once for each initializer; it cannot be called
- /// on an initializer having a positive number of (implicit) array indices.
- ///
- /// This assumes that the initializer was written in the source code, and
- /// ensures that isWritten() returns true.
- void setSourceOrder(int pos) {
- assert(!IsWritten &&
- "calling twice setSourceOrder() on the same initializer");
- assert(SourceOrderOrNumArrayIndices == 0 &&
- "setSourceOrder() used when there are implicit array indices");
- assert(pos >= 0 &&
- "setSourceOrder() used to make an initializer implicit");
- IsWritten = true;
- SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
- }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- /// \brief Determine the number of implicit array indices used while
- /// described an array member initialization.
- unsigned getNumArrayIndices() const {
- return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
- }
-
- /// \brief Retrieve a particular array index variable used to
- /// describe an array member initialization.
- VarDecl *getArrayIndex(unsigned I) {
- assert(I < getNumArrayIndices() && "Out of bounds member array index");
- return getTrailingObjects<VarDecl *>()[I];
- }
- const VarDecl *getArrayIndex(unsigned I) const {
- assert(I < getNumArrayIndices() && "Out of bounds member array index");
- return getTrailingObjects<VarDecl *>()[I];
- }
- void setArrayIndex(unsigned I, VarDecl *Index) {
- assert(I < getNumArrayIndices() && "Out of bounds member array index");
- getTrailingObjects<VarDecl *>()[I] = Index;
- }
- ArrayRef<VarDecl *> getArrayIndexes() {
- assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
- return llvm::makeArrayRef(getTrailingObjects<VarDecl *>(),
- getNumArrayIndices());
- }
-
- /// \brief Get the initializer.
- Expr *getInit() const { return static_cast<Expr*>(Init); }
-
- friend TrailingObjects;
-};
-
-/// \brief Represents a C++ constructor within a class.
-///
-/// For example:
-///
-/// \code
-/// class X {
-/// public:
-/// explicit X(int); // represented by a CXXConstructorDecl.
-/// };
-/// \endcode
-class CXXConstructorDecl : public CXXMethodDecl {
- void anchor() override;
- /// \brief Whether this constructor declaration has the \c explicit keyword
- /// specified.
- bool IsExplicitSpecified : 1;
-
- /// \name Support for base and member initializers.
- /// \{
- /// \brief The arguments used to initialize the base or member.
- LazyCXXCtorInitializersPtr CtorInitializers;
- unsigned NumCtorInitializers;
- /// \}
-
- CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isExplicitSpecified, bool isInline,
- bool isImplicitlyDeclared, bool isConstexpr)
- : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, isConstexpr, SourceLocation()),
- IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr),
- NumCtorInitializers(0) {
- setImplicit(isImplicitlyDeclared);
- }
-
-public:
- static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isExplicit,
- bool isInline, bool isImplicitlyDeclared,
- bool isConstexpr);
-
- /// \brief Determine whether this constructor declaration has the
- /// \c explicit keyword specified.
- bool isExplicitSpecified() const { return IsExplicitSpecified; }
-
- /// \brief Determine whether this constructor was marked "explicit" or not.
- bool isExplicit() const {
- return cast<CXXConstructorDecl>(getFirstDecl())->isExplicitSpecified();
- }
-
- /// \brief Iterates through the member/base initializer list.
- typedef CXXCtorInitializer **init_iterator;
-
- /// \brief Iterates through the member/base initializer list.
- typedef CXXCtorInitializer *const *init_const_iterator;
-
- typedef llvm::iterator_range<init_iterator> init_range;
- typedef llvm::iterator_range<init_const_iterator> init_const_range;
-
- init_range inits() { return init_range(init_begin(), init_end()); }
- init_const_range inits() const {
- return init_const_range(init_begin(), init_end());
- }
-
- /// \brief Retrieve an iterator to the first initializer.
- init_iterator init_begin() {
- const auto *ConstThis = this;
- return const_cast<init_iterator>(ConstThis->init_begin());
- }
- /// \brief Retrieve an iterator to the first initializer.
- init_const_iterator init_begin() const;
-
- /// \brief Retrieve an iterator past the last initializer.
- init_iterator init_end() {
- return init_begin() + NumCtorInitializers;
- }
- /// \brief Retrieve an iterator past the last initializer.
- init_const_iterator init_end() const {
- return init_begin() + NumCtorInitializers;
- }
-
- typedef std::reverse_iterator<init_iterator> init_reverse_iterator;
- typedef std::reverse_iterator<init_const_iterator>
- init_const_reverse_iterator;
-
- init_reverse_iterator init_rbegin() {
- return init_reverse_iterator(init_end());
- }
- init_const_reverse_iterator init_rbegin() const {
- return init_const_reverse_iterator(init_end());
- }
-
- init_reverse_iterator init_rend() {
- return init_reverse_iterator(init_begin());
- }
- init_const_reverse_iterator init_rend() const {
- return init_const_reverse_iterator(init_begin());
- }
-
- /// \brief Determine the number of arguments used to initialize the member
- /// or base.
- unsigned getNumCtorInitializers() const {
- return NumCtorInitializers;
- }
-
- void setNumCtorInitializers(unsigned numCtorInitializers) {
- NumCtorInitializers = numCtorInitializers;
- }
-
- void setCtorInitializers(CXXCtorInitializer **Initializers) {
- CtorInitializers = Initializers;
- }
-
- /// \brief Determine whether this constructor is a delegating constructor.
- bool isDelegatingConstructor() const {
- return (getNumCtorInitializers() == 1) &&
- init_begin()[0]->isDelegatingInitializer();
- }
-
- /// \brief When this constructor delegates to another, retrieve the target.
- CXXConstructorDecl *getTargetConstructor() const;
-
- /// Whether this constructor is a default
- /// constructor (C++ [class.ctor]p5), which can be used to
- /// default-initialize a class of this type.
- bool isDefaultConstructor() const;
-
- /// \brief Whether this constructor is a copy constructor (C++ [class.copy]p2,
- /// which can be used to copy the class.
- ///
- /// \p TypeQuals will be set to the qualifiers on the
- /// argument type. For example, \p TypeQuals would be set to \c
- /// Qualifiers::Const for the following copy constructor:
- ///
- /// \code
- /// class X {
- /// public:
- /// X(const X&);
- /// };
- /// \endcode
- bool isCopyConstructor(unsigned &TypeQuals) const;
-
- /// Whether this constructor is a copy
- /// constructor (C++ [class.copy]p2, which can be used to copy the
- /// class.
- bool isCopyConstructor() const {
- unsigned TypeQuals = 0;
- return isCopyConstructor(TypeQuals);
- }
-
- /// \brief Determine whether this constructor is a move constructor
- /// (C++11 [class.copy]p3), which can be used to move values of the class.
- ///
- /// \param TypeQuals If this constructor is a move constructor, will be set
- /// to the type qualifiers on the referent of the first parameter's type.
- bool isMoveConstructor(unsigned &TypeQuals) const;
-
- /// \brief Determine whether this constructor is a move constructor
- /// (C++11 [class.copy]p3), which can be used to move values of the class.
- bool isMoveConstructor() const {
- unsigned TypeQuals = 0;
- return isMoveConstructor(TypeQuals);
- }
-
- /// \brief Determine whether this is a copy or move constructor.
- ///
- /// \param TypeQuals Will be set to the type qualifiers on the reference
- /// parameter, if in fact this is a copy or move constructor.
- bool isCopyOrMoveConstructor(unsigned &TypeQuals) const;
-
- /// \brief Determine whether this a copy or move constructor.
- bool isCopyOrMoveConstructor() const {
- unsigned Quals;
- return isCopyOrMoveConstructor(Quals);
- }
-
- /// Whether this constructor is a
- /// converting constructor (C++ [class.conv.ctor]), which can be
- /// used for user-defined conversions.
- bool isConvertingConstructor(bool AllowExplicit) const;
-
- /// \brief Determine whether this is a member template specialization that
- /// would copy the object to itself. Such constructors are never used to copy
- /// an object.
- bool isSpecializationCopyingObject() const;
-
- /// \brief Get the constructor that this inheriting constructor is based on.
- const CXXConstructorDecl *getInheritedConstructor() const;
-
- /// \brief Set the constructor that this inheriting constructor is based on.
- void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
-
- CXXConstructorDecl *getCanonicalDecl() override {
- return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
- }
- const CXXConstructorDecl *getCanonicalDecl() const {
- return const_cast<CXXConstructorDecl*>(this)->getCanonicalDecl();
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == CXXConstructor; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a C++ destructor within a class.
-///
-/// For example:
-///
-/// \code
-/// class X {
-/// public:
-/// ~X(); // represented by a CXXDestructorDecl.
-/// };
-/// \endcode
-class CXXDestructorDecl : public CXXMethodDecl {
- void anchor() override;
-
- FunctionDecl *OperatorDelete;
-
- CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
- OperatorDelete(nullptr) {
- setImplicit(isImplicitlyDeclared);
- }
-
-public:
- static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo* TInfo,
- bool isInline,
- bool isImplicitlyDeclared);
- static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
-
- void setOperatorDelete(FunctionDecl *OD);
- const FunctionDecl *getOperatorDelete() const {
- return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == CXXDestructor; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a C++ conversion function within a class.
-///
-/// For example:
-///
-/// \code
-/// class X {
-/// public:
-/// operator bool();
-/// };
-/// \endcode
-class CXXConversionDecl : public CXXMethodDecl {
- void anchor() override;
- /// Whether this conversion function declaration is marked
- /// "explicit", meaning that it can only be applied when the user
- /// explicitly wrote a cast. This is a C++11 feature.
- bool IsExplicitSpecified : 1;
-
- CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicitSpecified,
- bool isConstexpr, SourceLocation EndLocation)
- : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, isConstexpr, EndLocation),
- IsExplicitSpecified(isExplicitSpecified) { }
-
-public:
- static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicit,
- bool isConstexpr,
- SourceLocation EndLocation);
- static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// Whether this conversion function declaration is marked
- /// "explicit", meaning that it can only be used for direct initialization
- /// (including explitly written casts). This is a C++11 feature.
- bool isExplicitSpecified() const { return IsExplicitSpecified; }
-
- /// \brief Whether this is an explicit conversion operator (C++11 and later).
- ///
- /// Explicit conversion operators are only considered for direct
- /// initialization, e.g., when the user has explicitly written a cast.
- bool isExplicit() const {
- return cast<CXXConversionDecl>(getFirstDecl())->isExplicitSpecified();
- }
-
- /// \brief Returns the type that this conversion function is converting to.
- QualType getConversionType() const {
- return getType()->getAs<FunctionType>()->getReturnType();
- }
-
- /// \brief Determine whether this conversion function is a conversion from
- /// a lambda closure type to a block pointer.
- bool isLambdaToBlockPointerConversion() const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == CXXConversion; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a linkage specification.
-///
-/// For example:
-/// \code
-/// extern "C" void foo();
-/// \endcode
-class LinkageSpecDecl : public Decl, public DeclContext {
- virtual void anchor();
-public:
- /// \brief Represents the language in a linkage specification.
- ///
- /// The values are part of the serialization ABI for
- /// ASTs and cannot be changed without altering that ABI. To help
- /// 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
- };
-private:
- /// \brief The language for this linkage specification.
- unsigned Language : 3;
- /// \brief True if this linkage spec has braces.
- ///
- /// This is needed so that hasBraces() returns the correct result while the
- /// linkage spec body is being parsed. Once RBraceLoc has been set this is
- /// not used, so it doesn't need to be serialized.
- unsigned HasBraces : 1;
- /// \brief The source location for the extern keyword.
- SourceLocation ExternLoc;
- /// \brief The source location for the right brace (if valid).
- SourceLocation RBraceLoc;
-
- LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs lang, bool HasBraces)
- : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
- Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc),
- RBraceLoc(SourceLocation()) { }
-
-public:
- static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs Lang,
- bool HasBraces);
- static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief Return the language specified by this linkage specification.
- LanguageIDs getLanguage() const { return LanguageIDs(Language); }
- /// \brief Set the language specified by this linkage specification.
- void setLanguage(LanguageIDs L) { Language = L; }
-
- /// \brief Determines whether this linkage specification had braces in
- /// its syntactic form.
- bool hasBraces() const {
- assert(!RBraceLoc.isValid() || HasBraces);
- return HasBraces;
- }
-
- SourceLocation getExternLoc() const { return ExternLoc; }
- SourceLocation getRBraceLoc() const { return RBraceLoc; }
- void setExternLoc(SourceLocation L) { ExternLoc = L; }
- void setRBraceLoc(SourceLocation L) {
- RBraceLoc = L;
- HasBraces = RBraceLoc.isValid();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasBraces())
- return getRBraceLoc();
- // No braces: get the end location of the (only) declaration in context
- // (if present).
- return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(ExternLoc, getLocEnd());
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == LinkageSpec; }
- static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
- return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
- }
- static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// \brief Represents C++ using-directive.
-///
-/// For example:
-/// \code
-/// using namespace std;
-/// \endcode
-///
-/// \note UsingDirectiveDecl should be Decl not NamedDecl, but we provide
-/// artificial names for all using-directives in order to store
-/// them in DeclContext effectively.
-class UsingDirectiveDecl : public NamedDecl {
- void anchor() override;
- /// \brief The location of the \c using keyword.
- SourceLocation UsingLoc;
-
- /// \brief The location of the \c namespace keyword.
- SourceLocation NamespaceLoc;
-
- /// \brief The nested-name-specifier that precedes the namespace.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The namespace nominated by this using-directive.
- NamedDecl *NominatedNamespace;
-
- /// Enclosing context containing both using-directive and nominated
- /// namespace.
- DeclContext *CommonAncestor;
-
- /// \brief Returns special DeclarationName used by using-directives.
- ///
- /// This is only used by DeclContext for storing UsingDirectiveDecls in
- /// its lookup structure.
- static DeclarationName getName() {
- return DeclarationName::getUsingDirectiveName();
- }
-
- UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc,
- SourceLocation NamespcLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Nominated,
- DeclContext *CommonAncestor)
- : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc),
- NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc),
- NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { }
-
-public:
- /// \brief Retrieve the nested-name-specifier that qualifies the
- /// name of the namespace, with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the
- /// name of the namespace.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
- const NamedDecl *getNominatedNamespaceAsWritten() const {
- return NominatedNamespace;
- }
-
- /// \brief Returns the namespace nominated by this using-directive.
- NamespaceDecl *getNominatedNamespace();
-
- const NamespaceDecl *getNominatedNamespace() const {
- return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
- }
-
- /// \brief Returns the common ancestor context of this using-directive and
- /// its nominated namespace.
- DeclContext *getCommonAncestor() { return CommonAncestor; }
- const DeclContext *getCommonAncestor() const { return CommonAncestor; }
-
- /// \brief Return the location of the \c using keyword.
- SourceLocation getUsingLoc() const { return UsingLoc; }
-
- // FIXME: Could omit 'Key' in name.
- /// \brief Returns the location of the \c namespace keyword.
- SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
-
- /// \brief Returns the location of this using declaration's identifier.
- SourceLocation getIdentLocation() const { return getLocation(); }
-
- static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingLoc,
- SourceLocation NamespaceLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Nominated,
- DeclContext *CommonAncestor);
- static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(UsingLoc, getLocation());
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == UsingDirective; }
-
- // Friend for getUsingDirectiveName.
- friend class DeclContext;
-
- friend class ASTDeclReader;
-};
-
-/// \brief Represents a C++ namespace alias.
-///
-/// For example:
-///
-/// \code
-/// namespace Foo = Bar;
-/// \endcode
-class NamespaceAliasDecl : public NamedDecl,
- public Redeclarable<NamespaceAliasDecl> {
- void anchor() override;
-
- /// \brief The location of the \c namespace keyword.
- SourceLocation NamespaceLoc;
-
- /// \brief The location of the namespace's identifier.
- ///
- /// This is accessed by TargetNameLoc.
- SourceLocation IdentLoc;
-
- /// \brief The nested-name-specifier that precedes the namespace.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The Decl that this alias points to, either a NamespaceDecl or
- /// a NamespaceAliasDecl.
- NamedDecl *Namespace;
-
- NamespaceAliasDecl(ASTContext &C, DeclContext *DC,
- SourceLocation NamespaceLoc, SourceLocation AliasLoc,
- IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc, NamedDecl *Namespace)
- : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias), redeclarable_base(C),
- NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
- QualifierLoc(QualifierLoc), Namespace(Namespace) {}
-
- typedef Redeclarable<NamespaceAliasDecl> redeclarable_base;
- NamespaceAliasDecl *getNextRedeclarationImpl() override;
- NamespaceAliasDecl *getPreviousDeclImpl() override;
- NamespaceAliasDecl *getMostRecentDeclImpl() override;
-
- friend class ASTDeclReader;
-
-public:
- static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation NamespaceLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Namespace);
-
- static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
-
- NamespaceAliasDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const NamespaceAliasDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the
- /// name of the namespace, with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the
- /// name of the namespace.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Retrieve the namespace declaration aliased by this directive.
- NamespaceDecl *getNamespace() {
- if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
- return AD->getNamespace();
-
- return cast<NamespaceDecl>(Namespace);
- }
-
- const NamespaceDecl *getNamespace() const {
- return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
- }
-
- /// Returns the location of the alias name, i.e. 'foo' in
- /// "namespace foo = ns::bar;".
- SourceLocation getAliasLoc() const { return getLocation(); }
-
- /// Returns the location of the \c namespace keyword.
- SourceLocation getNamespaceLoc() const { return NamespaceLoc; }
-
- /// Returns the location of the identifier in the named namespace.
- SourceLocation getTargetNameLoc() const { return IdentLoc; }
-
- /// \brief Retrieve the namespace that this alias refers to, which
- /// may either be a NamespaceDecl or a NamespaceAliasDecl.
- NamedDecl *getAliasedNamespace() const { return Namespace; }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(NamespaceLoc, IdentLoc);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == NamespaceAlias; }
-};
-
-/// \brief Represents a shadow declaration introduced into a scope by a
-/// (resolved) using declaration.
-///
-/// For example,
-/// \code
-/// namespace A {
-/// void foo();
-/// }
-/// namespace B {
-/// using A::foo; // <- a UsingDecl
-/// // Also creates a UsingShadowDecl for A::foo() in B
-/// }
-/// \endcode
-class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
- void anchor() override;
-
- /// The referenced declaration.
- NamedDecl *Underlying;
-
- /// \brief The using declaration which introduced this decl or the next using
- /// shadow declaration contained in the aforementioned using declaration.
- NamedDecl *UsingOrNextShadow;
- friend class UsingDecl;
-
- UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
- UsingDecl *Using, NamedDecl *Target)
- : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
- redeclarable_base(C), Underlying(Target),
- UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
- if (Target) {
- setDeclName(Target->getDeclName());
- IdentifierNamespace = Target->getIdentifierNamespace();
- }
- setImplicit();
- }
-
- typedef Redeclarable<UsingShadowDecl> redeclarable_base;
- UsingShadowDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- UsingShadowDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- UsingShadowDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation Loc, UsingDecl *Using,
- NamedDecl *Target) {
- return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
- }
-
- static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
-
- UsingShadowDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const UsingShadowDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- /// \brief Gets the underlying declaration which has been brought into the
- /// local scope.
- NamedDecl *getTargetDecl() const { return Underlying; }
-
- /// \brief Sets the underlying declaration which has been brought into the
- /// local scope.
- void setTargetDecl(NamedDecl* ND) {
- assert(ND && "Target decl is null!");
- Underlying = ND;
- IdentifierNamespace = ND->getIdentifierNamespace();
- }
-
- /// \brief Gets the using declaration to which this declaration is tied.
- UsingDecl *getUsingDecl() const;
-
- /// \brief The next using shadow declaration contained in the shadow decl
- /// chain of the using declaration which introduced this decl.
- UsingShadowDecl *getNextUsingShadowDecl() const {
- return dyn_cast_or_null<UsingShadowDecl>(UsingOrNextShadow);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a C++ using-declaration.
-///
-/// For example:
-/// \code
-/// using someNameSpace::someIdentifier;
-/// \endcode
-class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> {
- void anchor() override;
-
- /// \brief The source location of the 'using' keyword itself.
- SourceLocation UsingLocation;
-
- /// \brief The nested-name-specifier that precedes the name.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief Provides source/type location info for the declaration name
- /// embedded in the ValueDecl base class.
- DeclarationNameLoc DNLoc;
-
- /// \brief The first shadow declaration of the shadow decl chain associated
- /// with this using declaration.
- ///
- /// The bool member of the pair store whether this decl has the \c typename
- /// keyword.
- llvm::PointerIntPair<UsingShadowDecl *, 1, bool> FirstUsingShadow;
-
- UsingDecl(DeclContext *DC, SourceLocation UL,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)
- : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
- UsingLocation(UL), QualifierLoc(QualifierLoc),
- DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) {
- }
-
-public:
- /// \brief Return the source location of the 'using' keyword.
- SourceLocation getUsingLoc() const { return UsingLocation; }
-
- /// \brief Set the source location of the 'using' keyword.
- void setUsingLoc(SourceLocation L) { UsingLocation = L; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the name,
- /// with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the name.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
- }
-
- /// \brief Return true if it is a C++03 access declaration (no 'using').
- bool isAccessDeclaration() const { return UsingLocation.isInvalid(); }
-
- /// \brief Return true if the using declaration has 'typename'.
- bool hasTypename() const { return FirstUsingShadow.getInt(); }
-
- /// \brief Sets whether the using declaration has 'typename'.
- void setTypename(bool TN) { FirstUsingShadow.setInt(TN); }
-
- /// \brief Iterates through the using shadow declarations associated with
- /// this using declaration.
- class shadow_iterator {
- /// \brief The current using shadow declaration.
- UsingShadowDecl *Current;
-
- public:
- typedef UsingShadowDecl* value_type;
- typedef UsingShadowDecl* reference;
- typedef UsingShadowDecl* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- shadow_iterator() : Current(nullptr) { }
- explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
-
- reference operator*() const { return Current; }
- pointer operator->() const { return Current; }
-
- shadow_iterator& operator++() {
- Current = Current->getNextUsingShadowDecl();
- return *this;
- }
-
- shadow_iterator operator++(int) {
- shadow_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(shadow_iterator x, shadow_iterator y) {
- return x.Current == y.Current;
- }
- friend bool operator!=(shadow_iterator x, shadow_iterator y) {
- return x.Current != y.Current;
- }
- };
-
- typedef llvm::iterator_range<shadow_iterator> shadow_range;
-
- shadow_range shadows() const {
- return shadow_range(shadow_begin(), shadow_end());
- }
- shadow_iterator shadow_begin() const {
- return shadow_iterator(FirstUsingShadow.getPointer());
- }
- shadow_iterator shadow_end() const { return shadow_iterator(); }
-
- /// \brief Return the number of shadowed declarations associated with this
- /// using declaration.
- unsigned shadow_size() const {
- return std::distance(shadow_begin(), shadow_end());
- }
-
- void addShadowDecl(UsingShadowDecl *S);
- void removeShadowDecl(UsingShadowDecl *S);
-
- static UsingDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingL,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo,
- bool HasTypenameKeyword);
-
- static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Retrieves the canonical declaration of this declaration.
- UsingDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const UsingDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Using; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a dependent using declaration which was not marked with
-/// \c typename.
-///
-/// Unlike non-dependent using declarations, these *only* bring through
-/// non-types; otherwise they would break two-phase lookup.
-///
-/// \code
-/// template \<class T> class A : public Base<T> {
-/// using Base<T>::foo;
-/// };
-/// \endcode
-class UnresolvedUsingValueDecl : public ValueDecl,
- public Mergeable<UnresolvedUsingValueDecl> {
- void anchor() override;
-
- /// \brief The source location of the 'using' keyword
- SourceLocation UsingLocation;
-
- /// \brief The nested-name-specifier that precedes the name.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief Provides source/type location info for the declaration name
- /// embedded in the ValueDecl base class.
- DeclarationNameLoc DNLoc;
-
- UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
- SourceLocation UsingLoc,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo)
- : ValueDecl(UnresolvedUsingValue, DC,
- NameInfo.getLoc(), NameInfo.getName(), Ty),
- UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
- DNLoc(NameInfo.getInfo())
- { }
-
-public:
- /// \brief Returns the source location of the 'using' keyword.
- SourceLocation getUsingLoc() const { return UsingLocation; }
-
- /// \brief Set the source location of the 'using' keyword.
- void setUsingLoc(SourceLocation L) { UsingLocation = L; }
-
- /// \brief Return true if it is a C++03 access declaration (no 'using').
- bool isAccessDeclaration() const { return UsingLocation.isInvalid(); }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the name,
- /// with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the name.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
- }
-
- static UnresolvedUsingValueDecl *
- Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo);
-
- static UnresolvedUsingValueDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Retrieves the canonical declaration of this declaration.
- UnresolvedUsingValueDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const UnresolvedUsingValueDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Represents a dependent using declaration which was marked with
-/// \c typename.
-///
-/// \code
-/// template \<class T> class A : public Base<T> {
-/// using typename Base<T>::foo;
-/// };
-/// \endcode
-///
-/// The type associated with an unresolved using typename decl is
-/// currently always a typename type.
-class UnresolvedUsingTypenameDecl
- : public TypeDecl,
- public Mergeable<UnresolvedUsingTypenameDecl> {
- void anchor() override;
-
- /// \brief The source location of the 'typename' keyword
- SourceLocation TypenameLocation;
-
- /// \brief The nested-name-specifier that precedes the name.
- NestedNameSpecifierLoc QualifierLoc;
-
- UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
- SourceLocation TypenameLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TargetNameLoc,
- IdentifierInfo *TargetName)
- : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
- UsingLoc),
- TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
-
- friend class ASTDeclReader;
-
-public:
- /// \brief Returns the source location of the 'using' keyword.
- SourceLocation getUsingLoc() const { return getLocStart(); }
-
- /// \brief Returns the source location of the 'typename' keyword.
- SourceLocation getTypenameLoc() const { return TypenameLocation; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the name,
- /// with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the name.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- static UnresolvedUsingTypenameDecl *
- Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
- SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TargetNameLoc, DeclarationName TargetName);
-
- static UnresolvedUsingTypenameDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// Retrieves the canonical declaration of this declaration.
- UnresolvedUsingTypenameDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const UnresolvedUsingTypenameDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
-};
-
-/// \brief Represents a C++11 static_assert declaration.
-class StaticAssertDecl : public Decl {
- virtual void anchor();
- llvm::PointerIntPair<Expr *, 1, bool> AssertExprAndFailed;
- StringLiteral *Message;
- SourceLocation RParenLoc;
-
- StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
- Expr *AssertExpr, StringLiteral *Message,
- SourceLocation RParenLoc, bool Failed)
- : Decl(StaticAssert, DC, StaticAssertLoc),
- AssertExprAndFailed(AssertExpr, Failed), Message(Message),
- RParenLoc(RParenLoc) { }
-
-public:
- static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StaticAssertLoc,
- Expr *AssertExpr, StringLiteral *Message,
- SourceLocation RParenLoc, bool Failed);
- static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); }
- const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); }
-
- StringLiteral *getMessage() { return Message; }
- const StringLiteral *getMessage() const { return Message; }
-
- bool isFailed() const { return AssertExprAndFailed.getInt(); }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getLocation(), getRParenLoc());
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == StaticAssert; }
-
- friend class ASTDeclReader;
-};
-
-/// An instance of this class represents the declaration of a property
-/// member. This is a Microsoft extension to C++, first introduced in
-/// Visual Studio .NET 2003 as a parallel to similar features in C#
-/// and Managed C++.
-///
-/// A property must always be a non-static class member.
-///
-/// A property member superficially resembles a non-static data
-/// member, except preceded by a property attribute:
-/// __declspec(property(get=GetX, put=PutX)) int x;
-/// Either (but not both) of the 'get' and 'put' names may be omitted.
-///
-/// A reference to a property is always an lvalue. If the lvalue
-/// undergoes lvalue-to-rvalue conversion, then a getter name is
-/// required, and that member is called with no arguments.
-/// If the lvalue is assigned into, then a setter name is required,
-/// and that member is called with one argument, the value assigned.
-/// Both operations are potentially overloaded. Compound assignments
-/// are permitted, as are the increment and decrement operators.
-///
-/// The getter and putter methods are permitted to be overloaded,
-/// although their return and parameter types are subject to certain
-/// restrictions according to the type of the property.
-///
-/// A property declared using an incomplete array type may
-/// additionally be subscripted, adding extra parameters to the getter
-/// and putter methods.
-class MSPropertyDecl : public DeclaratorDecl {
- IdentifierInfo *GetterId, *SetterId;
-
- MSPropertyDecl(DeclContext *DC, SourceLocation L, DeclarationName N,
- QualType T, TypeSourceInfo *TInfo, SourceLocation StartL,
- IdentifierInfo *Getter, IdentifierInfo *Setter)
- : DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
- GetterId(Getter), SetterId(Setter) {}
-
-public:
- static MSPropertyDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, DeclarationName N, QualType T,
- TypeSourceInfo *TInfo, SourceLocation StartL,
- IdentifierInfo *Getter, IdentifierInfo *Setter);
- static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
-
- bool hasGetter() const { return GetterId != nullptr; }
- IdentifierInfo* getGetterId() const { return GetterId; }
- bool hasSetter() const { return SetterId != nullptr; }
- IdentifierInfo* getSetterId() const { return SetterId; }
-
- friend class ASTDeclReader;
-};
-
-/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
-/// into a diagnostic with <<.
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- AccessSpecifier AS);
-
-const PartialDiagnostic &operator<<(const PartialDiagnostic &DB,
- AccessSpecifier AS);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
deleted file mode 100644
index ff37758..0000000
--- a/include/clang/AST/DeclContextInternals.h
+++ /dev/null
@@ -1,264 +0,0 @@
-//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the data structures used in the implementation
-// of DeclContext.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
-#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclarationName.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/SmallVector.h"
-#include <algorithm>
-
-namespace clang {
-
-class DependentDiagnostic;
-
-/// \brief An array of decls optimized for the common case of only containing
-/// one entry.
-struct StoredDeclsList {
-
- /// \brief When in vector form, this is what the Data pointer points to.
- typedef SmallVector<NamedDecl *, 4> DeclsTy;
-
- /// \brief A collection of declarations, with a flag to indicate if we have
- /// further external declarations.
- typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy;
-
- /// \brief The stored data, which will be either a pointer to a NamedDecl,
- /// or a pointer to a vector with a flag to indicate if there are further
- /// external declarations.
- llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data;
-
-public:
- StoredDeclsList() {}
-
- StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
- RHS.Data = (NamedDecl *)nullptr;
- }
-
- ~StoredDeclsList() {
- // If this is a vector-form, free the vector.
- if (DeclsTy *Vector = getAsVector())
- delete Vector;
- }
-
- StoredDeclsList &operator=(StoredDeclsList &&RHS) {
- if (DeclsTy *Vector = getAsVector())
- delete Vector;
- Data = RHS.Data;
- RHS.Data = (NamedDecl *)nullptr;
- return *this;
- }
-
- bool isNull() const { return Data.isNull(); }
-
- NamedDecl *getAsDecl() const {
- return Data.dyn_cast<NamedDecl *>();
- }
-
- DeclsAndHasExternalTy getAsVectorAndHasExternal() const {
- return Data.dyn_cast<DeclsAndHasExternalTy>();
- }
-
- DeclsTy *getAsVector() const {
- return getAsVectorAndHasExternal().getPointer();
- }
-
- bool hasExternalDecls() const {
- return getAsVectorAndHasExternal().getInt();
- }
-
- void setHasExternalDecls() {
- if (DeclsTy *Vec = getAsVector())
- Data = DeclsAndHasExternalTy(Vec, true);
- else {
- DeclsTy *VT = new DeclsTy();
- if (NamedDecl *OldD = getAsDecl())
- VT->push_back(OldD);
- Data = DeclsAndHasExternalTy(VT, true);
- }
- }
-
- void setOnlyValue(NamedDecl *ND) {
- assert(!getAsVector() && "Not inline");
- Data = ND;
- // Make sure that Data is a plain NamedDecl* so we can use its address
- // at getLookupResult.
- assert(*(NamedDecl **)&Data == ND &&
- "PointerUnion mangles the NamedDecl pointer!");
- }
-
- void remove(NamedDecl *D) {
- assert(!isNull() && "removing from empty list");
- if (NamedDecl *Singleton = getAsDecl()) {
- assert(Singleton == D && "list is different singleton");
- (void)Singleton;
- Data = (NamedDecl *)nullptr;
- return;
- }
-
- DeclsTy &Vec = *getAsVector();
- DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
- assert(I != Vec.end() && "list does not contain decl");
- Vec.erase(I);
-
- assert(std::find(Vec.begin(), Vec.end(), D)
- == Vec.end() && "list still contains decl");
- }
-
- /// \brief Remove any declarations which were imported from an external
- /// AST source.
- void removeExternalDecls() {
- if (isNull()) {
- // Nothing to do.
- } else if (NamedDecl *Singleton = getAsDecl()) {
- if (Singleton->isFromASTFile())
- *this = StoredDeclsList();
- } else {
- DeclsTy &Vec = *getAsVector();
- Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
- std::mem_fun(&Decl::isFromASTFile)),
- Vec.end());
- // Don't have any external decls any more.
- Data = DeclsAndHasExternalTy(&Vec, false);
- }
- }
-
- /// getLookupResult - Return an array of all the decls that this list
- /// represents.
- DeclContext::lookup_result getLookupResult() {
- if (isNull())
- return DeclContext::lookup_result();
-
- // If we have a single NamedDecl, return it.
- if (NamedDecl *ND = getAsDecl()) {
- assert(!isNull() && "Empty list isn't allowed");
-
- // Data is a raw pointer to a NamedDecl*, return it.
- return DeclContext::lookup_result(ND);
- }
-
- assert(getAsVector() && "Must have a vector at this point");
- DeclsTy &Vector = *getAsVector();
-
- // Otherwise, we have a range result.
- return DeclContext::lookup_result(Vector);
- }
-
- /// HandleRedeclaration - If this is a redeclaration of an existing decl,
- /// replace the old one with D and return true. Otherwise return false.
- bool HandleRedeclaration(NamedDecl *D, bool IsKnownNewer) {
- // Most decls only have one entry in their list, special case it.
- if (NamedDecl *OldD = getAsDecl()) {
- if (!D->declarationReplaces(OldD, IsKnownNewer))
- return false;
- setOnlyValue(D);
- return true;
- }
-
- // Determine if this declaration is actually a redeclaration.
- DeclsTy &Vec = *getAsVector();
- for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
- OD != ODEnd; ++OD) {
- NamedDecl *OldD = *OD;
- if (D->declarationReplaces(OldD, IsKnownNewer)) {
- *OD = D;
- return true;
- }
- }
-
- return false;
- }
-
- /// AddSubsequentDecl - This is called on the second and later decl when it is
- /// not a redeclaration to merge it into the appropriate place in our list.
- ///
- void AddSubsequentDecl(NamedDecl *D) {
- assert(!isNull() && "don't AddSubsequentDecl when we have no decls");
-
- // If this is the second decl added to the list, convert this to vector
- // form.
- if (NamedDecl *OldD = getAsDecl()) {
- DeclsTy *VT = new DeclsTy();
- VT->push_back(OldD);
- Data = DeclsAndHasExternalTy(VT, false);
- }
-
- DeclsTy &Vec = *getAsVector();
-
- // Using directives end up in a special entry which contains only
- // other using directives, so all this logic is wasted for them.
- // But avoiding the logic wastes time in the far-more-common case
- // that we're *not* adding a new using directive.
-
- // Tag declarations always go at the end of the list so that an
- // iterator which points at the first tag will start a span of
- // decls that only contains tags.
- if (D->hasTagIdentifierNamespace())
- Vec.push_back(D);
-
- // Resolved using declarations go at the front of the list so that
- // they won't show up in other lookup results. Unresolved using
- // declarations (which are always in IDNS_Using | IDNS_Ordinary)
- // follow that so that the using declarations will be contiguous.
- else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
- DeclsTy::iterator I = Vec.begin();
- if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
- while (I != Vec.end() &&
- (*I)->getIdentifierNamespace() == Decl::IDNS_Using)
- ++I;
- }
- Vec.insert(I, D);
-
- // All other declarations go at the end of the list, but before any
- // tag declarations. But we can be clever about tag declarations
- // because there can only ever be one in a scope.
- } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) {
- NamedDecl *TagD = Vec.back();
- Vec.back() = D;
- Vec.push_back(TagD);
- } else
- Vec.push_back(D);
- }
-};
-
-class StoredDeclsMap
- : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
-
-public:
- static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
-
-private:
- friend class ASTContext; // walks the chain deleting these
- friend class DeclContext;
- llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
-};
-
-class DependentStoredDeclsMap : public StoredDeclsMap {
-public:
- DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {}
-
-private:
- friend class DependentDiagnostic;
- friend class DeclContext; // iterates over diagnostics
-
- DependentDiagnostic *FirstDiagnostic;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
deleted file mode 100644
index 27b0388..0000000
--- a/include/clang/AST/DeclFriend.h
+++ /dev/null
@@ -1,243 +0,0 @@
-//===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the section of the AST representing C++ friend
-// declarations.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLFRIEND_H
-#define LLVM_CLANG_AST_DECLFRIEND_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/TypeLoc.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-/// FriendDecl - Represents the declaration of a friend entity,
-/// which can be a function, a type, or a templated function or type.
-// For example:
-///
-/// @code
-/// template <typename T> class A {
-/// friend int foo(T);
-/// friend class B;
-/// friend T; // only in C++0x
-/// template <typename U> friend class C;
-/// template <typename U> friend A& operator+=(A&, const U&) { ... }
-/// };
-/// @endcode
-///
-/// The semantic context of a friend decl is its declaring class.
-class FriendDecl final
- : public Decl,
- private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> {
- virtual void anchor();
-public:
- typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
-
-private:
- // The declaration that's a friend of this class.
- FriendUnion Friend;
-
- // A pointer to the next friend in the sequence.
- LazyDeclPtr NextFriend;
-
- // Location of the 'friend' specifier.
- SourceLocation FriendLoc;
-
- /// True if this 'friend' declaration is unsupported. Eventually we
- /// will support every possible friend declaration, but for now we
- /// silently ignore some and set this flag to authorize all access.
- bool UnsupportedFriend : 1;
-
- // The number of "outer" template parameter lists in non-templatic
- // (currently unsupported) friend type declarations, such as
- // template <class T> friend class A<T>::B;
- unsigned NumTPLists : 31;
-
- friend class CXXRecordDecl::friend_iterator;
- friend class CXXRecordDecl;
-
- FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
- SourceLocation FriendL,
- ArrayRef<TemplateParameterList*> FriendTypeTPLists)
- : Decl(Decl::Friend, DC, L),
- Friend(Friend),
- NextFriend(),
- FriendLoc(FriendL),
- UnsupportedFriend(false),
- NumTPLists(FriendTypeTPLists.size()) {
- for (unsigned i = 0; i < NumTPLists; ++i)
- getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i];
- }
-
- FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
- : Decl(Decl::Friend, Empty), NextFriend(),
- NumTPLists(NumFriendTypeTPLists) { }
-
- FriendDecl *getNextFriend() {
- if (!NextFriend.isOffset())
- return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
- return getNextFriendSlowCase();
- }
- FriendDecl *getNextFriendSlowCase();
-
-public:
- static FriendDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, FriendUnion Friend_,
- SourceLocation FriendL,
- ArrayRef<TemplateParameterList*> FriendTypeTPLists
- = None);
- static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID,
- unsigned FriendTypeNumTPLists);
-
- /// If this friend declaration names an (untemplated but possibly
- /// dependent) type, return the type; otherwise return null. This
- /// is used for elaborated-type-specifiers and, in C++0x, for
- /// arbitrary friend type declarations.
- TypeSourceInfo *getFriendType() const {
- return Friend.dyn_cast<TypeSourceInfo*>();
- }
- unsigned getFriendTypeNumTemplateParameterLists() const {
- return NumTPLists;
- }
- TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
- assert(N < NumTPLists);
- return getTrailingObjects<TemplateParameterList *>()[N];
- }
-
- /// If this friend declaration doesn't name a type, return the inner
- /// declaration.
- NamedDecl *getFriendDecl() const {
- return Friend.dyn_cast<NamedDecl*>();
- }
-
- /// Retrieves the location of the 'friend' keyword.
- SourceLocation getFriendLoc() const {
- return FriendLoc;
- }
-
- /// Retrieves the source range for the friend declaration.
- SourceRange getSourceRange() const override LLVM_READONLY {
- if (NamedDecl *ND = getFriendDecl()) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
- return FD->getSourceRange();
- if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
- return FTD->getSourceRange();
- if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
- return CTD->getSourceRange();
- if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
- if (DD->getOuterLocStart() != DD->getInnerLocStart())
- return DD->getSourceRange();
- }
- return SourceRange(getFriendLoc(), ND->getLocEnd());
- }
- else if (TypeSourceInfo *TInfo = getFriendType()) {
- SourceLocation StartL =
- (NumTPLists == 0) ? getFriendLoc()
- : getTrailingObjects<TemplateParameterList *>()[0]
- ->getTemplateLoc();
- return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc());
- }
- else
- return SourceRange(getFriendLoc(), getLocation());
- }
-
- /// Determines if this friend kind is unsupported.
- bool isUnsupportedFriend() const {
- return UnsupportedFriend;
- }
- void setUnsupportedFriend(bool Unsupported) {
- UnsupportedFriend = Unsupported;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Decl::Friend; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
-};
-
-/// An iterator over the friend declarations of a class.
-class CXXRecordDecl::friend_iterator {
- FriendDecl *Ptr;
-
- friend class CXXRecordDecl;
- explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {}
-public:
- friend_iterator() {}
-
- typedef FriendDecl *value_type;
- typedef FriendDecl *reference;
- typedef FriendDecl *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- reference operator*() const { return Ptr; }
-
- friend_iterator &operator++() {
- assert(Ptr && "attempt to increment past end of friend list");
- Ptr = Ptr->getNextFriend();
- return *this;
- }
-
- friend_iterator operator++(int) {
- friend_iterator tmp = *this;
- ++*this;
- return tmp;
- }
-
- bool operator==(const friend_iterator &Other) const {
- return Ptr == Other.Ptr;
- }
-
- bool operator!=(const friend_iterator &Other) const {
- return Ptr != Other.Ptr;
- }
-
- friend_iterator &operator+=(difference_type N) {
- assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator");
- while (N--)
- ++*this;
- return *this;
- }
-
- friend_iterator operator+(difference_type N) const {
- friend_iterator tmp = *this;
- tmp += N;
- return tmp;
- }
-};
-
-inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const {
- return friend_iterator(getFirstFriend());
-}
-
-inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
- return friend_iterator(nullptr);
-}
-
-inline CXXRecordDecl::friend_range CXXRecordDecl::friends() const {
- return friend_range(friend_begin(), friend_end());
-}
-
-inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
- assert(!FD->NextFriend && "friend already has next friend?");
- FD->NextFriend = data().FirstFriend;
- data().FirstFriend = FD;
-}
-
-}
-
-#endif
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
deleted file mode 100644
index c84bb5e..0000000
--- a/include/clang/AST/DeclGroup.h
+++ /dev/null
@@ -1,154 +0,0 @@
-//===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLGROUP_H
-#define LLVM_CLANG_AST_DECLGROUP_H
-
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/TrailingObjects.h"
-#include <cassert>
-
-namespace clang {
-
-class ASTContext;
-class Decl;
-class DeclGroup;
-class DeclGroupIterator;
-
-class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> {
- // FIXME: Include a TypeSpecifier object.
- unsigned NumDecls;
-
-private:
- DeclGroup() : NumDecls(0) {}
- DeclGroup(unsigned numdecls, Decl** decls);
-
-public:
- static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
-
- unsigned size() const { return NumDecls; }
-
- Decl*& operator[](unsigned i) {
- assert (i < NumDecls && "Out-of-bounds access.");
- return getTrailingObjects<Decl *>()[i];
- }
-
- Decl* const& operator[](unsigned i) const {
- assert (i < NumDecls && "Out-of-bounds access.");
- return getTrailingObjects<Decl *>()[i];
- }
-
- friend TrailingObjects;
-};
-
-class DeclGroupRef {
- // Note this is not a PointerIntPair because we need the address of the
- // non-group case to be valid as a Decl** for iteration.
- enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
- Decl* D;
-
- Kind getKind() const {
- return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
- }
-
-public:
- DeclGroupRef() : D(nullptr) {}
-
- explicit DeclGroupRef(Decl* d) : D(d) {}
- explicit DeclGroupRef(DeclGroup* dg)
- : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
-
- static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
- if (NumDecls == 0)
- return DeclGroupRef();
- if (NumDecls == 1)
- return DeclGroupRef(Decls[0]);
- return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
- }
-
- typedef Decl** iterator;
- typedef Decl* const * const_iterator;
-
- bool isNull() const { return D == nullptr; }
- bool isSingleDecl() const { return getKind() == SingleDeclKind; }
- bool isDeclGroup() const { return getKind() == DeclGroupKind; }
-
- Decl *getSingleDecl() {
- assert(isSingleDecl() && "Isn't a declgroup");
- return D;
- }
- const Decl *getSingleDecl() const {
- return const_cast<DeclGroupRef*>(this)->getSingleDecl();
- }
-
- DeclGroup &getDeclGroup() {
- assert(isDeclGroup() && "Isn't a declgroup");
- return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask));
- }
- const DeclGroup &getDeclGroup() const {
- return const_cast<DeclGroupRef*>(this)->getDeclGroup();
- }
-
- iterator begin() {
- if (isSingleDecl())
- return D ? &D : nullptr;
- return &getDeclGroup()[0];
- }
-
- iterator end() {
- if (isSingleDecl())
- return D ? &D+1 : nullptr;
- DeclGroup &G = getDeclGroup();
- return &G[0] + G.size();
- }
-
- const_iterator begin() const {
- if (isSingleDecl())
- return D ? &D : nullptr;
- return &getDeclGroup()[0];
- }
-
- const_iterator end() const {
- if (isSingleDecl())
- return D ? &D+1 : nullptr;
- const DeclGroup &G = getDeclGroup();
- return &G[0] + G.size();
- }
-
- void *getAsOpaquePtr() const { return D; }
- static DeclGroupRef getFromOpaquePtr(void *Ptr) {
- DeclGroupRef X;
- X.D = static_cast<Decl*>(Ptr);
- return X;
- }
-};
-
-} // end clang namespace
-
-namespace llvm {
- // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
- template <typename T>
- class PointerLikeTypeTraits;
- template <>
- class PointerLikeTypeTraits<clang::DeclGroupRef> {
- public:
- static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
- return P.getAsOpaquePtr();
- }
- static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
- return clang::DeclGroupRef::getFromOpaquePtr(P);
- }
- enum { NumLowBitsAvailable = 0 };
- };
-}
-#endif
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
deleted file mode 100644
index eba2266..0000000
--- a/include/clang/AST/DeclLookups.h
+++ /dev/null
@@ -1,115 +0,0 @@
-//===-- DeclLookups.h - Low-level interface to all names in a DC-*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines DeclContext::all_lookups_iterator.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLLOOKUPS_H
-#define LLVM_CLANG_AST_DECLLOOKUPS_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclContextInternals.h"
-#include "clang/AST/DeclarationName.h"
-
-namespace clang {
-
-/// all_lookups_iterator - An iterator that provides a view over the results
-/// of looking up every possible name.
-class DeclContext::all_lookups_iterator {
- StoredDeclsMap::iterator It, End;
-public:
- typedef lookup_result value_type;
- typedef lookup_result reference;
- typedef lookup_result pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- all_lookups_iterator() {}
- all_lookups_iterator(StoredDeclsMap::iterator It,
- StoredDeclsMap::iterator End)
- : It(It), End(End) {}
-
- DeclarationName getLookupName() const { return It->first; }
-
- reference operator*() const { return It->second.getLookupResult(); }
- pointer operator->() const { return It->second.getLookupResult(); }
-
- all_lookups_iterator& operator++() {
- // Filter out using directives. They don't belong as results from name
- // lookup anyways, except as an implementation detail. Users of the API
- // should not expect to get them (or worse, rely on it).
- do {
- ++It;
- } while (It != End &&
- It->first == DeclarationName::getUsingDirectiveName());
-
- return *this;
- }
-
- all_lookups_iterator operator++(int) {
- all_lookups_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
- return x.It == y.It;
- }
- friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
- return x.It != y.It;
- }
-};
-
-inline DeclContext::lookups_range DeclContext::lookups() const {
- DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (Primary->hasExternalVisibleStorage())
- getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
- if (StoredDeclsMap *Map = Primary->buildLookup())
- return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
- all_lookups_iterator(Map->end(), Map->end()));
-
- // Synthesize an empty range. This requires that two default constructed
- // versions of these iterators form a valid empty range.
- return lookups_range(all_lookups_iterator(), all_lookups_iterator());
-}
-
-inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
- return lookups().begin();
-}
-
-inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
- return lookups().end();
-}
-
-inline DeclContext::lookups_range DeclContext::noload_lookups() const {
- DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (StoredDeclsMap *Map = Primary->getLookupPtr())
- return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
- all_lookups_iterator(Map->end(), Map->end()));
-
- // Synthesize an empty range. This requires that two default constructed
- // versions of these iterators form a valid empty range.
- return lookups_range(all_lookups_iterator(), all_lookups_iterator());
-}
-
-inline
-DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const {
- return noload_lookups().begin();
-}
-
-inline
-DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
- return noload_lookups().end();
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
deleted file mode 100644
index f46078f..0000000
--- a/include/clang/AST/DeclObjC.h
+++ /dev/null
@@ -1,2742 +0,0 @@
-//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the DeclObjC interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLOBJC_H
-#define LLVM_CLANG_AST_DECLOBJC_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/SelectorLocationsKind.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-class Expr;
-class Stmt;
-class FunctionDecl;
-class RecordDecl;
-class ObjCIvarDecl;
-class ObjCMethodDecl;
-class ObjCProtocolDecl;
-class ObjCCategoryDecl;
-class ObjCPropertyDecl;
-class ObjCPropertyImplDecl;
-class CXXCtorInitializer;
-
-class ObjCListBase {
- ObjCListBase(const ObjCListBase &) = delete;
- void operator=(const ObjCListBase &) = delete;
-protected:
- /// List is an array of pointers to objects that are not owned by this object.
- void **List;
- unsigned NumElts;
-
-public:
- ObjCListBase() : List(nullptr), NumElts(0) {}
- unsigned size() const { return NumElts; }
- bool empty() const { return NumElts == 0; }
-
-protected:
- void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
-};
-
-
-/// ObjCList - This is a simple template class used to hold various lists of
-/// decls etc, which is heavily used by the ObjC front-end. This only use case
-/// this supports is setting the list all at once and then reading elements out
-/// of it.
-template <typename T>
-class ObjCList : public ObjCListBase {
-public:
- void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
- ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
- }
-
- typedef T* const * iterator;
- iterator begin() const { return (iterator)List; }
- iterator end() const { return (iterator)List+NumElts; }
-
- T* operator[](unsigned Idx) const {
- assert(Idx < NumElts && "Invalid access");
- return (T*)List[Idx];
- }
-};
-
-/// \brief A list of Objective-C protocols, along with the source
-/// locations at which they were referenced.
-class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
- SourceLocation *Locations;
-
- using ObjCList<ObjCProtocolDecl>::set;
-
-public:
- ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { }
-
- typedef const SourceLocation *loc_iterator;
- loc_iterator loc_begin() const { return Locations; }
- loc_iterator loc_end() const { return Locations + size(); }
-
- void set(ObjCProtocolDecl* const* InList, unsigned Elts,
- const SourceLocation *Locs, ASTContext &Ctx);
-};
-
-
-/// ObjCMethodDecl - Represents an instance or class method declaration.
-/// ObjC methods can be declared within 4 contexts: class interfaces,
-/// categories, protocols, and class implementations. While C++ member
-/// functions leverage C syntax, Objective-C method syntax is modeled after
-/// Smalltalk (using colons to specify argument types/expressions).
-/// Here are some brief examples:
-///
-/// Setter/getter instance methods:
-/// - (void)setMenu:(NSMenu *)menu;
-/// - (NSMenu *)menu;
-///
-/// Instance method that takes 2 NSView arguments:
-/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
-///
-/// Getter class method:
-/// + (NSMenu *)defaultMenu;
-///
-/// A selector represents a unique name for a method. The selector names for
-/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
-///
-class ObjCMethodDecl : public NamedDecl, public DeclContext {
-public:
- enum ImplementationControl { None, Required, Optional };
-private:
- // The conventional meaning of this method; an ObjCMethodFamily.
- // This is not serialized; instead, it is computed on demand and
- // cached.
- mutable unsigned Family : ObjCMethodFamilyBitWidth;
-
- /// instance (true) or class (false) method.
- unsigned IsInstance : 1;
- unsigned IsVariadic : 1;
-
- /// True if this method is the getter or setter for an explicit property.
- unsigned IsPropertyAccessor : 1;
-
- // Method has a definition.
- unsigned IsDefined : 1;
-
- /// \brief Method redeclaration in the same interface.
- unsigned IsRedeclaration : 1;
-
- /// \brief Is redeclared in the same interface.
- mutable unsigned HasRedeclaration : 1;
-
- // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
- /// \@required/\@optional
- unsigned DeclImplementation : 2;
-
- // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
- /// in, inout, etc.
- unsigned objcDeclQualifier : 7;
-
- /// \brief Indicates whether this method has a related result type.
- unsigned RelatedResultType : 1;
-
- /// \brief Whether the locations of the selector identifiers are in a
- /// "standard" position, a enum SelectorLocationsKind.
- unsigned SelLocsKind : 2;
-
- /// \brief Whether this method overrides any other in the class hierarchy.
- ///
- /// A method is said to override any method in the class's
- /// base classes, its protocols, or its categories' protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- unsigned IsOverriding : 1;
-
- /// \brief Indicates if the method was a definition but its body was skipped.
- unsigned HasSkippedBody : 1;
-
- // Return type of this method.
- QualType MethodDeclType;
-
- // Type source information for the return type.
- TypeSourceInfo *ReturnTInfo;
-
- /// \brief Array of ParmVarDecls for the formal parameters of this method
- /// and optionally followed by selector locations.
- void *ParamsAndSelLocs;
- unsigned NumParams;
-
- /// List of attributes for this method declaration.
- SourceLocation DeclEndLoc; // the location of the ';' or '{'.
-
- // The following are only used for method definitions, null otherwise.
- LazyDeclStmtPtr Body;
-
- /// SelfDecl - Decl for the implicit self parameter. This is lazily
- /// constructed by createImplicitParams.
- ImplicitParamDecl *SelfDecl;
- /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
- /// constructed by createImplicitParams.
- ImplicitParamDecl *CmdDecl;
-
- SelectorLocationsKind getSelLocsKind() const {
- return (SelectorLocationsKind)SelLocsKind;
- }
- bool hasStandardSelLocs() const {
- return getSelLocsKind() != SelLoc_NonStandard;
- }
-
- /// \brief Get a pointer to the stored selector identifiers locations array.
- /// No locations will be stored if HasStandardSelLocs is true.
- SourceLocation *getStoredSelLocs() {
- return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
- }
- const SourceLocation *getStoredSelLocs() const {
- return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
- }
-
- /// \brief Get a pointer to the stored selector identifiers locations array.
- /// No locations will be stored if HasStandardSelLocs is true.
- ParmVarDecl **getParams() {
- return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
- }
- const ParmVarDecl *const *getParams() const {
- return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
- }
-
- /// \brief Get the number of stored selector identifiers locations.
- /// No locations will be stored if HasStandardSelLocs is true.
- unsigned getNumStoredSelLocs() const {
- if (hasStandardSelLocs())
- return 0;
- return getNumSelectorLocs();
- }
-
- void setParamsAndSelLocs(ASTContext &C,
- ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs);
-
- ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
- DeclContext *contextDecl, bool isInstance = true,
- bool isVariadic = false, bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false)
- : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
- DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
- IsInstance(isInstance), IsVariadic(isVariadic),
- IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
- IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
- objcDeclQualifier(OBJC_TQ_None),
- RelatedResultType(HasRelatedResultType),
- SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
- MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(nullptr),
- NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr),
- CmdDecl(nullptr) {
- setImplicit(isImplicitlyDeclared);
- }
-
- /// \brief A definition will return its interface declaration.
- /// An interface declaration will return its definition.
- /// Otherwise it will return itself.
- ObjCMethodDecl *getNextRedeclarationImpl() override;
-
-public:
- static ObjCMethodDecl *
- Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
- DeclContext *contextDecl, bool isInstance = true,
- bool isVariadic = false, bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false);
-
- static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ObjCMethodDecl *getCanonicalDecl() override;
- const ObjCMethodDecl *getCanonicalDecl() const {
- return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
- }
-
- ObjCDeclQualifier getObjCDeclQualifier() const {
- return ObjCDeclQualifier(objcDeclQualifier);
- }
- void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
-
- /// \brief Determine whether this method has a result type that is related
- /// to the message receiver's type.
- bool hasRelatedResultType() const { return RelatedResultType; }
-
- /// \brief Note whether this method has a related result type.
- void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
-
- /// \brief True if this is a method redeclaration in the same interface.
- bool isRedeclaration() const { return IsRedeclaration; }
- void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
-
- /// \brief Returns the location where the declarator ends. It will be
- /// the location of ';' for a method declaration and the location of '{'
- /// for a method definition.
- SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
-
- // Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY;
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(getLocation(), getLocEnd());
- }
-
- SourceLocation getSelectorStartLoc() const {
- if (isImplicit())
- return getLocStart();
- return getSelectorLoc(0);
- }
- SourceLocation getSelectorLoc(unsigned Index) const {
- assert(Index < getNumSelectorLocs() && "Index out of range!");
- if (hasStandardSelLocs())
- return getStandardSelectorLoc(Index, getSelector(),
- getSelLocsKind() == SelLoc_StandardWithSpace,
- parameters(),
- DeclEndLoc);
- return getStoredSelLocs()[Index];
- }
-
- void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
-
- unsigned getNumSelectorLocs() const {
- if (isImplicit())
- return 0;
- Selector Sel = getSelector();
- if (Sel.isUnarySelector())
- return 1;
- return Sel.getNumArgs();
- }
-
- ObjCInterfaceDecl *getClassInterface();
- const ObjCInterfaceDecl *getClassInterface() const {
- return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
- }
-
- Selector getSelector() const { return getDeclName().getObjCSelector(); }
-
- QualType getReturnType() const { return MethodDeclType; }
- void setReturnType(QualType T) { MethodDeclType = T; }
- SourceRange getReturnTypeSourceRange() const;
-
- /// \brief Determine the type of an expression that sends a message to this
- /// function. This replaces the type parameters with the types they would
- /// get if the receiver was parameterless (e.g. it may replace the type
- /// parameter with 'id').
- QualType getSendResultType() const;
-
- /// Determine the type of an expression that sends a message to this
- /// function with the given receiver type.
- QualType getSendResultType(QualType receiverType) const;
-
- TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; }
- void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; }
-
- // Iterator access to formal parameters.
- unsigned param_size() const { return NumParams; }
- typedef const ParmVarDecl *const *param_const_iterator;
- typedef ParmVarDecl *const *param_iterator;
- typedef llvm::iterator_range<param_iterator> param_range;
- typedef llvm::iterator_range<param_const_iterator> param_const_range;
-
- param_range params() { return param_range(param_begin(), param_end()); }
- param_const_range params() const {
- return param_const_range(param_begin(), param_end());
- }
-
- param_const_iterator param_begin() const {
- return param_const_iterator(getParams());
- }
- param_const_iterator param_end() const {
- return param_const_iterator(getParams() + NumParams);
- }
- param_iterator param_begin() { return param_iterator(getParams()); }
- param_iterator param_end() { return param_iterator(getParams() + NumParams); }
-
- // This method returns and of the parameters which are part of the selector
- // name mangling requirements.
- param_const_iterator sel_param_end() const {
- return param_begin() + getSelector().getNumArgs();
- }
-
- // ArrayRef access to formal parameters. This should eventually
- // replace the iterator interface above.
- ArrayRef<ParmVarDecl*> parameters() const {
- return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
- NumParams);
- }
-
- /// \brief Sets the method's parameters and selector source locations.
- /// If the method is implicit (not coming from source) \p SelLocs is
- /// ignored.
- void setMethodParams(ASTContext &C,
- ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs = llvm::None);
-
- // Iterator access to parameter types.
- typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
- typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
- param_type_iterator;
-
- param_type_iterator param_type_begin() const {
- return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
- }
- param_type_iterator param_type_end() const {
- return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
- }
-
- /// createImplicitParams - Used to lazily create the self and cmd
- /// implict parameters. This must be called prior to using getSelfDecl()
- /// or getCmdDecl(). The call is ignored if the implicit paramters
- /// have already been created.
- void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
-
- /// \return the type for \c self and set \arg selfIsPseudoStrong and
- /// \arg selfIsConsumed accordingly.
- QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID,
- bool &selfIsPseudoStrong, bool &selfIsConsumed);
-
- ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
- void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
- ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
- void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
-
- /// Determines the family of this method.
- ObjCMethodFamily getMethodFamily() const;
-
- bool isInstanceMethod() const { return IsInstance; }
- void setInstanceMethod(bool isInst) { IsInstance = isInst; }
- bool isVariadic() const { return IsVariadic; }
- void setVariadic(bool isVar) { IsVariadic = isVar; }
-
- bool isClassMethod() const { return !IsInstance; }
-
- bool isPropertyAccessor() const { return IsPropertyAccessor; }
- void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
-
- bool isDefined() const { return IsDefined; }
- void setDefined(bool isDefined) { IsDefined = isDefined; }
-
- /// \brief Whether this method overrides any other in the class hierarchy.
- ///
- /// A method is said to override any method in the class's
- /// base classes, its protocols, or its categories' protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- bool isOverriding() const { return IsOverriding; }
- void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
-
- /// \brief Return overridden methods for the given \p Method.
- ///
- /// An ObjC method is considered to override any method in the class's
- /// base classes (and base's categories), its protocols, or its categories'
- /// protocols, that has
- /// the same selector and is of the same kind (class or instance).
- /// A method in an implementation is not considered as overriding the same
- /// method in the interface or its categories.
- void getOverriddenMethods(
- SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
-
- /// \brief True if the method was a definition but its body was skipped.
- bool hasSkippedBody() const { return HasSkippedBody; }
- void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
-
- /// \brief Returns the property associated with this method's selector.
- ///
- /// Note that even if this particular method is not marked as a property
- /// accessor, it is still possible for it to match a property declared in a
- /// superclass. Pass \c false if you only want to check the current class.
- const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
-
- // Related to protocols declared in \@protocol
- void setDeclImplementation(ImplementationControl ic) {
- DeclImplementation = ic;
- }
- ImplementationControl getImplementationControl() const {
- return ImplementationControl(DeclImplementation);
- }
-
- /// Returns true if this specific method declaration is marked with the
- /// designated initializer attribute.
- bool isThisDeclarationADesignatedInitializer() const;
-
- /// Returns true if the method selector resolves to a designated initializer
- /// in the class's interface.
- ///
- /// \param InitMethod if non-null and the function returns true, it receives
- /// the method declaration that was marked with the designated initializer
- /// attribute.
- bool isDesignatedInitializerForTheInterface(
- const ObjCMethodDecl **InitMethod = nullptr) const;
-
- /// \brief Determine whether this method has a body.
- bool hasBody() const override { return Body.isValid(); }
-
- /// \brief Retrieve the body of this method, if it has one.
- Stmt *getBody() const override;
-
- void setLazyBody(uint64_t Offset) { Body = Offset; }
-
- CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
- void setBody(Stmt *B) { Body = B; }
-
- /// \brief Returns whether this specific method is a definition.
- bool isThisDeclarationADefinition() const { return hasBody(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCMethod; }
- static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
- return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
- }
- static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Describes the variance of a given generic parameter.
-enum class ObjCTypeParamVariance : uint8_t {
- /// The parameter is invariant: must match exactly.
- Invariant,
- /// The parameter is covariant, e.g., X<T> is a subtype of X<U> when
- /// the type parameter is covariant and T is a subtype of U.
- Covariant,
- /// The parameter is contravariant, e.g., X<T> is a subtype of X<U>
- /// when the type parameter is covariant and U is a subtype of T.
- Contravariant,
-};
-
-/// Represents the declaration of an Objective-C type parameter.
-///
-/// \code
-/// @interface NSDictionary<Key : id<NSCopying>, Value>
-/// @end
-/// \endcode
-///
-/// In the example above, both \c Key and \c Value are represented by
-/// \c ObjCTypeParamDecl. \c Key has an explicit bound of \c id<NSCopying>,
-/// while \c Value gets an implicit bound of \c id.
-///
-/// Objective-C type parameters are typedef-names in the grammar,
-class ObjCTypeParamDecl : public TypedefNameDecl {
- void anchor() override;
-
- /// Index of this type parameter in the type parameter list.
- unsigned Index : 14;
-
- /// The variance of the type parameter.
- unsigned Variance : 2;
-
- /// The location of the variance, if any.
- SourceLocation VarianceLoc;
-
- /// The location of the ':', which will be valid when the bound was
- /// explicitly specified.
- SourceLocation ColonLoc;
-
- ObjCTypeParamDecl(ASTContext &ctx, DeclContext *dc,
- ObjCTypeParamVariance variance, SourceLocation varianceLoc,
- unsigned index,
- SourceLocation nameLoc, IdentifierInfo *name,
- SourceLocation colonLoc, TypeSourceInfo *boundInfo)
- : TypedefNameDecl(ObjCTypeParam, ctx, dc, nameLoc, nameLoc, name,
- boundInfo),
- Index(index), Variance(static_cast<unsigned>(variance)),
- VarianceLoc(varianceLoc), ColonLoc(colonLoc) { }
-
-public:
- static ObjCTypeParamDecl *Create(ASTContext &ctx, DeclContext *dc,
- ObjCTypeParamVariance variance,
- SourceLocation varianceLoc,
- unsigned index,
- SourceLocation nameLoc,
- IdentifierInfo *name,
- SourceLocation colonLoc,
- TypeSourceInfo *boundInfo);
- static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- /// Determine the variance of this type parameter.
- ObjCTypeParamVariance getVariance() const {
- return static_cast<ObjCTypeParamVariance>(Variance);
- }
-
- /// Set the variance of this type parameter.
- void setVariance(ObjCTypeParamVariance variance) {
- Variance = static_cast<unsigned>(variance);
- }
-
- /// Retrieve the location of the variance keyword.
- SourceLocation getVarianceLoc() const { return VarianceLoc; }
-
- /// Retrieve the index into its type parameter list.
- unsigned getIndex() const { return Index; }
-
- /// Whether this type parameter has an explicitly-written type bound, e.g.,
- /// "T : NSView".
- bool hasExplicitBound() const { return ColonLoc.isValid(); }
-
- /// Retrieve the location of the ':' separating the type parameter name
- /// from the explicitly-specified bound.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCTypeParam; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Stores a list of Objective-C type parameters for a parameterized class
-/// or a category/extension thereof.
-///
-/// \code
-/// @interface NSArray<T> // stores the <T>
-/// @end
-/// \endcode
-class ObjCTypeParamList final
- : private llvm::TrailingObjects<ObjCTypeParamList, ObjCTypeParamDecl *> {
- /// Stores the components of a SourceRange as a POD.
- struct PODSourceRange {
- unsigned Begin;
- unsigned End;
- };
-
- union {
- /// Location of the left and right angle brackets.
- PODSourceRange Brackets;
-
- // Used only for alignment.
- ObjCTypeParamDecl *AlignmentHack;
- };
-
- /// The number of parameters in the list, which are tail-allocated.
- unsigned NumParams;
-
- ObjCTypeParamList(SourceLocation lAngleLoc,
- ArrayRef<ObjCTypeParamDecl *> typeParams,
- SourceLocation rAngleLoc);
-
-public:
- /// Create a new Objective-C type parameter list.
- static ObjCTypeParamList *create(ASTContext &ctx,
- SourceLocation lAngleLoc,
- ArrayRef<ObjCTypeParamDecl *> typeParams,
- SourceLocation rAngleLoc);
-
- /// Iterate through the type parameters in the list.
- typedef ObjCTypeParamDecl **iterator;
-
- iterator begin() { return getTrailingObjects<ObjCTypeParamDecl *>(); }
-
- iterator end() { return begin() + size(); }
-
- /// Determine the number of type parameters in this list.
- unsigned size() const { return NumParams; }
-
- // Iterate through the type parameters in the list.
- typedef ObjCTypeParamDecl * const *const_iterator;
-
- const_iterator begin() const {
- return getTrailingObjects<ObjCTypeParamDecl *>();
- }
-
- const_iterator end() const {
- return begin() + size();
- }
-
- ObjCTypeParamDecl *front() const {
- assert(size() > 0 && "empty Objective-C type parameter list");
- return *begin();
- }
-
- ObjCTypeParamDecl *back() const {
- assert(size() > 0 && "empty Objective-C type parameter list");
- return *(end() - 1);
- }
-
- SourceLocation getLAngleLoc() const {
- return SourceLocation::getFromRawEncoding(Brackets.Begin);
- }
- SourceLocation getRAngleLoc() const {
- return SourceLocation::getFromRawEncoding(Brackets.End);
- }
- SourceRange getSourceRange() const {
- return SourceRange(getLAngleLoc(), getRAngleLoc());
- }
-
- /// Gather the default set of type arguments to be substituted for
- /// these type parameters when dealing with an unspecialized type.
- void gatherDefaultTypeArgs(SmallVectorImpl<QualType> &typeArgs) const;
- friend TrailingObjects;
-};
-
-/// ObjCContainerDecl - Represents a container for method declarations.
-/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
-/// ObjCProtocolDecl, and ObjCImplDecl.
-///
-class ObjCContainerDecl : public NamedDecl, public DeclContext {
- void anchor() override;
-
- SourceLocation AtStart;
-
- // These two locations in the range mark the end of the method container.
- // The first points to the '@' token, and the second to the 'end' token.
- SourceRange AtEnd;
-public:
-
- ObjCContainerDecl(Kind DK, DeclContext *DC,
- IdentifierInfo *Id, SourceLocation nameLoc,
- SourceLocation atStartLoc)
- : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
-
- // Iterator access to properties.
- typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
- prop_range;
-
- prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
- prop_iterator prop_begin() const {
- return prop_iterator(decls_begin());
- }
- prop_iterator prop_end() const {
- return prop_iterator(decls_end());
- }
-
- // Iterator access to instance/class methods.
- typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
- method_range;
-
- method_range methods() const {
- return method_range(meth_begin(), meth_end());
- }
- method_iterator meth_begin() const {
- return method_iterator(decls_begin());
- }
- method_iterator meth_end() const {
- return method_iterator(decls_end());
- }
-
- typedef filtered_decl_iterator<ObjCMethodDecl,
- &ObjCMethodDecl::isInstanceMethod>
- instmeth_iterator;
- typedef llvm::iterator_range<instmeth_iterator> instmeth_range;
-
- instmeth_range instance_methods() const {
- return instmeth_range(instmeth_begin(), instmeth_end());
- }
- instmeth_iterator instmeth_begin() const {
- return instmeth_iterator(decls_begin());
- }
- instmeth_iterator instmeth_end() const {
- return instmeth_iterator(decls_end());
- }
-
- typedef filtered_decl_iterator<ObjCMethodDecl,
- &ObjCMethodDecl::isClassMethod>
- classmeth_iterator;
- typedef llvm::iterator_range<classmeth_iterator> classmeth_range;
-
- classmeth_range class_methods() const {
- return classmeth_range(classmeth_begin(), classmeth_end());
- }
- classmeth_iterator classmeth_begin() const {
- return classmeth_iterator(decls_begin());
- }
- classmeth_iterator classmeth_end() const {
- return classmeth_iterator(decls_end());
- }
-
- // Get the local instance/class method declared in this interface.
- ObjCMethodDecl *getMethod(Selector Sel, bool isInstance,
- bool AllowHidden = false) const;
- ObjCMethodDecl *getInstanceMethod(Selector Sel,
- bool AllowHidden = false) const {
- return getMethod(Sel, true/*isInstance*/, AllowHidden);
- }
- ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const {
- return getMethod(Sel, false/*isInstance*/, AllowHidden);
- }
- bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
- ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
-
- ObjCPropertyDecl *
- FindPropertyDeclaration(const IdentifierInfo *PropertyId) const;
-
- typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
-
- typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*>
- ProtocolPropertyMap;
-
- typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder;
-
- /// This routine collects list of properties to be implemented in the class.
- /// This includes, class's and its conforming protocols' properties.
- /// Note, the superclass's properties are not included in the list.
- virtual void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const {}
-
- SourceLocation getAtStartLoc() const { return AtStart; }
- void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
-
- // Marks the end of the container.
- SourceRange getAtEndRange() const {
- return AtEnd;
- }
- void setAtEndRange(SourceRange atEnd) {
- AtEnd = atEnd;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(AtStart, getAtEndRange().getEnd());
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstObjCContainer &&
- K <= lastObjCContainer;
- }
-
- static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
- return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
- }
- static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
- return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
- }
-};
-
-/// \brief Represents an ObjC class declaration.
-///
-/// For example:
-///
-/// \code
-/// // MostPrimitive declares no super class (not particularly useful).
-/// \@interface MostPrimitive
-/// // no instance variables or methods.
-/// \@end
-///
-/// // NSResponder inherits from NSObject & implements NSCoding (a protocol).
-/// \@interface NSResponder : NSObject \<NSCoding>
-/// { // instance variables are represented by ObjCIvarDecl.
-/// id nextResponder; // nextResponder instance variable.
-/// }
-/// - (NSResponder *)nextResponder; // return a pointer to NSResponder.
-/// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
-/// \@end // to an NSEvent.
-/// \endcode
-///
-/// Unlike C/C++, forward class declarations are accomplished with \@class.
-/// Unlike C/C++, \@class allows for a list of classes to be forward declared.
-/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
-/// typically inherit from NSObject (an exception is NSProxy).
-///
-class ObjCInterfaceDecl : public ObjCContainerDecl
- , public Redeclarable<ObjCInterfaceDecl> {
- void anchor() override;
-
- /// TypeForDecl - This indicates the Type object that represents this
- /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
- mutable const Type *TypeForDecl;
- friend class ASTContext;
-
- struct DefinitionData {
- /// \brief The definition of this class, for quick access from any
- /// declaration.
- ObjCInterfaceDecl *Definition;
-
- /// When non-null, this is always an ObjCObjectType.
- TypeSourceInfo *SuperClassTInfo;
-
- /// Protocols referenced in the \@interface declaration
- ObjCProtocolList ReferencedProtocols;
-
- /// Protocols reference in both the \@interface and class extensions.
- ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
-
- /// \brief List of categories and class extensions defined for this class.
- ///
- /// Categories are stored as a linked list in the AST, since the categories
- /// and class extensions come long after the initial interface declaration,
- /// and we avoid dynamically-resized arrays in the AST wherever possible.
- ObjCCategoryDecl *CategoryList;
-
- /// IvarList - List of all ivars defined by this class; including class
- /// extensions and implementation. This list is built lazily.
- ObjCIvarDecl *IvarList;
-
- /// \brief Indicates that the contents of this Objective-C class will be
- /// completed by the external AST source when required.
- mutable bool ExternallyCompleted : 1;
-
- /// \brief Indicates that the ivar cache does not yet include ivars
- /// declared in the implementation.
- mutable bool IvarListMissingImplementation : 1;
-
- /// Indicates that this interface decl contains at least one initializer
- /// marked with the 'objc_designated_initializer' attribute.
- bool HasDesignatedInitializers : 1;
-
- enum InheritedDesignatedInitializersState {
- /// We didn't calculate whether the designated initializers should be
- /// inherited or not.
- IDI_Unknown = 0,
- /// Designated initializers are inherited for the super class.
- IDI_Inherited = 1,
- /// The class does not inherit designated initializers.
- IDI_NotInherited = 2
- };
- /// One of the \c InheritedDesignatedInitializersState enumeratos.
- mutable unsigned InheritedDesignatedInitializers : 2;
-
- /// \brief The location of the last location in this declaration, before
- /// the properties/methods. For example, this will be the '>', '}', or
- /// identifier,
- SourceLocation EndLoc;
-
- DefinitionData() : Definition(), SuperClassTInfo(), CategoryList(), IvarList(),
- ExternallyCompleted(),
- IvarListMissingImplementation(true),
- HasDesignatedInitializers(),
- InheritedDesignatedInitializers(IDI_Unknown) { }
- };
-
- ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
- IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
- SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
- bool IsInternal);
-
- void LoadExternalDefinition() const;
-
- /// The type parameters associated with this class, if any.
- ObjCTypeParamList *TypeParamList;
-
- /// \brief Contains a pointer to the data associated with this class,
- /// which will be NULL if this class has not yet been defined.
- ///
- /// The bit indicates when we don't need to check for out-of-date
- /// declarations. It will be set unless modules are enabled.
- llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
-
- DefinitionData &data() const {
- assert(Data.getPointer() && "Declaration has no definition!");
- return *Data.getPointer();
- }
-
- /// \brief Allocate the definition data for this class.
- void allocateDefinitionData();
-
- typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
- ObjCInterfaceDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- ObjCInterfaceDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- ObjCInterfaceDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation atLoc,
- IdentifierInfo *Id,
- ObjCTypeParamList *typeParamList,
- ObjCInterfaceDecl *PrevDecl,
- SourceLocation ClassLoc = SourceLocation(),
- bool isInternal = false);
-
- static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
-
- /// Retrieve the type parameters of this class.
- ///
- /// This function looks for a type parameter list for the given
- /// class; if the class has been declared (with \c \@class) but not
- /// defined (with \c \@interface), it will search for a declaration that
- /// has type parameters, skipping any declarations that do not.
- ObjCTypeParamList *getTypeParamList() const;
-
- /// Set the type parameters of this class.
- ///
- /// This function is used by the AST importer, which must import the type
- /// parameters after creating their DeclContext to avoid loops.
- void setTypeParamList(ObjCTypeParamList *TPL);
-
- /// Retrieve the type parameters written on this particular declaration of
- /// the class.
- ObjCTypeParamList *getTypeParamListAsWritten() const {
- return TypeParamList;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- if (isThisDeclarationADefinition())
- return ObjCContainerDecl::getSourceRange();
-
- return SourceRange(getAtStartLoc(), getLocation());
- }
-
- /// \brief Indicate that this Objective-C class is complete, but that
- /// the external AST source will be responsible for filling in its contents
- /// when a complete class is required.
- void setExternallyCompleted();
-
- /// Indicate that this interface decl contains at least one initializer
- /// marked with the 'objc_designated_initializer' attribute.
- void setHasDesignatedInitializers();
-
- /// Returns true if this interface decl contains at least one initializer
- /// marked with the 'objc_designated_initializer' attribute.
- bool hasDesignatedInitializers() const;
-
- /// Returns true if this interface decl declares a designated initializer
- /// or it inherites one from its super class.
- bool declaresOrInheritsDesignatedInitializers() const {
- return hasDesignatedInitializers() || inheritsDesignatedInitializers();
- }
-
- const ObjCProtocolList &getReferencedProtocols() const {
- assert(hasDefinition() && "Caller did not check for forward reference!");
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols;
- }
-
- ObjCImplementationDecl *getImplementation() const;
- void setImplementation(ObjCImplementationDecl *ImplD);
-
- ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
-
- // Get the local instance/class method declared in a category.
- ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
- ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
- ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
- return isInstance ? getCategoryInstanceMethod(Sel)
- : getCategoryClassMethod(Sel);
- }
-
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
-
- protocol_range protocols() const {
- return protocol_range(protocol_begin(), protocol_end());
- }
- protocol_iterator protocol_begin() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.begin();
- }
- protocol_iterator protocol_end() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.end();
- }
-
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
-
- protocol_loc_range protocol_locs() const {
- return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
- }
- protocol_loc_iterator protocol_loc_begin() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.loc_begin();
- }
-
- protocol_loc_iterator protocol_loc_end() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().ReferencedProtocols.loc_end();
- }
-
- typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
- typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range;
-
- all_protocol_range all_referenced_protocols() const {
- return all_protocol_range(all_referenced_protocol_begin(),
- all_referenced_protocol_end());
- }
- all_protocol_iterator all_referenced_protocol_begin() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return all_protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().AllReferencedProtocols.empty()
- ? protocol_begin()
- : data().AllReferencedProtocols.begin();
- }
- all_protocol_iterator all_referenced_protocol_end() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return all_protocol_iterator();
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().AllReferencedProtocols.empty()
- ? protocol_end()
- : data().AllReferencedProtocols.end();
- }
-
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
-
- ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
- ivar_iterator ivar_begin() const {
- if (const ObjCInterfaceDecl *Def = getDefinition())
- return ivar_iterator(Def->decls_begin());
-
- // FIXME: Should make sure no callers ever do this.
- return ivar_iterator();
- }
- ivar_iterator ivar_end() const {
- if (const ObjCInterfaceDecl *Def = getDefinition())
- return ivar_iterator(Def->decls_end());
-
- // FIXME: Should make sure no callers ever do this.
- return ivar_iterator();
- }
-
- unsigned ivar_size() const {
- return std::distance(ivar_begin(), ivar_end());
- }
-
- bool ivar_empty() const { return ivar_begin() == ivar_end(); }
-
- ObjCIvarDecl *all_declared_ivar_begin();
- const ObjCIvarDecl *all_declared_ivar_begin() const {
- // Even though this modifies IvarList, it's conceptually const:
- // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
- return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
- }
- void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
-
- /// setProtocolList - Set the list of protocols that this interface
- /// implements.
- void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
- const SourceLocation *Locs, ASTContext &C) {
- data().ReferencedProtocols.set(List, Num, Locs, C);
- }
-
- /// mergeClassExtensionProtocolList - Merge class extension's protocol list
- /// into the protocol list for this class.
- void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
- unsigned Num,
- ASTContext &C);
-
- /// Produce a name to be used for class's metadata. It comes either via
- /// objc_runtime_name attribute or class name.
- StringRef getObjCRuntimeNameAsString() const;
-
- /// Returns the designated initializers for the interface.
- ///
- /// If this declaration does not have methods marked as designated
- /// initializers then the interface inherits the designated initializers of
- /// its super class.
- void getDesignatedInitializers(
- llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const;
-
- /// Returns true if the given selector is a designated initializer for the
- /// interface.
- ///
- /// If this declaration does not have methods marked as designated
- /// initializers then the interface inherits the designated initializers of
- /// its super class.
- ///
- /// \param InitMethod if non-null and the function returns true, it receives
- /// the method that was marked as a designated initializer.
- bool
- isDesignatedInitializer(Selector Sel,
- const ObjCMethodDecl **InitMethod = nullptr) const;
-
- /// \brief Determine whether this particular declaration of this class is
- /// actually also a definition.
- bool isThisDeclarationADefinition() const {
- return getDefinition() == this;
- }
-
- /// \brief Determine whether this class has been defined.
- bool hasDefinition() const {
- // If the name of this class is out-of-date, bring it up-to-date, which
- // might bring in a definition.
- // Note: a null value indicates that we don't have a definition and that
- // modules are enabled.
- if (!Data.getOpaqueValue())
- getMostRecentDecl();
-
- return Data.getPointer();
- }
-
- /// \brief Retrieve the definition of this class, or NULL if this class
- /// has been forward-declared (with \@class) but not yet defined (with
- /// \@interface).
- ObjCInterfaceDecl *getDefinition() {
- return hasDefinition()? Data.getPointer()->Definition : nullptr;
- }
-
- /// \brief Retrieve the definition of this class, or NULL if this class
- /// has been forward-declared (with \@class) but not yet defined (with
- /// \@interface).
- const ObjCInterfaceDecl *getDefinition() const {
- return hasDefinition()? Data.getPointer()->Definition : nullptr;
- }
-
- /// \brief Starts the definition of this Objective-C class, taking it from
- /// a forward declaration (\@class) to a definition (\@interface).
- void startDefinition();
-
- /// Retrieve the superclass type.
- const ObjCObjectType *getSuperClassType() const {
- if (TypeSourceInfo *TInfo = getSuperClassTInfo())
- return TInfo->getType()->castAs<ObjCObjectType>();
-
- return nullptr;
- }
-
- // Retrieve the type source information for the superclass.
- TypeSourceInfo *getSuperClassTInfo() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return nullptr;
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().SuperClassTInfo;
- }
-
- // Retrieve the declaration for the superclass of this class, which
- // does not include any type arguments that apply to the superclass.
- ObjCInterfaceDecl *getSuperClass() const;
-
- void setSuperClass(TypeSourceInfo *superClass) {
- data().SuperClassTInfo = superClass;
- }
-
- /// \brief Iterator that walks over the list of categories, filtering out
- /// those that do not meet specific criteria.
- ///
- /// This class template is used for the various permutations of category
- /// and extension iterators.
- template<bool (*Filter)(ObjCCategoryDecl *)>
- class filtered_category_iterator {
- ObjCCategoryDecl *Current;
-
- void findAcceptableCategory();
-
- public:
- typedef ObjCCategoryDecl * value_type;
- typedef value_type reference;
- typedef value_type pointer;
- typedef std::ptrdiff_t difference_type;
- typedef std::input_iterator_tag iterator_category;
-
- filtered_category_iterator() : Current(nullptr) { }
- explicit filtered_category_iterator(ObjCCategoryDecl *Current)
- : Current(Current)
- {
- findAcceptableCategory();
- }
-
- reference operator*() const { return Current; }
- pointer operator->() const { return Current; }
-
- filtered_category_iterator &operator++();
-
- filtered_category_iterator operator++(int) {
- filtered_category_iterator Tmp = *this;
- ++(*this);
- return Tmp;
- }
-
- friend bool operator==(filtered_category_iterator X,
- filtered_category_iterator Y) {
- return X.Current == Y.Current;
- }
-
- friend bool operator!=(filtered_category_iterator X,
- filtered_category_iterator Y) {
- return X.Current != Y.Current;
- }
- };
-
-private:
- /// \brief Test whether the given category is visible.
- ///
- /// Used in the \c visible_categories_iterator.
- static bool isVisibleCategory(ObjCCategoryDecl *Cat);
-
-public:
- /// \brief Iterator that walks over the list of categories and extensions
- /// that are visible, i.e., not hidden in a non-imported submodule.
- typedef filtered_category_iterator<isVisibleCategory>
- visible_categories_iterator;
-
- typedef llvm::iterator_range<visible_categories_iterator>
- visible_categories_range;
-
- visible_categories_range visible_categories() const {
- return visible_categories_range(visible_categories_begin(),
- visible_categories_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the visible-categories
- /// list.
- visible_categories_iterator visible_categories_begin() const {
- return visible_categories_iterator(getCategoryListRaw());
- }
-
- /// \brief Retrieve an iterator to the end of the visible-categories list.
- visible_categories_iterator visible_categories_end() const {
- return visible_categories_iterator();
- }
-
- /// \brief Determine whether the visible-categories list is empty.
- bool visible_categories_empty() const {
- return visible_categories_begin() == visible_categories_end();
- }
-
-private:
- /// \brief Test whether the given category... is a category.
- ///
- /// Used in the \c known_categories_iterator.
- static bool isKnownCategory(ObjCCategoryDecl *) { return true; }
-
-public:
- /// \brief Iterator that walks over all of the known categories and
- /// extensions, including those that are hidden.
- typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
- typedef llvm::iterator_range<known_categories_iterator>
- known_categories_range;
-
- known_categories_range known_categories() const {
- return known_categories_range(known_categories_begin(),
- known_categories_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the known-categories
- /// list.
- known_categories_iterator known_categories_begin() const {
- return known_categories_iterator(getCategoryListRaw());
- }
-
- /// \brief Retrieve an iterator to the end of the known-categories list.
- known_categories_iterator known_categories_end() const {
- return known_categories_iterator();
- }
-
- /// \brief Determine whether the known-categories list is empty.
- bool known_categories_empty() const {
- return known_categories_begin() == known_categories_end();
- }
-
-private:
- /// \brief Test whether the given category is a visible extension.
- ///
- /// Used in the \c visible_extensions_iterator.
- static bool isVisibleExtension(ObjCCategoryDecl *Cat);
-
-public:
- /// \brief Iterator that walks over all of the visible extensions, skipping
- /// any that are known but hidden.
- typedef filtered_category_iterator<isVisibleExtension>
- visible_extensions_iterator;
-
- typedef llvm::iterator_range<visible_extensions_iterator>
- visible_extensions_range;
-
- visible_extensions_range visible_extensions() const {
- return visible_extensions_range(visible_extensions_begin(),
- visible_extensions_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the visible-extensions
- /// list.
- visible_extensions_iterator visible_extensions_begin() const {
- return visible_extensions_iterator(getCategoryListRaw());
- }
-
- /// \brief Retrieve an iterator to the end of the visible-extensions list.
- visible_extensions_iterator visible_extensions_end() const {
- return visible_extensions_iterator();
- }
-
- /// \brief Determine whether the visible-extensions list is empty.
- bool visible_extensions_empty() const {
- return visible_extensions_begin() == visible_extensions_end();
- }
-
-private:
- /// \brief Test whether the given category is an extension.
- ///
- /// Used in the \c known_extensions_iterator.
- static bool isKnownExtension(ObjCCategoryDecl *Cat);
-
-public:
- /// \brief Iterator that walks over all of the known extensions.
- typedef filtered_category_iterator<isKnownExtension>
- known_extensions_iterator;
- typedef llvm::iterator_range<known_extensions_iterator>
- known_extensions_range;
-
- known_extensions_range known_extensions() const {
- return known_extensions_range(known_extensions_begin(),
- known_extensions_end());
- }
-
- /// \brief Retrieve an iterator to the beginning of the known-extensions
- /// list.
- known_extensions_iterator known_extensions_begin() const {
- return known_extensions_iterator(getCategoryListRaw());
- }
-
- /// \brief Retrieve an iterator to the end of the known-extensions list.
- known_extensions_iterator known_extensions_end() const {
- return known_extensions_iterator();
- }
-
- /// \brief Determine whether the known-extensions list is empty.
- bool known_extensions_empty() const {
- return known_extensions_begin() == known_extensions_end();
- }
-
- /// \brief Retrieve the raw pointer to the start of the category/extension
- /// list.
- ObjCCategoryDecl* getCategoryListRaw() const {
- // FIXME: Should make sure no callers ever do this.
- if (!hasDefinition())
- return nullptr;
-
- if (data().ExternallyCompleted)
- LoadExternalDefinition();
-
- return data().CategoryList;
- }
-
- /// \brief Set the raw pointer to the start of the category/extension
- /// list.
- void setCategoryListRaw(ObjCCategoryDecl *category) {
- data().CategoryList = category;
- }
-
- ObjCPropertyDecl
- *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
-
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
-
- /// isSuperClassOf - Return true if this class is the specified class or is a
- /// super class of the specified interface class.
- bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
- // If RHS is derived from LHS it is OK; else it is not OK.
- while (I != nullptr) {
- if (declaresSameEntity(this, I))
- return true;
-
- I = I->getSuperClass();
- }
- return false;
- }
-
- /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
- /// to be incompatible with __weak references. Returns true if it is.
- bool isArcWeakrefUnavailable() const;
-
- /// isObjCRequiresPropertyDefs - Checks that a class or one of its super
- /// classes must not be auto-synthesized. Returns class decl. if it must not
- /// be; 0, otherwise.
- const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const;
-
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
- ObjCInterfaceDecl *&ClassDeclared);
- ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
- ObjCInterfaceDecl *ClassDeclared;
- return lookupInstanceVariable(IVarName, ClassDeclared);
- }
-
- ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name);
-
- // Lookup a method. First, we search locally. If a method isn't
- // found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
- bool shallowCategoryLookup = false,
- bool followSuper = true,
- const ObjCCategoryDecl *C = nullptr) const;
-
- /// Lookup an instance method for a given selector.
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
- return lookupMethod(Sel, true/*isInstance*/);
- }
-
- /// Lookup a class method for a given selector.
- ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
- return lookupMethod(Sel, false/*isInstance*/);
- }
- ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
-
- /// \brief Lookup a method in the classes implementation hierarchy.
- ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
- bool Instance=true) const;
-
- ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
- return lookupPrivateMethod(Sel, false);
- }
-
- /// \brief Lookup a setter or getter in the class hierarchy,
- /// including in all categories except for category passed
- /// as argument.
- ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
- const ObjCCategoryDecl *Cat) const {
- return lookupMethod(Sel, true/*isInstance*/,
- false/*shallowCategoryLookup*/,
- true /* followsSuper */,
- Cat);
- }
-
- SourceLocation getEndOfDefinitionLoc() const {
- if (!hasDefinition())
- return getLocation();
-
- return data().EndLoc;
- }
-
- void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
-
- /// Retrieve the starting location of the superclass.
- SourceLocation getSuperClassLoc() const;
-
- /// isImplicitInterfaceDecl - check that this is an implicitly declared
- /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation
- /// declaration without an \@interface declaration.
- bool isImplicitInterfaceDecl() const {
- return hasDefinition() ? data().Definition->isImplicit() : isImplicit();
- }
-
- /// ClassImplementsProtocol - Checks that 'lProto' protocol
- /// has been implemented in IDecl class, its super class or categories (if
- /// lookupCategory is true).
- bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
- bool lookupCategory,
- bool RHSIsQualifiedID = false);
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- /// Retrieves the canonical declaration of this Objective-C class.
- ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- // Low-level accessor
- const Type *getTypeForDecl() const { return TypeForDecl; }
- void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCInterface; }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-
-private:
- const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
- bool inheritsDesignatedInitializers() const;
-};
-
-/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
-/// instance variables are identical to C. The only exception is Objective-C
-/// supports C++ style access control. For example:
-///
-/// \@interface IvarExample : NSObject
-/// {
-/// id defaultToProtected;
-/// \@public:
-/// id canBePublic; // same as C++.
-/// \@protected:
-/// id canBeProtected; // same as C++.
-/// \@package:
-/// id canBePackage; // framework visibility (not available in C++).
-/// }
-///
-class ObjCIvarDecl : public FieldDecl {
- void anchor() override;
-
-public:
- enum AccessControl {
- None, Private, Protected, Public, Package
- };
-
-private:
- ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
- bool synthesized)
- : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
- /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
- NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {}
-
-public:
- static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo,
- AccessControl ac, Expr *BW = nullptr,
- bool synthesized=false);
-
- static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief Return the class interface that this ivar is logically contained
- /// in; this is either the interface where the ivar was declared, or the
- /// interface the ivar is conceptually a part of in the case of synthesized
- /// ivars.
- const ObjCInterfaceDecl *getContainingInterface() const;
-
- ObjCIvarDecl *getNextIvar() { return NextIvar; }
- const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
- void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
-
- void setAccessControl(AccessControl ac) { DeclAccess = ac; }
-
- AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
-
- AccessControl getCanonicalAccessControl() const {
- return DeclAccess == None ? Protected : AccessControl(DeclAccess);
- }
-
- void setSynthesize(bool synth) { Synthesized = synth; }
- bool getSynthesize() const { return Synthesized; }
-
- /// Retrieve the type of this instance variable when viewed as a member of a
- /// specific object type.
- QualType getUsageType(QualType objectType) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCIvar; }
-private:
- /// NextIvar - Next Ivar in the list of ivars declared in class; class's
- /// extensions and class's implementation
- ObjCIvarDecl *NextIvar;
-
- // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
- unsigned DeclAccess : 3;
- unsigned Synthesized : 1;
-};
-
-
-/// \brief Represents a field declaration created by an \@defs(...).
-class ObjCAtDefsFieldDecl : public FieldDecl {
- void anchor() override;
- ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, Expr *BW)
- : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
- /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
- BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
-
-public:
- static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, Expr *BW);
-
- static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
-};
-
-/// \brief Represents an Objective-C protocol declaration.
-///
-/// Objective-C protocols declare a pure abstract type (i.e., no instance
-/// variables are permitted). Protocols originally drew inspiration from
-/// C++ pure virtual functions (a C++ feature with nice semantics and lousy
-/// syntax:-). Here is an example:
-///
-/// \code
-/// \@protocol NSDraggingInfo <refproto1, refproto2>
-/// - (NSWindow *)draggingDestinationWindow;
-/// - (NSImage *)draggedImage;
-/// \@end
-/// \endcode
-///
-/// This says that NSDraggingInfo requires two methods and requires everything
-/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
-/// well.
-///
-/// \code
-/// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo>
-/// \@end
-/// \endcode
-///
-/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
-/// protocols are in distinct namespaces. For example, Cocoa defines both
-/// an NSObject protocol and class (which isn't allowed in Java). As a result,
-/// protocols are referenced using angle brackets as follows:
-///
-/// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
-///
-class ObjCProtocolDecl : public ObjCContainerDecl,
- public Redeclarable<ObjCProtocolDecl> {
- void anchor() override;
-
- struct DefinitionData {
- // \brief The declaration that defines this protocol.
- ObjCProtocolDecl *Definition;
-
- /// \brief Referenced protocols
- ObjCProtocolList ReferencedProtocols;
- };
-
- /// \brief Contains a pointer to the data associated with this class,
- /// which will be NULL if this class has not yet been defined.
- ///
- /// The bit indicates when we don't need to check for out-of-date
- /// declarations. It will be set unless modules are enabled.
- llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
-
- DefinitionData &data() const {
- assert(Data.getPointer() && "Objective-C protocol has no definition!");
- return *Data.getPointer();
- }
-
- ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- ObjCProtocolDecl *PrevDecl);
-
- void allocateDefinitionData();
-
- typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
- ObjCProtocolDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- ObjCProtocolDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- ObjCProtocolDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-public:
- static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
- IdentifierInfo *Id,
- SourceLocation nameLoc,
- SourceLocation atStartLoc,
- ObjCProtocolDecl *PrevDecl);
-
- static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- const ObjCProtocolList &getReferencedProtocols() const {
- assert(hasDefinition() && "No definition available!");
- return data().ReferencedProtocols;
- }
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
-
- protocol_range protocols() const {
- return protocol_range(protocol_begin(), protocol_end());
- }
- protocol_iterator protocol_begin() const {
- if (!hasDefinition())
- return protocol_iterator();
-
- return data().ReferencedProtocols.begin();
- }
- protocol_iterator protocol_end() const {
- if (!hasDefinition())
- return protocol_iterator();
-
- return data().ReferencedProtocols.end();
- }
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
-
- protocol_loc_range protocol_locs() const {
- return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
- }
- protocol_loc_iterator protocol_loc_begin() const {
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- return data().ReferencedProtocols.loc_begin();
- }
- protocol_loc_iterator protocol_loc_end() const {
- if (!hasDefinition())
- return protocol_loc_iterator();
-
- return data().ReferencedProtocols.loc_end();
- }
- unsigned protocol_size() const {
- if (!hasDefinition())
- return 0;
-
- return data().ReferencedProtocols.size();
- }
-
- /// setProtocolList - Set the list of protocols that this interface
- /// implements.
- void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
- const SourceLocation *Locs, ASTContext &C) {
- assert(hasDefinition() && "Protocol is not defined");
- data().ReferencedProtocols.set(List, Num, Locs, C);
- }
-
- ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
-
- // Lookup a method. First, we search locally. If a method isn't
- // found, we search referenced protocols and class categories.
- ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
- return lookupMethod(Sel, true/*isInstance*/);
- }
- ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
- return lookupMethod(Sel, false/*isInstance*/);
- }
-
- /// \brief Determine whether this protocol has a definition.
- bool hasDefinition() const {
- // If the name of this protocol is out-of-date, bring it up-to-date, which
- // might bring in a definition.
- // Note: a null value indicates that we don't have a definition and that
- // modules are enabled.
- if (!Data.getOpaqueValue())
- getMostRecentDecl();
-
- return Data.getPointer();
- }
-
- /// \brief Retrieve the definition of this protocol, if any.
- ObjCProtocolDecl *getDefinition() {
- return hasDefinition()? Data.getPointer()->Definition : nullptr;
- }
-
- /// \brief Retrieve the definition of this protocol, if any.
- const ObjCProtocolDecl *getDefinition() const {
- return hasDefinition()? Data.getPointer()->Definition : nullptr;
- }
-
- /// \brief Determine whether this particular declaration is also the
- /// definition.
- bool isThisDeclarationADefinition() const {
- return getDefinition() == this;
- }
-
- /// \brief Starts the definition of this Objective-C protocol.
- void startDefinition();
-
- /// Produce a name to be used for protocol's metadata. It comes either via
- /// objc_runtime_name attribute or protocol name.
- StringRef getObjCRuntimeNameAsString() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- if (isThisDeclarationADefinition())
- return ObjCContainerDecl::getSourceRange();
-
- return SourceRange(getAtStartLoc(), getLocation());
- }
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- /// Retrieves the canonical declaration of this Objective-C protocol.
- ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
-
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
-
- void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
- ProtocolPropertyMap &PM) const;
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCProtocol; }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// ObjCCategoryDecl - Represents a category declaration. A category allows
-/// you to add methods to an existing class (without subclassing or modifying
-/// the original class interface or implementation:-). Categories don't allow
-/// you to add instance data. The following example adds "myMethod" to all
-/// NSView's within a process:
-///
-/// \@interface NSView (MyViewMethods)
-/// - myMethod;
-/// \@end
-///
-/// Categories also allow you to split the implementation of a class across
-/// several files (a feature more naturally supported in C++).
-///
-/// Categories were originally inspired by dynamic languages such as Common
-/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
-/// don't support this level of dynamism, which is both powerful and dangerous.
-///
-class ObjCCategoryDecl : public ObjCContainerDecl {
- void anchor() override;
-
- /// Interface belonging to this category
- ObjCInterfaceDecl *ClassInterface;
-
- /// The type parameters associated with this category, if any.
- ObjCTypeParamList *TypeParamList;
-
- /// referenced protocols in this category.
- ObjCProtocolList ReferencedProtocols;
-
- /// Next category belonging to this class.
- /// FIXME: this should not be a singly-linked list. Move storage elsewhere.
- ObjCCategoryDecl *NextClassCategory;
-
- /// \brief The location of the category name in this declaration.
- SourceLocation CategoryNameLoc;
-
- /// class extension may have private ivars.
- SourceLocation IvarLBraceLoc;
- SourceLocation IvarRBraceLoc;
-
- ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
- SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
- IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
- ObjCTypeParamList *typeParamList,
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
-
-public:
-
- static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation AtLoc,
- SourceLocation ClassNameLoc,
- SourceLocation CategoryNameLoc,
- IdentifierInfo *Id,
- ObjCInterfaceDecl *IDecl,
- ObjCTypeParamList *typeParamList,
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
- static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
- const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
-
- /// Retrieve the type parameter list associated with this category or
- /// extension.
- ObjCTypeParamList *getTypeParamList() const { return TypeParamList; }
-
- /// Set the type parameters of this category.
- ///
- /// This function is used by the AST importer, which must import the type
- /// parameters after creating their DeclContext to avoid loops.
- void setTypeParamList(ObjCTypeParamList *TPL);
-
-
- ObjCCategoryImplDecl *getImplementation() const;
- void setImplementation(ObjCCategoryImplDecl *ImplD);
-
- /// setProtocolList - Set the list of protocols that this interface
- /// implements.
- void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
- const SourceLocation *Locs, ASTContext &C) {
- ReferencedProtocols.set(List, Num, Locs, C);
- }
-
- const ObjCProtocolList &getReferencedProtocols() const {
- return ReferencedProtocols;
- }
-
- typedef ObjCProtocolList::iterator protocol_iterator;
- typedef llvm::iterator_range<protocol_iterator> protocol_range;
-
- protocol_range protocols() const {
- return protocol_range(protocol_begin(), protocol_end());
- }
- protocol_iterator protocol_begin() const {
- return ReferencedProtocols.begin();
- }
- protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
- unsigned protocol_size() const { return ReferencedProtocols.size(); }
- typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
- typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
-
- protocol_loc_range protocol_locs() const {
- return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
- }
- protocol_loc_iterator protocol_loc_begin() const {
- return ReferencedProtocols.loc_begin();
- }
- protocol_loc_iterator protocol_loc_end() const {
- return ReferencedProtocols.loc_end();
- }
-
- ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
-
- /// \brief Retrieve the pointer to the next stored category (or extension),
- /// which may be hidden.
- ObjCCategoryDecl *getNextClassCategoryRaw() const {
- return NextClassCategory;
- }
-
- bool IsClassExtension() const { return getIdentifier() == nullptr; }
-
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
-
- ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
- ivar_iterator ivar_begin() const {
- return ivar_iterator(decls_begin());
- }
- ivar_iterator ivar_end() const {
- return ivar_iterator(decls_end());
- }
- unsigned ivar_size() const {
- return std::distance(ivar_begin(), ivar_end());
- }
- bool ivar_empty() const {
- return ivar_begin() == ivar_end();
- }
-
- SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
- void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
-
- void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
- SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
- void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
- SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCCategory; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-class ObjCImplDecl : public ObjCContainerDecl {
- void anchor() override;
-
- /// Class interface for this class/category implementation
- ObjCInterfaceDecl *ClassInterface;
-
-protected:
- ObjCImplDecl(Kind DK, DeclContext *DC,
- ObjCInterfaceDecl *classInterface,
- SourceLocation nameLoc, SourceLocation atStartLoc)
- : ObjCContainerDecl(DK, DC,
- classInterface? classInterface->getIdentifier()
- : nullptr,
- nameLoc, atStartLoc),
- ClassInterface(classInterface) {}
-
-public:
- const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
- ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
- void setClassInterface(ObjCInterfaceDecl *IFace);
-
- void addInstanceMethod(ObjCMethodDecl *method) {
- // FIXME: Context should be set correctly before we get here.
- method->setLexicalDeclContext(this);
- addDecl(method);
- }
- void addClassMethod(ObjCMethodDecl *method) {
- // FIXME: Context should be set correctly before we get here.
- method->setLexicalDeclContext(this);
- addDecl(method);
- }
-
- void addPropertyImplementation(ObjCPropertyImplDecl *property);
-
- ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
- ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
-
- // Iterator access to properties.
- typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>
- propimpl_range;
-
- propimpl_range property_impls() const {
- return propimpl_range(propimpl_begin(), propimpl_end());
- }
- propimpl_iterator propimpl_begin() const {
- return propimpl_iterator(decls_begin());
- }
- propimpl_iterator propimpl_end() const {
- return propimpl_iterator(decls_end());
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstObjCImpl && K <= lastObjCImpl;
- }
-};
-
-/// ObjCCategoryImplDecl - An object of this class encapsulates a category
-/// \@implementation declaration. If a category class has declaration of a
-/// property, its implementation must be specified in the category's
-/// \@implementation declaration. Example:
-/// \@interface I \@end
-/// \@interface I(CATEGORY)
-/// \@property int p1, d1;
-/// \@end
-/// \@implementation I(CATEGORY)
-/// \@dynamic p1,d1;
-/// \@end
-///
-/// ObjCCategoryImplDecl
-class ObjCCategoryImplDecl : public ObjCImplDecl {
- void anchor() override;
-
- // Category name
- IdentifierInfo *Id;
-
- // Category name location
- SourceLocation CategoryNameLoc;
-
- ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- SourceLocation CategoryNameLoc)
- : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
- Id(Id), CategoryNameLoc(CategoryNameLoc) {}
-public:
- static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
- IdentifierInfo *Id,
- ObjCInterfaceDecl *classInterface,
- SourceLocation nameLoc,
- SourceLocation atStartLoc,
- SourceLocation CategoryNameLoc);
- static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// getIdentifier - Get the identifier that names the category
- /// interface associated with this implementation.
- /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
- /// with a different meaning. For example:
- /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
- /// returns the class interface name, whereas
- /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
- /// returns the category name.
- IdentifierInfo *getIdentifier() const {
- return Id;
- }
- void setIdentifier(IdentifierInfo *II) { Id = II; }
-
- ObjCCategoryDecl *getCategoryDecl() const;
-
- SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
-
- /// getName - Get the name of identifier for the class interface associated
- /// with this implementation as a StringRef.
- //
- // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
- // meaning.
- StringRef getName() const { return Id ? Id->getName() : StringRef(); }
-
- /// @brief Get the name of the class associated with this interface.
- //
- // FIXME: Deprecated, move clients to getName().
- std::string getNameAsString() const {
- return getName();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
-
-/// ObjCImplementationDecl - Represents a class definition - this is where
-/// method definitions are specified. For example:
-///
-/// @code
-/// \@implementation MyClass
-/// - (void)myMethod { /* do something */ }
-/// \@end
-/// @endcode
-///
-/// In a non-fragile runtime, instance variables can appear in the class
-/// interface, class extensions (nameless categories), and in the implementation
-/// itself, as well as being synthesized as backing storage for properties.
-///
-/// In a fragile runtime, instance variables are specified in the class
-/// interface, \em not in the implementation. Nevertheless (for legacy reasons),
-/// we allow instance variables to be specified in the implementation. When
-/// specified, they need to be \em identical to the interface.
-class ObjCImplementationDecl : public ObjCImplDecl {
- void anchor() override;
- /// Implementation Class's super class.
- ObjCInterfaceDecl *SuperClass;
- SourceLocation SuperLoc;
-
- /// \@implementation may have private ivars.
- SourceLocation IvarLBraceLoc;
- SourceLocation IvarRBraceLoc;
-
- /// Support for ivar initialization.
- /// \brief The arguments used to initialize the ivars
- LazyCXXCtorInitializersPtr IvarInitializers;
- unsigned NumIvarInitializers;
-
- /// Do the ivars of this class require initialization other than
- /// zero-initialization?
- bool HasNonZeroConstructors : 1;
-
- /// Do the ivars of this class require non-trivial destruction?
- bool HasDestructors : 1;
-
- ObjCImplementationDecl(DeclContext *DC,
- ObjCInterfaceDecl *classInterface,
- ObjCInterfaceDecl *superDecl,
- SourceLocation nameLoc, SourceLocation atStartLoc,
- SourceLocation superLoc = SourceLocation(),
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation())
- : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
- SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
- IvarRBraceLoc(IvarRBraceLoc),
- IvarInitializers(nullptr), NumIvarInitializers(0),
- HasNonZeroConstructors(false), HasDestructors(false) {}
-public:
- static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
- ObjCInterfaceDecl *classInterface,
- ObjCInterfaceDecl *superDecl,
- SourceLocation nameLoc,
- SourceLocation atStartLoc,
- SourceLocation superLoc = SourceLocation(),
- SourceLocation IvarLBraceLoc=SourceLocation(),
- SourceLocation IvarRBraceLoc=SourceLocation());
-
- static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// init_iterator - Iterates through the ivar initializer list.
- typedef CXXCtorInitializer **init_iterator;
-
- /// init_const_iterator - Iterates through the ivar initializer list.
- typedef CXXCtorInitializer * const * init_const_iterator;
-
- typedef llvm::iterator_range<init_iterator> init_range;
- typedef llvm::iterator_range<init_const_iterator> init_const_range;
-
- init_range inits() { return init_range(init_begin(), init_end()); }
- init_const_range inits() const {
- return init_const_range(init_begin(), init_end());
- }
-
- /// init_begin() - Retrieve an iterator to the first initializer.
- init_iterator init_begin() {
- const auto *ConstThis = this;
- return const_cast<init_iterator>(ConstThis->init_begin());
- }
- /// begin() - Retrieve an iterator to the first initializer.
- init_const_iterator init_begin() const;
-
- /// init_end() - Retrieve an iterator past the last initializer.
- init_iterator init_end() {
- return init_begin() + NumIvarInitializers;
- }
- /// end() - Retrieve an iterator past the last initializer.
- init_const_iterator init_end() const {
- return init_begin() + NumIvarInitializers;
- }
- /// getNumArgs - Number of ivars which must be initialized.
- unsigned getNumIvarInitializers() const {
- return NumIvarInitializers;
- }
-
- void setNumIvarInitializers(unsigned numNumIvarInitializers) {
- NumIvarInitializers = numNumIvarInitializers;
- }
-
- void setIvarInitializers(ASTContext &C,
- CXXCtorInitializer ** initializers,
- unsigned numInitializers);
-
- /// Do any of the ivars of this class (not counting its base classes)
- /// require construction other than zero-initialization?
- bool hasNonZeroConstructors() const { return HasNonZeroConstructors; }
- void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; }
-
- /// Do any of the ivars of this class (not counting its base classes)
- /// require non-trivial destruction?
- bool hasDestructors() const { return HasDestructors; }
- void setHasDestructors(bool val) { HasDestructors = val; }
-
- /// getIdentifier - Get the identifier that names the class
- /// interface associated with this implementation.
- IdentifierInfo *getIdentifier() const {
- return getClassInterface()->getIdentifier();
- }
-
- /// getName - Get the name of identifier for the class interface associated
- /// with this implementation as a StringRef.
- //
- // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
- // meaning.
- StringRef getName() const {
- assert(getIdentifier() && "Name is not a simple identifier");
- return getIdentifier()->getName();
- }
-
- /// @brief Get the name of the class associated with this interface.
- //
- // FIXME: Move to StringRef API.
- std::string getNameAsString() const {
- return getName();
- }
-
- /// Produce a name to be used for class's metadata. It comes either via
- /// class's objc_runtime_name attribute or class name.
- StringRef getObjCRuntimeNameAsString() const;
-
- const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
- ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
- SourceLocation getSuperClassLoc() const { return SuperLoc; }
-
- void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
-
- void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
- SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
- void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
- SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
-
- typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
- typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
-
- ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
- ivar_iterator ivar_begin() const {
- return ivar_iterator(decls_begin());
- }
- ivar_iterator ivar_end() const {
- return ivar_iterator(decls_end());
- }
- unsigned ivar_size() const {
- return std::distance(ivar_begin(), ivar_end());
- }
- bool ivar_empty() const {
- return ivar_begin() == ivar_end();
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCImplementation; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
-
-/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
-/// declared as \@compatibility_alias alias class.
-class ObjCCompatibleAliasDecl : public NamedDecl {
- void anchor() override;
- /// Class that this is an alias of.
- ObjCInterfaceDecl *AliasedClass;
-
- ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl* aliasedClass)
- : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
-public:
- static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- ObjCInterfaceDecl* aliasedClass);
-
- static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
-
- const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
- ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
- void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
-
-};
-
-/// \brief Represents one property declaration in an Objective-C interface.
-///
-/// For example:
-/// \code{.mm}
-/// \@property (assign, readwrite) int MyProperty;
-/// \endcode
-class ObjCPropertyDecl : public NamedDecl {
- void anchor() override;
-public:
- enum PropertyAttributeKind {
- OBJC_PR_noattr = 0x00,
- OBJC_PR_readonly = 0x01,
- OBJC_PR_getter = 0x02,
- OBJC_PR_assign = 0x04,
- OBJC_PR_readwrite = 0x08,
- OBJC_PR_retain = 0x10,
- OBJC_PR_copy = 0x20,
- OBJC_PR_nonatomic = 0x40,
- OBJC_PR_setter = 0x80,
- OBJC_PR_atomic = 0x100,
- OBJC_PR_weak = 0x200,
- OBJC_PR_strong = 0x400,
- OBJC_PR_unsafe_unretained = 0x800,
- /// Indicates that the nullability of the type was spelled with a
- /// property attribute rather than a type qualifier.
- OBJC_PR_nullability = 0x1000,
- OBJC_PR_null_resettable = 0x2000
- // Adding a property should change NumPropertyAttrsBits
- };
-
- enum {
- /// \brief Number of bits fitting all the property attributes.
- NumPropertyAttrsBits = 14
- };
-
- enum SetterKind { Assign, Retain, Copy, Weak };
- enum PropertyControl { None, Required, Optional };
-private:
- SourceLocation AtLoc; // location of \@property
- SourceLocation LParenLoc; // location of '(' starting attribute list or null.
- QualType DeclType;
- TypeSourceInfo *DeclTypeSourceInfo;
- unsigned PropertyAttributes : NumPropertyAttrsBits;
- unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
- // \@required/\@optional
- unsigned PropertyImplementation : 2;
-
- Selector GetterName; // getter name of NULL if no getter
- Selector SetterName; // setter name of NULL if no setter
-
- ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
- ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
- ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
-
- ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- SourceLocation AtLocation, SourceLocation LParenLocation,
- QualType T, TypeSourceInfo *TSI,
- PropertyControl propControl)
- : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
- LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI),
- PropertyAttributes(OBJC_PR_noattr),
- PropertyAttributesAsWritten(OBJC_PR_noattr),
- PropertyImplementation(propControl),
- GetterName(Selector()),
- SetterName(Selector()),
- GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
- PropertyIvarDecl(nullptr) {}
-
-public:
- static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- IdentifierInfo *Id, SourceLocation AtLocation,
- SourceLocation LParenLocation,
- QualType T,
- TypeSourceInfo *TSI,
- PropertyControl propControl = None);
-
- static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceLocation getAtLoc() const { return AtLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
-
- TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; }
-
- QualType getType() const { return DeclType; }
-
- void setType(QualType T, TypeSourceInfo *TSI) {
- DeclType = T;
- DeclTypeSourceInfo = TSI;
- }
-
- /// Retrieve the type when this property is used with a specific base object
- /// type.
- QualType getUsageType(QualType objectType) const;
-
- PropertyAttributeKind getPropertyAttributes() const {
- return PropertyAttributeKind(PropertyAttributes);
- }
- void setPropertyAttributes(PropertyAttributeKind PRVal) {
- PropertyAttributes |= PRVal;
- }
- void overwritePropertyAttributes(unsigned PRVal) {
- PropertyAttributes = PRVal;
- }
-
- PropertyAttributeKind getPropertyAttributesAsWritten() const {
- return PropertyAttributeKind(PropertyAttributesAsWritten);
- }
-
- void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
- PropertyAttributesAsWritten = PRVal;
- }
-
- // Helper methods for accessing attributes.
-
- /// isReadOnly - Return true iff the property has a setter.
- bool isReadOnly() const {
- return (PropertyAttributes & OBJC_PR_readonly);
- }
-
- /// isAtomic - Return true if the property is atomic.
- bool isAtomic() const {
- return (PropertyAttributes & OBJC_PR_atomic);
- }
-
- /// isRetaining - Return true if the property retains its value.
- bool isRetaining() const {
- return (PropertyAttributes &
- (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
- }
-
- /// getSetterKind - Return the method used for doing assignment in
- /// the property setter. This is only valid if the property has been
- /// defined to have a setter.
- SetterKind getSetterKind() const {
- if (PropertyAttributes & OBJC_PR_strong)
- return getType()->isBlockPointerType() ? Copy : Retain;
- if (PropertyAttributes & OBJC_PR_retain)
- return Retain;
- if (PropertyAttributes & OBJC_PR_copy)
- return Copy;
- if (PropertyAttributes & OBJC_PR_weak)
- return Weak;
- return Assign;
- }
-
- Selector getGetterName() const { return GetterName; }
- void setGetterName(Selector Sel) { GetterName = Sel; }
-
- Selector getSetterName() const { return SetterName; }
- void setSetterName(Selector Sel) { SetterName = Sel; }
-
- ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
- void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
-
- ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
- void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
-
- // Related to \@optional/\@required declared in \@protocol
- void setPropertyImplementation(PropertyControl pc) {
- PropertyImplementation = pc;
- }
- PropertyControl getPropertyImplementation() const {
- return PropertyControl(PropertyImplementation);
- }
-
- void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
- PropertyIvarDecl = Ivar;
- }
- ObjCIvarDecl *getPropertyIvarDecl() const {
- return PropertyIvarDecl;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(AtLoc, getLocation());
- }
-
- /// Get the default name of the synthesized ivar.
- IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
-
- /// Lookup a property by name in the specified DeclContext.
- static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
- const IdentifierInfo *propertyID);
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ObjCProperty; }
-};
-
-/// ObjCPropertyImplDecl - Represents implementation declaration of a property
-/// in a class or category implementation block. For example:
-/// \@synthesize prop1 = ivar1;
-///
-class ObjCPropertyImplDecl : public Decl {
-public:
- enum Kind {
- Synthesize,
- Dynamic
- };
-private:
- SourceLocation AtLoc; // location of \@synthesize or \@dynamic
-
- /// \brief For \@synthesize, the location of the ivar, if it was written in
- /// the source code.
- ///
- /// \code
- /// \@synthesize int a = b
- /// \endcode
- SourceLocation IvarLoc;
-
- /// Property declaration being implemented
- ObjCPropertyDecl *PropertyDecl;
-
- /// Null for \@dynamic. Required for \@synthesize.
- ObjCIvarDecl *PropertyIvarDecl;
-
- /// Null for \@dynamic. Non-null if property must be copy-constructed in
- /// getter.
- Expr *GetterCXXConstructor;
-
- /// Null for \@dynamic. Non-null if property has assignment operator to call
- /// in Setter synthesis.
- Expr *SetterCXXAssignment;
-
- ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
- ObjCPropertyDecl *property,
- Kind PK,
- ObjCIvarDecl *ivarDecl,
- SourceLocation ivarLoc)
- : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
- IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
- GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) {
- assert (PK == Dynamic || PropertyIvarDecl);
- }
-
-public:
- static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation atLoc, SourceLocation L,
- ObjCPropertyDecl *property,
- Kind PK,
- ObjCIvarDecl *ivarDecl,
- SourceLocation ivarLoc);
-
- static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
-
- ObjCPropertyDecl *getPropertyDecl() const {
- return PropertyDecl;
- }
- void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
-
- Kind getPropertyImplementation() const {
- return PropertyIvarDecl ? Synthesize : Dynamic;
- }
-
- ObjCIvarDecl *getPropertyIvarDecl() const {
- return PropertyIvarDecl;
- }
- SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
-
- void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
- SourceLocation IvarLoc) {
- PropertyIvarDecl = Ivar;
- this->IvarLoc = IvarLoc;
- }
-
- /// \brief For \@synthesize, returns true if an ivar name was explicitly
- /// specified.
- ///
- /// \code
- /// \@synthesize int a = b; // true
- /// \@synthesize int a; // false
- /// \endcode
- bool isIvarNameSpecified() const {
- return IvarLoc.isValid() && IvarLoc != getLocation();
- }
-
- Expr *getGetterCXXConstructor() const {
- return GetterCXXConstructor;
- }
- void setGetterCXXConstructor(Expr *getterCXXConstructor) {
- GetterCXXConstructor = getterCXXConstructor;
- }
-
- Expr *getSetterCXXAssignment() const {
- return SetterCXXAssignment;
- }
- void setSetterCXXAssignment(Expr *setterCXXAssignment) {
- SetterCXXAssignment = setterCXXAssignment;
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
-
- friend class ASTDeclReader;
-};
-
-template<bool (*Filter)(ObjCCategoryDecl *)>
-void
-ObjCInterfaceDecl::filtered_category_iterator<Filter>::
-findAcceptableCategory() {
- while (Current && !Filter(Current))
- Current = Current->getNextClassCategoryRaw();
-}
-
-template<bool (*Filter)(ObjCCategoryDecl *)>
-inline ObjCInterfaceDecl::filtered_category_iterator<Filter> &
-ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
- Current = Current->getNextClassCategoryRaw();
- findAcceptableCategory();
- return *this;
-}
-
-inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
- return !Cat->isHidden();
-}
-
-inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension() && !Cat->isHidden();
-}
-
-inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension();
-}
-
-} // end namespace clang
-#endif
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
deleted file mode 100644
index 598f418..0000000
--- a/include/clang/AST/DeclOpenMP.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file defines OpenMP nodes for declarative directives.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLOPENMP_H
-#define LLVM_CLANG_AST_DECLOPENMP_H
-
-#include "clang/AST/DeclBase.h"
-#include "llvm/ADT/ArrayRef.h"
-
-namespace clang {
-class Expr;
-
-/// \brief This represents '#pragma omp threadprivate ...' directive.
-/// For example, in the following, both 'a' and 'A::b' are threadprivate:
-///
-/// \code
-/// int a;
-/// #pragma omp threadprivate(a)
-/// struct A {
-/// static int b;
-/// #pragma omp threadprivate(b)
-/// };
-/// \endcode
-///
-class OMPThreadPrivateDecl final
- : public Decl,
- private llvm::TrailingObjects<OMPThreadPrivateDecl, Expr *> {
- friend class ASTDeclReader;
- friend TrailingObjects;
-
- unsigned NumVars;
-
- virtual void anchor();
-
- OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
- Decl(DK, DC, L), NumVars(0) { }
-
- ArrayRef<const Expr *> getVars() const {
- return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
- }
-
- MutableArrayRef<Expr *> getVars() {
- return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
- }
-
- void setVars(ArrayRef<Expr *> VL);
-
-public:
- static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- ArrayRef<Expr *> VL);
- static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
- unsigned ID, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
- typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
- typedef llvm::iterator_range<varlist_iterator> varlist_range;
- typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
-
- unsigned varlist_size() const { return NumVars; }
- bool varlist_empty() const { return NumVars == 0; }
-
- varlist_range varlists() {
- return varlist_range(varlist_begin(), varlist_end());
- }
- varlist_const_range varlists() const {
- return varlist_const_range(varlist_begin(), varlist_end());
- }
- varlist_iterator varlist_begin() { return getVars().begin(); }
- varlist_iterator varlist_end() { return getVars().end(); }
- varlist_const_iterator varlist_begin() const { return getVars().begin(); }
- varlist_const_iterator varlist_end() const { return getVars().end(); }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
deleted file mode 100644
index a9109ef..0000000
--- a/include/clang/AST/DeclTemplate.h
+++ /dev/null
@@ -1,2927 +0,0 @@
-//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the C++ template declaration subclasses.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
-#define LLVM_CLANG_AST_DECLTEMPLATE_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Redeclarable.h"
-#include "clang/AST/TemplateBase.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/TrailingObjects.h"
-#include <limits>
-
-namespace clang {
-
-enum BuiltinTemplateKind : int;
-class TemplateParameterList;
-class TemplateDecl;
-class RedeclarableTemplateDecl;
-class FunctionTemplateDecl;
-class ClassTemplateDecl;
-class ClassTemplatePartialSpecializationDecl;
-class TemplateTypeParmDecl;
-class NonTypeTemplateParmDecl;
-class TemplateTemplateParmDecl;
-class TypeAliasTemplateDecl;
-class VarTemplateDecl;
-class VarTemplatePartialSpecializationDecl;
-
-/// \brief Stores a template parameter of any kind.
-typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
- TemplateTemplateParmDecl*> TemplateParameter;
-
-/// \brief Stores a list of template parameters for a TemplateDecl and its
-/// derived classes.
-class TemplateParameterList final
- : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> {
-
- /// The location of the 'template' keyword.
- SourceLocation TemplateLoc;
-
- /// The locations of the '<' and '>' angle brackets.
- SourceLocation LAngleLoc, RAngleLoc;
-
- /// The number of template parameters in this template
- /// parameter list.
- unsigned NumParams : 31;
-
- /// Whether this template parameter list contains an unexpanded parameter
- /// pack.
- unsigned ContainsUnexpandedParameterPack : 1;
-
-protected:
- size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
- return NumParams;
- }
-
- TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc);
-
-public:
- static TemplateParameterList *Create(const ASTContext &C,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params,
- SourceLocation RAngleLoc);
-
- /// \brief Iterates through the template parameters in this list.
- typedef NamedDecl** iterator;
-
- /// \brief Iterates through the template parameters in this list.
- typedef NamedDecl* const* const_iterator;
-
- iterator begin() { return getTrailingObjects<NamedDecl *>(); }
- const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
- iterator end() { return begin() + NumParams; }
- const_iterator end() const { return begin() + NumParams; }
-
- unsigned size() const { return NumParams; }
-
- ArrayRef<NamedDecl*> asArray() {
- return llvm::makeArrayRef(begin(), end());
- }
- ArrayRef<const NamedDecl*> asArray() const {
- return llvm::makeArrayRef(begin(), size());
- }
-
- NamedDecl* getParam(unsigned Idx) {
- assert(Idx < size() && "Template parameter index out-of-range");
- return begin()[Idx];
- }
-
- const NamedDecl* getParam(unsigned Idx) const {
- assert(Idx < size() && "Template parameter index out-of-range");
- return begin()[Idx];
- }
-
- /// \brief Returns the minimum number of arguments needed to form a
- /// template specialization.
- ///
- /// This may be fewer than the number of template parameters, if some of
- /// the parameters have default arguments or if there is a parameter pack.
- unsigned getMinRequiredArguments() const;
-
- /// \brief Get the depth of this template parameter list in the set of
- /// template parameter lists.
- ///
- /// The first template parameter list in a declaration will have depth 0,
- /// the second template parameter list will have depth 1, etc.
- unsigned getDepth() const;
-
- /// \brief Determine whether this template parameter list contains an
- /// unexpanded parameter pack.
- bool containsUnexpandedParameterPack() const {
- return ContainsUnexpandedParameterPack;
- }
-
- SourceLocation getTemplateLoc() const { return TemplateLoc; }
- SourceLocation getLAngleLoc() const { return LAngleLoc; }
- SourceLocation getRAngleLoc() const { return RAngleLoc; }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(TemplateLoc, RAngleLoc);
- }
-
- friend TrailingObjects;
- template <size_t N> friend class FixedSizeTemplateParameterListStorage;
-};
-
-/// \brief Stores a list of template parameters for a TemplateDecl and its
-/// derived classes. Suitable for creating on the stack.
-template <size_t N> class FixedSizeTemplateParameterListStorage {
- // This is kinda ugly: TemplateParameterList usually gets allocated
- // in a block of memory with NamedDecls appended to it. Here, to get
- // it stack allocated, we include the params as a separate
- // variable. After allocation, the TemplateParameterList object
- // treats them as part of itself.
- TemplateParameterList List;
- NamedDecl *Params[N];
-
-public:
- FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params,
- SourceLocation RAngleLoc)
- : List(TemplateLoc, LAngleLoc, Params, RAngleLoc) {
- // Because we're doing an evil layout hack above, have some
- // asserts, just to double-check everything is laid out like
- // expected.
- assert(sizeof(*this) ==
- TemplateParameterList::totalSizeToAlloc<NamedDecl *>(N) &&
- "Object layout not as expected");
- assert(this->Params == List.getTrailingObjects<NamedDecl *>() &&
- "Object layout not as expected");
- }
- TemplateParameterList *get() { return &List; }
-};
-
-/// \brief A template argument list.
-class TemplateArgumentList final
- : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
- /// \brief The template argument list.
- const TemplateArgument *Arguments;
-
- /// \brief The number of template arguments in this template
- /// argument list.
- unsigned NumArguments;
-
- TemplateArgumentList(const TemplateArgumentList &Other) = delete;
- void operator=(const TemplateArgumentList &Other) = delete;
-
- // Constructs an instance with an internal Argument list, containing
- // a copy of the Args array. (Called by CreateCopy)
- TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs);
-
-public:
- /// \brief Type used to indicate that the template argument list itself is a
- /// stack object. It does not own its template arguments.
- enum OnStackType { OnStack };
-
- /// \brief Create a new template argument list that copies the given set of
- /// template arguments.
- static TemplateArgumentList *CreateCopy(ASTContext &Context,
- const TemplateArgument *Args,
- unsigned NumArgs);
-
- /// \brief Construct a new, temporary template argument list on the stack.
- ///
- /// The template argument list does not own the template arguments
- /// provided.
- explicit TemplateArgumentList(OnStackType, const TemplateArgument *Args,
- unsigned NumArgs)
- : Arguments(Args), NumArguments(NumArgs) {}
-
- /// \brief Produces a shallow copy of the given template argument list.
- ///
- /// This operation assumes that the input argument list outlives it.
- /// This takes the list as a pointer to avoid looking like a copy
- /// constructor, since this really really isn't safe to use that
- /// way.
- explicit TemplateArgumentList(const TemplateArgumentList *Other)
- : Arguments(Other->data()), NumArguments(Other->size()) {}
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &get(unsigned Idx) const {
- assert(Idx < NumArguments && "Invalid template argument index");
- return data()[Idx];
- }
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
-
- /// \brief Produce this as an array ref.
- ArrayRef<TemplateArgument> asArray() const {
- return llvm::makeArrayRef(data(), size());
- }
-
- /// \brief Retrieve the number of template arguments in this
- /// template argument list.
- unsigned size() const { return NumArguments; }
-
- /// \brief Retrieve a pointer to the template argument list.
- const TemplateArgument *data() const { return Arguments; }
-
- friend TrailingObjects;
-};
-
-void *allocateDefaultArgStorageChain(const ASTContext &C);
-
-/// Storage for a default argument. This is conceptually either empty, or an
-/// argument value, or a pointer to a previous declaration that had a default
-/// argument.
-///
-/// However, this is complicated by modules: while we require all the default
-/// arguments for a template to be equivalent, there may be more than one, and
-/// we need to track all the originating parameters to determine if the default
-/// argument is visible.
-template<typename ParmDecl, typename ArgType>
-class DefaultArgStorage {
- /// Storage for both the value *and* another parameter from which we inherit
- /// the default argument. This is used when multiple default arguments for a
- /// parameter are merged together from different modules.
- struct Chain {
- ParmDecl *PrevDeclWithDefaultArg;
- ArgType Value;
- };
- static_assert(sizeof(Chain) == sizeof(void *) * 2,
- "non-pointer argument type?");
-
- llvm::PointerUnion3<ArgType, ParmDecl*, Chain*> ValueOrInherited;
-
- static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
- const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
- if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl*>())
- Parm = Prev;
- assert(!Parm->getDefaultArgStorage()
- .ValueOrInherited.template is<ParmDecl *>() &&
- "should only be one level of indirection");
- return Parm;
- }
-
-public:
- DefaultArgStorage() : ValueOrInherited(ArgType()) {}
-
- /// Determine whether there is a default argument for this parameter.
- bool isSet() const { return !ValueOrInherited.isNull(); }
- /// Determine whether the default argument for this parameter was inherited
- /// from a previous declaration of the same entity.
- bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
- /// Get the default argument's value. This does not consider whether the
- /// default argument is visible.
- ArgType get() const {
- const DefaultArgStorage *Storage = this;
- if (auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl*>())
- Storage = &Prev->getDefaultArgStorage();
- if (auto *C = Storage->ValueOrInherited.template dyn_cast<Chain*>())
- return C->Value;
- return Storage->ValueOrInherited.template get<ArgType>();
- }
- /// Get the parameter from which we inherit the default argument, if any.
- /// This is the parameter on which the default argument was actually written.
- const ParmDecl *getInheritedFrom() const {
- if (auto *D = ValueOrInherited.template dyn_cast<ParmDecl*>())
- return D;
- if (auto *C = ValueOrInherited.template dyn_cast<Chain*>())
- return C->PrevDeclWithDefaultArg;
- return nullptr;
- }
- /// Set the default argument.
- void set(ArgType Arg) {
- assert(!isSet() && "default argument already set");
- ValueOrInherited = Arg;
- }
- /// Set that the default argument was inherited from another parameter.
- void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
- assert(!isInherited() && "default argument already inherited");
- InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
- if (!isSet())
- ValueOrInherited = InheritedFrom;
- else
- ValueOrInherited = new (allocateDefaultArgStorageChain(C))
- Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
- }
- /// Remove the default argument, even if it was inherited.
- void clear() {
- ValueOrInherited = ArgType();
- }
-};
-
-//===----------------------------------------------------------------------===//
-// Kinds of Templates
-//===----------------------------------------------------------------------===//
-
-/// \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
-/// reference to the templated scoped declaration: the underlying AST node.
-class TemplateDecl : public NamedDecl {
- void anchor() override;
-protected:
- // This is probably never used.
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
- TemplateParams(nullptr) {}
-
- // Construct a template decl with the given name and parameters.
- // Used when there is not templated element (tt-params).
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
- TemplateParams(Params) {}
-
- // Construct a template decl with name, parameters, and templated element.
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
- TemplateParams(Params) { }
-public:
- /// Get the list of template parameters
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- /// Get the underlying, templated declaration.
- NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstTemplate && K <= lastTemplate;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(TemplateParams->getTemplateLoc(),
- TemplatedDecl->getSourceRange().getEnd());
- }
-
-protected:
- NamedDecl *TemplatedDecl;
- TemplateParameterList* TemplateParams;
-
-public:
- /// \brief Initialize the underlying templated declaration and
- /// template parameters.
- void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
- assert(!TemplatedDecl && "TemplatedDecl already set!");
- assert(!TemplateParams && "TemplateParams already set!");
- TemplatedDecl = templatedDecl;
- TemplateParams = templateParams;
- }
-};
-
-/// \brief Provides information about a function template specialization,
-/// which is a FunctionDecl that has been explicitly specialization or
-/// instantiated from a function template.
-class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
- FunctionTemplateSpecializationInfo(FunctionDecl *FD,
- FunctionTemplateDecl *Template,
- TemplateSpecializationKind TSK,
- const TemplateArgumentList *TemplateArgs,
- const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation POI)
- : Function(FD),
- Template(Template, TSK - 1),
- TemplateArguments(TemplateArgs),
- TemplateArgumentsAsWritten(TemplateArgsAsWritten),
- PointOfInstantiation(POI) { }
-
-public:
- static FunctionTemplateSpecializationInfo *
- Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
- TemplateSpecializationKind TSK,
- const TemplateArgumentList *TemplateArgs,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation POI);
-
- /// \brief The function template specialization that this structure
- /// describes.
- FunctionDecl *Function;
-
- /// \brief The function template from which this function template
- /// specialization was generated.
- ///
- /// The two bits contain the top 4 values of TemplateSpecializationKind.
- llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
-
- /// \brief The template arguments used to produce the function template
- /// specialization from the function template.
- const TemplateArgumentList *TemplateArguments;
-
- /// \brief The template arguments as written in the sources, if provided.
- const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
-
- /// \brief The point at which this function template specialization was
- /// first instantiated.
- SourceLocation PointOfInstantiation;
-
- /// \brief Retrieve the template from which this function was specialized.
- FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
-
- /// \brief Determine what kind of template specialization this is.
- TemplateSpecializationKind getTemplateSpecializationKind() const {
- return (TemplateSpecializationKind)(Template.getInt() + 1);
- }
-
- bool isExplicitSpecialization() const {
- return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief True if this declaration is an explicit specialization,
- /// explicit instantiation declaration, or explicit instantiation
- /// definition.
- bool isExplicitInstantiationOrSpecialization() const {
- return isTemplateExplicitInstantiationOrSpecialization(
- getTemplateSpecializationKind());
- }
-
- /// \brief Set the template specialization kind.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
- assert(TSK != TSK_Undeclared &&
- "Cannot encode TSK_Undeclared for a function template specialization");
- Template.setInt(TSK - 1);
- }
-
- /// \brief Retrieve the first point of instantiation of this function
- /// template specialization.
- ///
- /// The point of instantiation may be an invalid source location if this
- /// function has yet to be instantiated.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- /// \brief Set the (first) point of instantiation of this function template
- /// specialization.
- void setPointOfInstantiation(SourceLocation POI) {
- PointOfInstantiation = POI;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, TemplateArguments->asArray(),
- Function->getASTContext());
- }
-
- static void
- Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
- ID.AddInteger(TemplateArgs.size());
- for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
- TemplateArgs[Arg].Profile(ID, Context);
- }
-};
-
-/// \brief Provides information a specialization of a member of a class
-/// template, which may be a member function, static data member,
-/// member class or member enumeration.
-class MemberSpecializationInfo {
- // The member declaration from which this member was instantiated, and the
- // manner in which the instantiation occurred (in the lower two bits).
- llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
-
- // The point at which this member was first instantiated.
- SourceLocation PointOfInstantiation;
-
-public:
- explicit
- MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
- SourceLocation POI = SourceLocation())
- : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
- assert(TSK != TSK_Undeclared &&
- "Cannot encode undeclared template specializations for members");
- }
-
- /// \brief Retrieve the member declaration from which this member was
- /// instantiated.
- NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
-
- /// \brief Determine what kind of template specialization this is.
- TemplateSpecializationKind getTemplateSpecializationKind() const {
- return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
- }
-
- bool isExplicitSpecialization() const {
- return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief Set the template specialization kind.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
- assert(TSK != TSK_Undeclared &&
- "Cannot encode undeclared template specializations for members");
- MemberAndTSK.setInt(TSK - 1);
- }
-
- /// \brief Retrieve the first point of instantiation of this member.
- /// If the point of instantiation is an invalid location, then this member
- /// has not yet been instantiated.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- /// \brief Set the first point of instantiation.
- void setPointOfInstantiation(SourceLocation POI) {
- PointOfInstantiation = POI;
- }
-};
-
-/// \brief Provides information about a dependent function-template
-/// specialization declaration.
-///
-/// Since explicit function template specialization and instantiation
-/// declarations can only appear in namespace scope, and you can only
-/// specialize a member of a fully-specialized class, the only way to
-/// get one of these is in a friend declaration like the following:
-///
-/// \code
-/// template \<class T> void foo(T);
-/// template \<class T> class A {
-/// friend void foo<>(T);
-/// };
-/// \endcode
-class DependentFunctionTemplateSpecializationInfo final
- : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
- TemplateArgumentLoc,
- FunctionTemplateDecl *> {
- /// The number of potential template candidates.
- unsigned NumTemplates;
-
- /// The number of template arguments.
- unsigned NumArgs;
-
- /// The locations of the left and right angle brackets.
- SourceRange AngleLocs;
-
- size_t numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
- return NumArgs;
- }
- size_t numTrailingObjects(OverloadToken<FunctionTemplateDecl *>) const {
- return NumTemplates;
- }
-
- DependentFunctionTemplateSpecializationInfo(
- const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
-
-public:
- static DependentFunctionTemplateSpecializationInfo *
- Create(ASTContext &Context, const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
-
- /// \brief Returns the number of function templates that this might
- /// be a specialization of.
- unsigned getNumTemplates() const { return NumTemplates; }
-
- /// \brief Returns the i'th template candidate.
- FunctionTemplateDecl *getTemplate(unsigned I) const {
- assert(I < getNumTemplates() && "template index out of range");
- return getTrailingObjects<FunctionTemplateDecl *>()[I];
- }
-
- /// \brief Returns the explicit template arguments that were given.
- const TemplateArgumentLoc *getTemplateArgs() const {
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Returns the number of explicit template arguments that were given.
- unsigned getNumTemplateArgs() const { return NumArgs; }
-
- /// \brief Returns the nth template argument.
- const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
- assert(I < getNumTemplateArgs() && "template arg index out of range");
- return getTemplateArgs()[I];
- }
-
- SourceLocation getLAngleLoc() const {
- return AngleLocs.getBegin();
- }
-
- SourceLocation getRAngleLoc() const {
- return AngleLocs.getEnd();
- }
-
- friend TrailingObjects;
-};
-
-/// Declaration of a redeclarable template.
-class RedeclarableTemplateDecl : public TemplateDecl,
- public Redeclarable<RedeclarableTemplateDecl>
-{
- typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
- RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- RedeclarableTemplateDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-protected:
- template <typename EntryType> struct SpecEntryTraits {
- typedef EntryType DeclType;
-
- static DeclType *getDecl(EntryType *D) {
- return D;
- }
- static ArrayRef<TemplateArgument> getTemplateArgs(EntryType *D) {
- return D->getTemplateArgs().asArray();
- }
- };
-
- template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
- typename DeclType = typename SETraits::DeclType>
- struct SpecIterator
- : llvm::iterator_adaptor_base<
- SpecIterator<EntryType, SETraits, DeclType>,
- typename llvm::FoldingSetVector<EntryType>::iterator,
- typename std::iterator_traits<typename llvm::FoldingSetVector<
- EntryType>::iterator>::iterator_category,
- DeclType *, ptrdiff_t, DeclType *, DeclType *> {
- SpecIterator() {}
- explicit SpecIterator(
- typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
- : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
-
- DeclType *operator*() const {
- return SETraits::getDecl(&*this->I)->getMostRecentDecl();
- }
- DeclType *operator->() const { return **this; }
- };
-
- template <typename EntryType>
- static SpecIterator<EntryType>
- makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
- return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
- }
-
- template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
- findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
- ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- template <class Derived, class EntryType>
- void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
- EntryType *Entry, void *InsertPos);
-
- struct CommonBase {
- CommonBase() : InstantiatedFromMember(nullptr, false) { }
-
- /// \brief The template from which this was most
- /// directly instantiated (or null).
- ///
- /// The boolean value indicates whether this template
- /// was explicitly specialized.
- llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
- InstantiatedFromMember;
- };
-
- /// \brief Pointer to the common data shared by all declarations of this
- /// template.
- mutable CommonBase *Common;
-
- /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
- /// the same template. Calling this routine may implicitly allocate memory
- /// for the common pointer.
- CommonBase *getCommonPtr() const;
-
- virtual CommonBase *newCommon(ASTContext &C) const = 0;
-
- // Construct a template decl with name, parameters, and templated element.
- RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
- Common() {}
-
-public:
- template <class decl_type> friend class RedeclarableTemplate;
-
- /// \brief Retrieves the canonical declaration of this template.
- RedeclarableTemplateDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const RedeclarableTemplateDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- /// \brief Determines whether this template was a specialization of a
- /// member template.
- ///
- /// In the following example, the function template \c X<int>::f and the
- /// member template \c X<int>::Inner are member specializations.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> void f(T, U);
- /// template<typename U> struct Inner;
- /// };
- ///
- /// template<> template<typename T>
- /// void X<int>::f(int, T);
- /// template<> template<typename T>
- /// struct X<int>::Inner { /* ... */ };
- /// \endcode
- bool isMemberSpecialization() const {
- return getCommonPtr()->InstantiatedFromMember.getInt();
- }
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- getCommonPtr()->InstantiatedFromMember.setInt(true);
- }
-
- /// \brief Retrieve the member template from which this template was
- /// instantiated, or NULL if this template was not instantiated from a
- /// member template.
- ///
- /// A template is instantiated from a member template when the member
- /// template itself is part of a class template (or member thereof). For
- /// example, given
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> void f(T, U);
- /// };
- ///
- /// void test(X<int> x) {
- /// x.f(1, 'a');
- /// };
- /// \endcode
- ///
- /// \c X<int>::f is a FunctionTemplateDecl that describes the function
- /// template
- ///
- /// \code
- /// template<typename U> void X<int>::f(int, U);
- /// \endcode
- ///
- /// which was itself created during the instantiation of \c X<int>. Calling
- /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
- /// retrieve the FunctionTemplateDecl for the original template \c f within
- /// the class template \c X<T>, i.e.,
- ///
- /// \code
- /// template<typename T>
- /// template<typename U>
- /// void X<T>::f(T, U);
- /// \endcode
- RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return getCommonPtr()->InstantiatedFromMember.getPointer();
- }
-
- void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
- assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
- getCommonPtr()->InstantiatedFromMember.setPointer(TD);
- }
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
- }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-template <> struct RedeclarableTemplateDecl::
-SpecEntryTraits<FunctionTemplateSpecializationInfo> {
- typedef FunctionDecl DeclType;
-
- static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) {
- return I->Function;
- }
- static ArrayRef<TemplateArgument>
- getTemplateArgs(FunctionTemplateSpecializationInfo *I) {
- return I->TemplateArguments->asArray();
- }
-};
-
-/// Declaration of a template function.
-class FunctionTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// function template.
- struct Common : CommonBase {
- Common() : InjectedArgs(), LazySpecializations() { }
-
- /// \brief The function template specializations for this function
- /// template, including explicit specializations and instantiations.
- llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
-
- /// \brief The set of "injected" template arguments used within this
- /// function template.
- ///
- /// This pointer refers to the template arguments (there are as
- /// many template arguments as template parameaters) for the function
- /// template, and is allocated lazily, since most function templates do not
- /// require the use of this information.
- TemplateArgument *InjectedArgs;
-
- /// \brief If non-null, points to an array of specializations known only
- /// by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations
- /// that follow.
- uint32_t *LazySpecializations;
- };
-
- FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
- Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() const {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
- friend class FunctionDecl;
-
- /// \brief Retrieve the set of function template specializations of this
- /// function template.
- llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
- getSpecializations() const;
-
- /// \brief Add a specialization of this function template.
- ///
- /// \param InsertPos Insert position in the FoldingSetVector, must have been
- /// retrieved by an earlier call to findSpecialization().
- void addSpecialization(FunctionTemplateSpecializationInfo* Info,
- void *InsertPos);
-
-public:
- /// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
-
- /// Get the underlying function declaration of the template.
- FunctionDecl *getTemplatedDecl() const {
- return static_cast<FunctionDecl*>(TemplatedDecl);
- }
-
- /// Returns whether this template declaration defines the primary
- /// pattern.
- bool isThisDeclarationADefinition() const {
- return getTemplatedDecl()->isThisDeclarationADefinition();
- }
-
- /// \brief Return the specialization with the provided arguments if it exists,
- /// otherwise return the insertion point.
- FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
- void *&InsertPos);
-
- FunctionTemplateDecl *getCanonicalDecl() override {
- return cast<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const FunctionTemplateDecl *getCanonicalDecl() const {
- return cast<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- FunctionTemplateDecl *getPreviousDecl() {
- return cast_or_null<FunctionTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- const FunctionTemplateDecl *getPreviousDecl() const {
- return cast_or_null<FunctionTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- FunctionTemplateDecl *getMostRecentDecl() {
- return cast<FunctionTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)
- ->getMostRecentDecl());
- }
- const FunctionTemplateDecl *getMostRecentDecl() const {
- return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
- }
-
- FunctionTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
- typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
-
- spec_range specializations() const {
- return spec_range(spec_begin(), spec_end());
- }
- spec_iterator spec_begin() const {
- return makeSpecIterator(getSpecializations(), false);
- }
-
- spec_iterator spec_end() const {
- return makeSpecIterator(getSpecializations(), true);
- }
-
- /// \brief Retrieve the "injected" template arguments that correspond to the
- /// template parameters of this function template.
- ///
- /// Although the C++ standard has no notion of the "injected" template
- /// arguments for a function template, the notion is convenient when
- /// we need to perform substitutions inside the definition of a function
- /// template.
- ArrayRef<TemplateArgument> getInjectedTemplateArgs();
-
- /// \brief Create a function template node.
- static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl);
-
- /// \brief Create an empty function template node.
- static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == FunctionTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-//===----------------------------------------------------------------------===//
-// Kinds of Template Parameters
-//===----------------------------------------------------------------------===//
-
-/// \brief Defines the position of a template parameter within a template
-/// parameter list.
-///
-/// Because template parameter can be listed
-/// sequentially for out-of-line template members, each template parameter is
-/// given a Depth - the nesting of template parameter scopes - and a Position -
-/// the occurrence within the parameter list.
-/// This class is inheritedly privately by different kinds of template
-/// parameters and is not part of the Decl hierarchy. Just a facility.
-class TemplateParmPosition {
- TemplateParmPosition() = delete;
-
-protected:
- TemplateParmPosition(unsigned D, unsigned P)
- : Depth(D), Position(P)
- { }
-
- // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
- // position? Maybe?
- unsigned Depth;
- unsigned Position;
-
-public:
- /// Get the nesting depth of the template parameter.
- unsigned getDepth() const { return Depth; }
- void setDepth(unsigned D) { Depth = D; }
-
- /// Get the position of the template parameter within its parameter list.
- unsigned getPosition() const { return Position; }
- void setPosition(unsigned P) { Position = P; }
-
- /// Get the index of the template parameter within its parameter list.
- unsigned getIndex() const { return Position; }
-};
-
-/// \brief Declaration of a template type parameter.
-///
-/// For example, "T" in
-/// \code
-/// template<typename T> class vector;
-/// \endcode
-class TemplateTypeParmDecl : public TypeDecl {
- /// \brief Whether this template type parameter was declaration with
- /// the 'typename' keyword.
- ///
- /// If false, it was declared with the 'class' keyword.
- bool Typename : 1;
-
- /// \brief The default template argument, if any.
- typedef DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>
- DefArgStorage;
- DefArgStorage DefaultArgument;
-
- TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- bool Typename)
- : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
- DefaultArgument() { }
-
- /// Sema creates these on the stack during auto type deduction.
- friend class Sema;
-
-public:
- static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation KeyLoc,
- SourceLocation NameLoc,
- unsigned D, unsigned P,
- IdentifierInfo *Id, bool Typename,
- bool ParameterPack);
- static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
- unsigned ID);
-
- /// \brief Whether this template type parameter was declared with
- /// the 'typename' keyword.
- ///
- /// If not, it was declared with the 'class' keyword.
- bool wasDeclaredWithTypename() const { return Typename; }
-
- const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
-
- /// \brief Determine whether this template parameter has a default
- /// argument.
- bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
-
- /// \brief Retrieve the default argument, if any.
- QualType getDefaultArgument() const {
- return DefaultArgument.get()->getType();
- }
-
- /// \brief Retrieves the default argument's source information, if any.
- TypeSourceInfo *getDefaultArgumentInfo() const {
- return DefaultArgument.get();
- }
-
- /// \brief Retrieves the location of the default argument declaration.
- SourceLocation getDefaultArgumentLoc() const;
-
- /// \brief Determines whether the default argument was inherited
- /// from a previous declaration of this template.
- bool defaultArgumentWasInherited() const {
- return DefaultArgument.isInherited();
- }
-
- /// \brief Set the default argument for this template parameter.
- void setDefaultArgument(TypeSourceInfo *DefArg) {
- DefaultArgument.set(DefArg);
- }
- /// \brief Set that this default argument was inherited from another
- /// parameter.
- void setInheritedDefaultArgument(const ASTContext &C,
- TemplateTypeParmDecl *Prev) {
- DefaultArgument.setInherited(C, Prev);
- }
-
- /// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() {
- DefaultArgument.clear();
- }
-
- /// \brief Set whether this template type parameter was declared with
- /// the 'typename' or 'class' keyword.
- void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
-
- /// \brief Retrieve the depth of the template parameter.
- unsigned getDepth() const;
-
- /// \brief Retrieve the index of the template parameter.
- unsigned getIndex() const;
-
- /// \brief Returns whether this is a parameter pack.
- bool isParameterPack() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TemplateTypeParm; }
-};
-
-/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
-/// e.g., "Size" in
-/// @code
-/// template<int Size> class array { };
-/// @endcode
-class NonTypeTemplateParmDecl final
- : public DeclaratorDecl,
- protected TemplateParmPosition,
- private llvm::TrailingObjects<NonTypeTemplateParmDecl,
- std::pair<QualType, TypeSourceInfo *>> {
- /// \brief The default template argument, if any, and whether or not
- /// it was inherited.
- typedef DefaultArgStorage<NonTypeTemplateParmDecl, Expr*> DefArgStorage;
- DefArgStorage DefaultArgument;
-
- // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
- // down here to save memory.
-
- /// \brief Whether this non-type template parameter is a parameter pack.
- bool ParameterPack;
-
- /// \brief Whether this non-type template parameter is an "expanded"
- /// parameter pack, meaning that its type is a pack expansion and we
- /// already know the set of types that expansion expands to.
- bool ExpandedParameterPack;
-
- /// \brief The number of types in an expanded parameter pack.
- unsigned NumExpandedTypes;
-
- size_t numTrailingObjects(
- OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
- return NumExpandedTypes;
- }
-
- NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P,
- IdentifierInfo *Id, QualType T,
- bool ParameterPack, TypeSourceInfo *TInfo)
- : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
- TemplateParmPosition(D, P), ParameterPack(ParameterPack),
- ExpandedParameterPack(false), NumExpandedTypes(0)
- { }
-
- NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P,
- IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo,
- const QualType *ExpandedTypes,
- unsigned NumExpandedTypes,
- TypeSourceInfo **ExpandedTInfos);
-
- friend class ASTDeclReader;
- friend TrailingObjects;
-
-public:
- static NonTypeTemplateParmDecl *
- Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
- QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
-
- static NonTypeTemplateParmDecl *
- Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo,
- const QualType *ExpandedTypes, unsigned NumExpandedTypes,
- TypeSourceInfo **ExpandedTInfos);
-
- static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
- static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID,
- unsigned NumExpandedTypes);
-
- using TemplateParmPosition::getDepth;
- using TemplateParmPosition::setDepth;
- using TemplateParmPosition::getPosition;
- using TemplateParmPosition::setPosition;
- using TemplateParmPosition::getIndex;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
-
- /// \brief Determine whether this template parameter has a default
- /// argument.
- bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
-
- /// \brief Retrieve the default argument, if any.
- Expr *getDefaultArgument() const { return DefaultArgument.get(); }
-
- /// \brief Retrieve the location of the default argument, if any.
- SourceLocation getDefaultArgumentLoc() const;
-
- /// \brief Determines whether the default argument was inherited
- /// from a previous declaration of this template.
- bool defaultArgumentWasInherited() const {
- return DefaultArgument.isInherited();
- }
-
- /// \brief Set the default argument for this template parameter, and
- /// whether that default argument was inherited from another
- /// declaration.
- void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
- void setInheritedDefaultArgument(const ASTContext &C,
- NonTypeTemplateParmDecl *Parm) {
- DefaultArgument.setInherited(C, Parm);
- }
-
- /// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() { DefaultArgument.clear(); }
-
- /// \brief Whether this parameter is a non-type template parameter pack.
- ///
- /// If the parameter is a parameter pack, the type may be a
- /// \c PackExpansionType. In the following example, the \c Dims parameter
- /// is a parameter pack (whose type is 'unsigned').
- ///
- /// \code
- /// template<typename T, unsigned ...Dims> struct multi_array;
- /// \endcode
- bool isParameterPack() const { return ParameterPack; }
-
- /// \brief Whether this parameter pack is a pack expansion.
- ///
- /// A non-type template parameter pack is a pack expansion if its type
- /// contains an unexpanded parameter pack. In this case, we will have
- /// built a PackExpansionType wrapping the type.
- bool isPackExpansion() const {
- return ParameterPack && getType()->getAs<PackExpansionType>();
- }
-
- /// \brief Whether this parameter is a non-type template parameter pack
- /// that has a known list of different types at different positions.
- ///
- /// A parameter pack is an expanded parameter pack when the original
- /// parameter pack's type was itself a pack expansion, and that expansion
- /// has already been expanded. For example, given:
- ///
- /// \code
- /// template<typename ...Types>
- /// struct X {
- /// template<Types ...Values>
- /// struct Y { /* ... */ };
- /// };
- /// \endcode
- ///
- /// The parameter pack \c Values has a \c PackExpansionType as its type,
- /// which expands \c Types. When \c Types is supplied with template arguments
- /// by instantiating \c X, the instantiation of \c Values becomes an
- /// expanded parameter pack. For example, instantiating
- /// \c X<int, unsigned int> results in \c Values being an expanded parameter
- /// pack with expansion types \c int and \c unsigned int.
- ///
- /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
- /// return the expansion types.
- bool isExpandedParameterPack() const { return ExpandedParameterPack; }
-
- /// \brief Retrieves the number of expansion types in an expanded parameter
- /// pack.
- unsigned getNumExpansionTypes() const {
- assert(ExpandedParameterPack && "Not an expansion parameter pack");
- return NumExpandedTypes;
- }
-
- /// \brief Retrieve a particular expansion type within an expanded parameter
- /// pack.
- QualType getExpansionType(unsigned I) const {
- assert(I < NumExpandedTypes && "Out-of-range expansion type index");
- auto TypesAndInfos =
- getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
- return TypesAndInfos[I].first;
- }
-
- /// \brief Retrieve a particular expansion type source info within an
- /// expanded parameter pack.
- TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
- assert(I < NumExpandedTypes && "Out-of-range expansion type index");
- auto TypesAndInfos =
- getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
- return TypesAndInfos[I].second;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
-};
-
-/// TemplateTemplateParmDecl - Declares a template template parameter,
-/// e.g., "T" in
-/// @code
-/// template <template <typename> class T> class container { };
-/// @endcode
-/// A template template parameter is a TemplateDecl because it defines the
-/// name of a template and the template parameters allowable for substitution.
-class TemplateTemplateParmDecl final
- : public TemplateDecl,
- protected TemplateParmPosition,
- private llvm::TrailingObjects<TemplateTemplateParmDecl,
- TemplateParameterList *> {
- void anchor() override;
-
- /// \brief The default template argument, if any.
- typedef DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>
- DefArgStorage;
- DefArgStorage DefaultArgument;
-
- /// \brief Whether this parameter is a parameter pack.
- bool ParameterPack;
-
- /// \brief Whether this template template parameter is an "expanded"
- /// parameter pack, meaning that it is a pack expansion and we
- /// already know the set of template parameters that expansion expands to.
- bool ExpandedParameterPack;
-
- /// \brief The number of parameters in an expanded parameter pack.
- unsigned NumExpandedParams;
-
- TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
- unsigned D, unsigned P, bool ParameterPack,
- IdentifierInfo *Id, TemplateParameterList *Params)
- : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
- TemplateParmPosition(D, P), ParameterPack(ParameterPack),
- ExpandedParameterPack(false), NumExpandedParams(0)
- { }
-
- TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
- unsigned D, unsigned P,
- IdentifierInfo *Id, TemplateParameterList *Params,
- unsigned NumExpansions,
- TemplateParameterList * const *Expansions);
-
-public:
- static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation L, unsigned D,
- unsigned P, bool ParameterPack,
- IdentifierInfo *Id,
- TemplateParameterList *Params);
- static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation L, unsigned D,
- unsigned P,
- IdentifierInfo *Id,
- TemplateParameterList *Params,
- ArrayRef<TemplateParameterList *> Expansions);
-
- static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
- static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID,
- unsigned NumExpansions);
-
- using TemplateParmPosition::getDepth;
- using TemplateParmPosition::getPosition;
- using TemplateParmPosition::getIndex;
-
- /// \brief Whether this template template parameter is a template
- /// parameter pack.
- ///
- /// \code
- /// template<template <class T> ...MetaFunctions> struct Apply;
- /// \endcode
- bool isParameterPack() const { return ParameterPack; }
-
- /// \brief Whether this parameter pack is a pack expansion.
- ///
- /// A template template parameter pack is a pack expansion if its template
- /// parameter list contains an unexpanded parameter pack.
- bool isPackExpansion() const {
- return ParameterPack &&
- getTemplateParameters()->containsUnexpandedParameterPack();
- }
-
- /// \brief Whether this parameter is a template template parameter pack that
- /// has a known list of different template parameter lists at different
- /// positions.
- ///
- /// A parameter pack is an expanded parameter pack when the original parameter
- /// pack's template parameter list was itself a pack expansion, and that
- /// expansion has already been expanded. For exampe, given:
- ///
- /// \code
- /// template<typename...Types> struct Outer {
- /// template<template<Types> class...Templates> struct Inner;
- /// };
- /// \endcode
- ///
- /// The parameter pack \c Templates is a pack expansion, which expands the
- /// pack \c Types. When \c Types is supplied with template arguments by
- /// instantiating \c Outer, the instantiation of \c Templates is an expanded
- /// parameter pack.
- bool isExpandedParameterPack() const { return ExpandedParameterPack; }
-
- /// \brief Retrieves the number of expansion template parameters in
- /// an expanded parameter pack.
- unsigned getNumExpansionTemplateParameters() const {
- assert(ExpandedParameterPack && "Not an expansion parameter pack");
- return NumExpandedParams;
- }
-
- /// \brief Retrieve a particular expansion type within an expanded parameter
- /// pack.
- TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
- assert(I < NumExpandedParams && "Out-of-range expansion type index");
- return getTrailingObjects<TemplateParameterList *>()[I];
- }
-
- const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
-
- /// \brief Determine whether this template parameter has a default
- /// argument.
- bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
-
- /// \brief Retrieve the default argument, if any.
- const TemplateArgumentLoc &getDefaultArgument() const {
- static const TemplateArgumentLoc None;
- return DefaultArgument.isSet() ? *DefaultArgument.get() : None;
- }
-
- /// \brief Retrieve the location of the default argument, if any.
- SourceLocation getDefaultArgumentLoc() const;
-
- /// \brief Determines whether the default argument was inherited
- /// from a previous declaration of this template.
- bool defaultArgumentWasInherited() const {
- return DefaultArgument.isInherited();
- }
-
- /// \brief Set the default argument for this template parameter, and
- /// whether that default argument was inherited from another
- /// declaration.
- void setDefaultArgument(const ASTContext &C,
- const TemplateArgumentLoc &DefArg);
- void setInheritedDefaultArgument(const ASTContext &C,
- TemplateTemplateParmDecl *Prev) {
- DefaultArgument.setInherited(C, Prev);
- }
-
- /// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() { DefaultArgument.clear(); }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- SourceLocation End = getLocation();
- if (hasDefaultArgument() && !defaultArgumentWasInherited())
- End = getDefaultArgument().getSourceRange().getEnd();
- return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
-};
-
-/// \brief Represents the builtin template declaration which is used to
-/// implement __make_integer_seq. It serves no real purpose beyond existing as
-/// a place to hold template parameters.
-class BuiltinTemplateDecl : public TemplateDecl {
- void anchor() override;
-
- BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
- DeclarationName Name, BuiltinTemplateKind BTK);
-
- BuiltinTemplateKind BTK;
-
-public:
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == BuiltinTemplate; }
-
- static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
- DeclarationName Name,
- BuiltinTemplateKind BTK) {
- return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange();
- }
-
- BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
-};
-
-/// \brief Represents a class template specialization, which refers to
-/// a class template with a given set of template arguments.
-///
-/// Class template specializations represent both explicit
-/// specialization of class templates, as in the example below, and
-/// implicit instantiations of class templates.
-///
-/// \code
-/// template<typename T> class array;
-///
-/// template<>
-/// class array<bool> { }; // class template specialization array<bool>
-/// \endcode
-class ClassTemplateSpecializationDecl
- : public CXXRecordDecl, public llvm::FoldingSetNode {
-
- /// \brief Structure that stores information about a class template
- /// specialization that was instantiated from a class template partial
- /// specialization.
- struct SpecializedPartialSpecialization {
- /// \brief The class template partial specialization from which this
- /// class template specialization was instantiated.
- ClassTemplatePartialSpecializationDecl *PartialSpecialization;
-
- /// \brief The template argument list deduced for the class template
- /// partial specialization itself.
- const TemplateArgumentList *TemplateArgs;
- };
-
- /// \brief The template that this specialization specializes
- llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
- SpecializedTemplate;
-
- /// \brief Further info for explicit template specialization/instantiation.
- struct ExplicitSpecializationInfo {
- /// \brief The type-as-written.
- TypeSourceInfo *TypeAsWritten;
- /// \brief The location of the extern keyword.
- SourceLocation ExternLoc;
- /// \brief The location of the template keyword.
- SourceLocation TemplateKeywordLoc;
-
- ExplicitSpecializationInfo()
- : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
- };
-
- /// \brief Further info for explicit template specialization/instantiation.
- /// Does not apply to implicit specializations.
- ExplicitSpecializationInfo *ExplicitInfo;
-
- /// \brief The template arguments used to describe this specialization.
- const TemplateArgumentList *TemplateArgs;
-
- /// \brief The point where this template was instantiated (if any)
- SourceLocation PointOfInstantiation;
-
- /// \brief The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
- unsigned SpecializationKind : 3;
-
-protected:
- ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
- DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- ClassTemplateSpecializationDecl *PrevDecl);
-
- explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
-
-public:
- static ClassTemplateSpecializationDecl *
- Create(ASTContext &Context, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- ClassTemplateSpecializationDecl *PrevDecl);
- static ClassTemplateSpecializationDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
- bool Qualified) const override;
-
- // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
- // different "most recent" declaration from this function for the same
- // declaration, because we don't override getMostRecentDeclImpl(). But
- // it's not clear that we should override that, because the most recent
- // declaration as a CXXRecordDecl sometimes is the injected-class-name.
- ClassTemplateSpecializationDecl *getMostRecentDecl() {
- CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
- this)->getMostRecentDecl();
- while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
- // FIXME: Does injected class name need to be in the redeclarations chain?
- assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
- Recent = Recent->getPreviousDecl();
- }
- return cast<ClassTemplateSpecializationDecl>(Recent);
- }
-
- /// \brief Retrieve the template that this specialization specializes.
- ClassTemplateDecl *getSpecializedTemplate() const;
-
- /// \brief Retrieve the template arguments of the class template
- /// specialization.
- const TemplateArgumentList &getTemplateArgs() const {
- return *TemplateArgs;
- }
-
- /// \brief Determine the kind of specialization that this
- /// declaration represents.
- TemplateSpecializationKind getSpecializationKind() const {
- return static_cast<TemplateSpecializationKind>(SpecializationKind);
- }
-
- bool isExplicitSpecialization() const {
- return getSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief True if this declaration is an explicit specialization,
- /// explicit instantiation declaration, or explicit instantiation
- /// definition.
- bool isExplicitInstantiationOrSpecialization() const {
- return isTemplateExplicitInstantiationOrSpecialization(
- getTemplateSpecializationKind());
- }
-
- void setSpecializationKind(TemplateSpecializationKind TSK) {
- SpecializationKind = TSK;
- }
-
- /// \brief Get the point of instantiation (if any), or null if none.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- void setPointOfInstantiation(SourceLocation Loc) {
- assert(Loc.isValid() && "point of instantiation must be valid!");
- PointOfInstantiation = Loc;
- }
-
- /// \brief If this class template specialization is an instantiation of
- /// a template (rather than an explicit specialization), return the
- /// class template or class template partial specialization from which it
- /// was instantiated.
- llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *>
- getInstantiatedFrom() const {
- if (!isTemplateInstantiation(getSpecializationKind()))
- return llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *>();
-
- return getSpecializedTemplateOrPartial();
- }
-
- /// \brief Retrieve the class template or class template partial
- /// specialization which was specialized by this.
- llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *>
- getSpecializedTemplateOrPartial() const {
- if (SpecializedPartialSpecialization *PartialSpec
- = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<ClassTemplateDecl*>();
- }
-
- /// \brief Retrieve the set of template arguments that should be used
- /// to instantiate members of the class template or class template partial
- /// specialization from which this class template specialization was
- /// instantiated.
- ///
- /// \returns For a class template specialization instantiated from the primary
- /// template, this function will return the same template arguments as
- /// getTemplateArgs(). For a class template specialization instantiated from
- /// a class template partial specialization, this function will return the
- /// deduced template arguments for the class template partial specialization
- /// itself.
- const TemplateArgumentList &getTemplateInstantiationArgs() const {
- if (SpecializedPartialSpecialization *PartialSpec
- = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
- return *PartialSpec->TemplateArgs;
-
- return getTemplateArgs();
- }
-
- /// \brief Note that this class template specialization is actually an
- /// instantiation of the given class template partial specialization whose
- /// template arguments have been deduced.
- void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
- const TemplateArgumentList *TemplateArgs) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
- "Already set to a class template partial specialization!");
- SpecializedPartialSpecialization *PS
- = new (getASTContext()) SpecializedPartialSpecialization();
- PS->PartialSpecialization = PartialSpec;
- PS->TemplateArgs = TemplateArgs;
- SpecializedTemplate = PS;
- }
-
- /// \brief Note that this class template specialization is an instantiation
- /// of the given class template.
- void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
- "Previously set to a class template partial specialization!");
- SpecializedTemplate = TemplDecl;
- }
-
- /// \brief Sets the type of this specialization as it was written by
- /// the user. This will be a class template specialization type.
- void setTypeAsWritten(TypeSourceInfo *T) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = T;
- }
- /// \brief Gets the type of this specialization as it was written by
- /// the user, if it was so written.
- TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
- }
-
- /// \brief Gets the location of the extern keyword, if present.
- SourceLocation getExternLoc() const {
- return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
- }
- /// \brief Sets the location of the extern keyword.
- void setExternLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->ExternLoc = Loc;
- }
-
- /// \brief Sets the location of the template keyword.
- void setTemplateKeywordLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TemplateKeywordLoc = Loc;
- }
- /// \brief Gets the location of the template keyword, if present.
- SourceLocation getTemplateKeywordLoc() const {
- return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs->asArray(), getASTContext());
- }
-
- static void
- Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
- ID.AddInteger(TemplateArgs.size());
- for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
- TemplateArgs[Arg].Profile(ID, Context);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstClassTemplateSpecialization &&
- K <= lastClassTemplateSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-class ClassTemplatePartialSpecializationDecl
- : public ClassTemplateSpecializationDecl {
- void anchor() override;
-
- /// \brief The list of template parameters
- TemplateParameterList* TemplateParams;
-
- /// \brief The source info for the template arguments as written.
- /// FIXME: redundant with TypeAsWritten?
- const ASTTemplateArgumentListInfo *ArgsAsWritten;
-
- /// \brief The class template partial specialization from which this
- /// class template partial specialization was instantiated.
- ///
- /// The boolean value will be true to indicate that this class template
- /// partial specialization was specialized at this level.
- llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
- InstantiatedFromMember;
-
- ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
- DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc,
- TemplateParameterList *Params,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ClassTemplatePartialSpecializationDecl *PrevDecl);
-
- ClassTemplatePartialSpecializationDecl(ASTContext &C)
- : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
- TemplateParams(nullptr), ArgsAsWritten(nullptr),
- InstantiatedFromMember(nullptr, false) {}
-
-public:
- static ClassTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- TemplateParameterList *Params,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const TemplateArgumentListInfo &ArgInfos,
- QualType CanonInjectedType,
- ClassTemplatePartialSpecializationDecl *PrevDecl);
-
- static ClassTemplatePartialSpecializationDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
- return cast<ClassTemplatePartialSpecializationDecl>(
- static_cast<ClassTemplateSpecializationDecl *>(
- this)->getMostRecentDecl());
- }
-
- /// Get the list of template parameters
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- /// Get the template arguments as written.
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return ArgsAsWritten;
- }
-
- /// \brief Retrieve the member class template partial specialization from
- /// which this particular class template partial specialization was
- /// instantiated.
- ///
- /// \code
- /// template<typename T>
- /// struct Outer {
- /// template<typename U> struct Inner;
- /// template<typename U> struct Inner<U*> { }; // #1
- /// };
- ///
- /// Outer<float>::Inner<int*> ii;
- /// \endcode
- ///
- /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
- /// end up instantiating the partial specialization
- /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
- /// template partial specialization \c Outer<T>::Inner<U*>. Given
- /// \c Outer<float>::Inner<U*>, this function would return
- /// \c Outer<T>::Inner<U*>.
- ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
- const ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getPointer();
- }
-
- void setInstantiatedFromMember(
- ClassTemplatePartialSpecializationDecl *PartialSpec) {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- First->InstantiatedFromMember.setPointer(PartialSpec);
- }
-
- /// \brief Determines whether this class template partial specialization
- /// template was a specialization of a member partial specialization.
- ///
- /// In the following example, the member template partial specialization
- /// \c X<int>::Inner<T*> is a member specialization.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> struct Inner;
- /// template<typename U> struct Inner<U*>;
- /// };
- ///
- /// template<> template<typename T>
- /// struct X<int>::Inner<T*> { /* ... */ };
- /// \endcode
- bool isMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getInt();
- }
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- assert(First->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- return First->InstantiatedFromMember.setInt(true);
- }
-
- /// Retrieves the injected specialization type for this partial
- /// specialization. This is not the same as the type-decl-type for
- /// this partial specialization, which is an InjectedClassNameType.
- QualType getInjectedSpecializationType() const {
- assert(getTypeForDecl() && "partial specialization has no type set!");
- return cast<InjectedClassNameType>(getTypeForDecl())
- ->getInjectedSpecializationType();
- }
-
- // FIXME: Add Profile support!
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K == ClassTemplatePartialSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Declaration of a class template.
-class ClassTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// class template.
- struct Common : CommonBase {
- Common() : LazySpecializations() { }
-
- /// \brief The class template specializations for this class
- /// template, including explicit specializations and instantiations.
- llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
-
- /// \brief The class template partial specializations for this class
- /// template.
- llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
- PartialSpecializations;
-
- /// \brief The injected-class-name type for this class template.
- QualType InjectedClassNameType;
-
- /// \brief If non-null, points to an array of specializations (including
- /// partial specializations) known only by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations/
- /// partial specializations that follow.
- uint32_t *LazySpecializations;
- };
-
- /// \brief Retrieve the set of specializations of this class template.
- llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
- getSpecializations() const;
-
- /// \brief Retrieve the set of partial specializations of this class
- /// template.
- llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
- getPartialSpecializations();
-
- ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() const {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
-public:
- /// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
-
- /// \brief Get the underlying class declarations of the template.
- CXXRecordDecl *getTemplatedDecl() const {
- return static_cast<CXXRecordDecl *>(TemplatedDecl);
- }
-
- /// \brief Returns whether this template declaration defines the primary
- /// class pattern.
- bool isThisDeclarationADefinition() const {
- return getTemplatedDecl()->isThisDeclarationADefinition();
- }
-
- /// \brief Create a class template node.
- static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl,
- ClassTemplateDecl *PrevDecl);
-
- /// \brief Create an empty class template node.
- static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief Return the specialization with the provided arguments if it exists,
- /// otherwise return the insertion point.
- ClassTemplateSpecializationDecl *
- findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- /// \brief Insert the specified specialization knowing that it is not already
- /// in. InsertPos must be obtained from findSpecialization.
- void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
-
- ClassTemplateDecl *getCanonicalDecl() override {
- return cast<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const ClassTemplateDecl *getCanonicalDecl() const {
- return cast<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
- ClassTemplateDecl *getPreviousDecl() {
- return cast_or_null<ClassTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
- const ClassTemplateDecl *getPreviousDecl() const {
- return cast_or_null<ClassTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(
- this)->getPreviousDecl());
- }
-
- ClassTemplateDecl *getMostRecentDecl() {
- return cast<ClassTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
- }
- const ClassTemplateDecl *getMostRecentDecl() const {
- return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
- }
-
- ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
- /// \brief Return the partial specialization with the provided arguments if it
- /// exists, otherwise return the insertion point.
- ClassTemplatePartialSpecializationDecl *
- findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- /// \brief Insert the specified partial specialization knowing that it is not
- /// already in. InsertPos must be obtained from findPartialSpecialization.
- void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
- void *InsertPos);
-
- /// \brief Retrieve the partial specializations as an ordered list.
- void getPartialSpecializations(
- SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
-
- /// \brief Find a class template partial specialization with the given
- /// type T.
- ///
- /// \param T a dependent type that names a specialization of this class
- /// template.
- ///
- /// \returns the class template partial specialization that exactly matches
- /// the type \p T, or NULL if no such partial specialization exists.
- ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
-
- /// \brief Find a class template partial specialization which was instantiated
- /// from the given member partial specialization.
- ///
- /// \param D a member class template partial specialization.
- ///
- /// \returns the class template partial specialization which was instantiated
- /// from the given member partial specialization, or NULL if no such partial
- /// specialization exists.
- ClassTemplatePartialSpecializationDecl *
- findPartialSpecInstantiatedFromMember(
- ClassTemplatePartialSpecializationDecl *D);
-
- /// \brief Retrieve the template specialization type of the
- /// injected-class-name for this class template.
- ///
- /// The injected-class-name for a class template \c X is \c
- /// X<template-args>, where \c template-args is formed from the
- /// template arguments that correspond to the template parameters of
- /// \c X. For example:
- ///
- /// \code
- /// template<typename T, int N>
- /// struct array {
- /// typedef array this_type; // "array" is equivalent to "array<T, N>"
- /// };
- /// \endcode
- QualType getInjectedClassNameSpecialization();
-
- typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
-
- spec_range specializations() const {
- return spec_range(spec_begin(), spec_end());
- }
-
- spec_iterator spec_begin() const {
- return makeSpecIterator(getSpecializations(), false);
- }
-
- spec_iterator spec_end() const {
- return makeSpecIterator(getSpecializations(), true);
- }
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ClassTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Declaration of a friend template.
-///
-/// For example:
-/// \code
-/// template \<typename T> class A {
-/// friend class MyVector<T>; // not a friend template
-/// template \<typename U> friend class B; // not a friend template
-/// template \<typename U> friend class Foo<T>::Nested; // friend template
-/// };
-/// \endcode
-///
-/// \note This class is not currently in use. All of the above
-/// will yield a FriendDecl, not a FriendTemplateDecl.
-class FriendTemplateDecl : public Decl {
- virtual void anchor();
-public:
- typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
-
-private:
- // The number of template parameters; always non-zero.
- unsigned NumParams;
-
- // The parameter list.
- TemplateParameterList **Params;
-
- // The declaration that's a friend of this class.
- FriendUnion Friend;
-
- // Location of the 'friend' specifier.
- SourceLocation FriendLoc;
-
-
- FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
- unsigned NParams,
- TemplateParameterList **Params,
- FriendUnion Friend,
- SourceLocation FriendLoc)
- : Decl(Decl::FriendTemplate, DC, Loc),
- NumParams(NParams),
- Params(Params),
- Friend(Friend),
- FriendLoc(FriendLoc)
- {}
-
- FriendTemplateDecl(EmptyShell Empty)
- : Decl(Decl::FriendTemplate, Empty),
- NumParams(0),
- Params(nullptr)
- {}
-
-public:
- static FriendTemplateDecl *Create(ASTContext &Context,
- DeclContext *DC, SourceLocation Loc,
- unsigned NParams,
- TemplateParameterList **Params,
- FriendUnion Friend,
- SourceLocation FriendLoc);
-
- static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// If this friend declaration names a templated type (or
- /// a dependent member type of a templated type), return that
- /// type; otherwise return null.
- TypeSourceInfo *getFriendType() const {
- return Friend.dyn_cast<TypeSourceInfo*>();
- }
-
- /// If this friend declaration names a templated function (or
- /// a member function of a templated type), return that type;
- /// otherwise return null.
- NamedDecl *getFriendDecl() const {
- return Friend.dyn_cast<NamedDecl*>();
- }
-
- /// \brief Retrieves the location of the 'friend' keyword.
- SourceLocation getFriendLoc() const {
- return FriendLoc;
- }
-
- TemplateParameterList *getTemplateParameterList(unsigned i) const {
- assert(i <= NumParams);
- return Params[i];
- }
-
- unsigned getNumTemplateParameters() const {
- return NumParams;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
-
- friend class ASTDeclReader;
-};
-
-/// \brief Declaration of an alias template.
-///
-/// For example:
-/// \code
-/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
-/// \endcode
-class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- typedef CommonBase Common;
-
- TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
- Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
-public:
- /// Get the underlying function declaration of the template.
- TypeAliasDecl *getTemplatedDecl() const {
- return static_cast<TypeAliasDecl*>(TemplatedDecl);
- }
-
-
- TypeAliasTemplateDecl *getCanonicalDecl() override {
- return cast<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const TypeAliasTemplateDecl *getCanonicalDecl() const {
- return cast<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- TypeAliasTemplateDecl *getPreviousDecl() {
- return cast_or_null<TypeAliasTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- const TypeAliasTemplateDecl *getPreviousDecl() const {
- return cast_or_null<TypeAliasTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(
- this)->getPreviousDecl());
- }
-
- TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
-
- /// \brief Create a function template node.
- static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl);
-
- /// \brief Create an empty alias template node.
- static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Declaration of a function specialization at template class scope.
-///
-/// This is a non-standard extension needed to support MSVC.
-///
-/// For example:
-/// \code
-/// template <class T>
-/// class A {
-/// template <class U> void foo(U a) { }
-/// template<> void foo(int a) { }
-/// }
-/// \endcode
-///
-/// "template<> foo(int a)" will be saved in Specialization as a normal
-/// CXXMethodDecl. Then during an instantiation of class A, it will be
-/// transformed into an actual function specialization.
-class ClassScopeFunctionSpecializationDecl : public Decl {
- virtual void anchor();
-
- ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
- CXXMethodDecl *FD, bool Args,
- TemplateArgumentListInfo TemplArgs)
- : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
- Specialization(FD), HasExplicitTemplateArgs(Args),
- TemplateArgs(TemplArgs) {}
-
- ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
- : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
-
- CXXMethodDecl *Specialization;
- bool HasExplicitTemplateArgs;
- TemplateArgumentListInfo TemplateArgs;
-
-public:
- CXXMethodDecl *getSpecialization() const { return Specialization; }
- bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
- const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
-
- static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
- DeclContext *DC,
- SourceLocation Loc,
- CXXMethodDecl *FD,
- bool HasExplicitTemplateArgs,
- TemplateArgumentListInfo TemplateArgs) {
- return new (C, DC) ClassScopeFunctionSpecializationDecl(
- DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
- }
-
- static ClassScopeFunctionSpecializationDecl *
- CreateDeserialized(ASTContext &Context, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K == Decl::ClassScopeFunctionSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Implementation of inline functions that require the template declarations
-inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
- : Function(FTD) { }
-
-/// \brief Represents a variable template specialization, which refers to
-/// a variable template with a given set of template arguments.
-///
-/// Variable template specializations represent both explicit
-/// specializations of variable templates, as in the example below, and
-/// implicit instantiations of variable templates.
-///
-/// \code
-/// template<typename T> constexpr T pi = T(3.1415926535897932385);
-///
-/// template<>
-/// constexpr float pi<float>; // variable template specialization pi<float>
-/// \endcode
-class VarTemplateSpecializationDecl : public VarDecl,
- public llvm::FoldingSetNode {
-
- /// \brief Structure that stores information about a variable template
- /// specialization that was instantiated from a variable template partial
- /// specialization.
- struct SpecializedPartialSpecialization {
- /// \brief The variable template partial specialization from which this
- /// variable template specialization was instantiated.
- VarTemplatePartialSpecializationDecl *PartialSpecialization;
-
- /// \brief The template argument list deduced for the variable template
- /// partial specialization itself.
- const TemplateArgumentList *TemplateArgs;
- };
-
- /// \brief The template that this specialization specializes.
- llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
- SpecializedTemplate;
-
- /// \brief Further info for explicit template specialization/instantiation.
- struct ExplicitSpecializationInfo {
- /// \brief The type-as-written.
- TypeSourceInfo *TypeAsWritten;
- /// \brief The location of the extern keyword.
- SourceLocation ExternLoc;
- /// \brief The location of the template keyword.
- SourceLocation TemplateKeywordLoc;
-
- ExplicitSpecializationInfo()
- : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
- };
-
- /// \brief Further info for explicit template specialization/instantiation.
- /// Does not apply to implicit specializations.
- ExplicitSpecializationInfo *ExplicitInfo;
-
- /// \brief The template arguments used to describe this specialization.
- const TemplateArgumentList *TemplateArgs;
- TemplateArgumentListInfo TemplateArgsInfo;
-
- /// \brief The point where this template was instantiated (if any).
- SourceLocation PointOfInstantiation;
-
- /// \brief The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
- unsigned SpecializationKind : 3;
-
-protected:
- VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- VarTemplateDecl *SpecializedTemplate,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, const TemplateArgument *Args,
- unsigned NumArgs);
-
- explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
-
-public:
- static VarTemplateSpecializationDecl *
- Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
- unsigned NumArgs);
- static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
-
- void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
- bool Qualified) const override;
-
- VarTemplateSpecializationDecl *getMostRecentDecl() {
- VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
- return cast<VarTemplateSpecializationDecl>(Recent);
- }
-
- /// \brief Retrieve the template that this specialization specializes.
- VarTemplateDecl *getSpecializedTemplate() const;
-
- /// \brief Retrieve the template arguments of the variable template
- /// specialization.
- const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
-
- // TODO: Always set this when creating the new specialization?
- void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
-
- const TemplateArgumentListInfo &getTemplateArgsInfo() const {
- return TemplateArgsInfo;
- }
-
- /// \brief Determine the kind of specialization that this
- /// declaration represents.
- TemplateSpecializationKind getSpecializationKind() const {
- return static_cast<TemplateSpecializationKind>(SpecializationKind);
- }
-
- bool isExplicitSpecialization() const {
- return getSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief True if this declaration is an explicit specialization,
- /// explicit instantiation declaration, or explicit instantiation
- /// definition.
- bool isExplicitInstantiationOrSpecialization() const {
- return isTemplateExplicitInstantiationOrSpecialization(
- getTemplateSpecializationKind());
- }
-
- void setSpecializationKind(TemplateSpecializationKind TSK) {
- SpecializationKind = TSK;
- }
-
- /// \brief Get the point of instantiation (if any), or null if none.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- void setPointOfInstantiation(SourceLocation Loc) {
- assert(Loc.isValid() && "point of instantiation must be valid!");
- PointOfInstantiation = Loc;
- }
-
- /// \brief If this variable template specialization is an instantiation of
- /// a template (rather than an explicit specialization), return the
- /// variable template or variable template partial specialization from which
- /// it was instantiated.
- llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
- getInstantiatedFrom() const {
- if (getSpecializationKind() != TSK_ImplicitInstantiation &&
- getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
- getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
- return llvm::PointerUnion<VarTemplateDecl *,
- VarTemplatePartialSpecializationDecl *>();
-
- if (SpecializedPartialSpecialization *PartialSpec =
- SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<VarTemplateDecl *>();
- }
-
- /// \brief Retrieve the variable template or variable template partial
- /// specialization which was specialized by this.
- llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
- getSpecializedTemplateOrPartial() const {
- if (SpecializedPartialSpecialization *PartialSpec =
- SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<VarTemplateDecl *>();
- }
-
- /// \brief Retrieve the set of template arguments that should be used
- /// to instantiate the initializer of the variable template or variable
- /// template partial specialization from which this variable template
- /// specialization was instantiated.
- ///
- /// \returns For a variable template specialization instantiated from the
- /// primary template, this function will return the same template arguments
- /// as getTemplateArgs(). For a variable template specialization instantiated
- /// from a variable template partial specialization, this function will the
- /// return deduced template arguments for the variable template partial
- /// specialization itself.
- const TemplateArgumentList &getTemplateInstantiationArgs() const {
- if (SpecializedPartialSpecialization *PartialSpec =
- SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
- return *PartialSpec->TemplateArgs;
-
- return getTemplateArgs();
- }
-
- /// \brief Note that this variable template specialization is actually an
- /// instantiation of the given variable template partial specialization whose
- /// template arguments have been deduced.
- void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
- const TemplateArgumentList *TemplateArgs) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
- "Already set to a variable template partial specialization!");
- SpecializedPartialSpecialization *PS =
- new (getASTContext()) SpecializedPartialSpecialization();
- PS->PartialSpecialization = PartialSpec;
- PS->TemplateArgs = TemplateArgs;
- SpecializedTemplate = PS;
- }
-
- /// \brief Note that this variable template specialization is an instantiation
- /// of the given variable template.
- void setInstantiationOf(VarTemplateDecl *TemplDecl) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
- "Previously set to a variable template partial specialization!");
- SpecializedTemplate = TemplDecl;
- }
-
- /// \brief Sets the type of this specialization as it was written by
- /// the user.
- void setTypeAsWritten(TypeSourceInfo *T) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = T;
- }
- /// \brief Gets the type of this specialization as it was written by
- /// the user, if it was so written.
- TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
- }
-
- /// \brief Gets the location of the extern keyword, if present.
- SourceLocation getExternLoc() const {
- return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
- }
- /// \brief Sets the location of the extern keyword.
- void setExternLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->ExternLoc = Loc;
- }
-
- /// \brief Sets the location of the template keyword.
- void setTemplateKeywordLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TemplateKeywordLoc = Loc;
- }
- /// \brief Gets the location of the template keyword, if present.
- SourceLocation getTemplateKeywordLoc() const {
- return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs->asArray(), getASTContext());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
- ID.AddInteger(TemplateArgs.size());
- for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
- TemplateArgs[Arg].Profile(ID, Context);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstVarTemplateSpecialization &&
- K <= lastVarTemplateSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-class VarTemplatePartialSpecializationDecl
- : public VarTemplateSpecializationDecl {
- void anchor() override;
-
- /// \brief The list of template parameters
- TemplateParameterList *TemplateParams;
-
- /// \brief The source info for the template arguments as written.
- /// FIXME: redundant with TypeAsWritten?
- const ASTTemplateArgumentListInfo *ArgsAsWritten;
-
- /// \brief The variable template partial specialization from which this
- /// variable template partial specialization was instantiated.
- ///
- /// The boolean value will be true to indicate that this variable template
- /// partial specialization was specialized at this level.
- llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
- InstantiatedFromMember;
-
- VarTemplatePartialSpecializationDecl(
- ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, TemplateParameterList *Params,
- VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
- StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
- const ASTTemplateArgumentListInfo *ArgInfos);
-
- VarTemplatePartialSpecializationDecl(ASTContext &Context)
- : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
- TemplateParams(nullptr), ArgsAsWritten(nullptr),
- InstantiatedFromMember(nullptr, false) {}
-
-public:
- static VarTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, TemplateParameterList *Params,
- VarTemplateDecl *SpecializedTemplate, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
- unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
-
- static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
-
- VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
- return cast<VarTemplatePartialSpecializationDecl>(
- static_cast<VarTemplateSpecializationDecl *>(
- this)->getMostRecentDecl());
- }
-
- /// Get the list of template parameters
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- /// Get the template arguments as written.
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return ArgsAsWritten;
- }
-
- /// \brief Retrieve the member variable template partial specialization from
- /// which this particular variable template partial specialization was
- /// instantiated.
- ///
- /// \code
- /// template<typename T>
- /// struct Outer {
- /// template<typename U> U Inner;
- /// template<typename U> U* Inner<U*> = (U*)(0); // #1
- /// };
- ///
- /// template int* Outer<float>::Inner<int*>;
- /// \endcode
- ///
- /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
- /// end up instantiating the partial specialization
- /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
- /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
- /// \c Outer<float>::Inner<U*>, this function would return
- /// \c Outer<T>::Inner<U*>.
- VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
- const VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getPointer();
- }
-
- void
- setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- First->InstantiatedFromMember.setPointer(PartialSpec);
- }
-
- /// \brief Determines whether this variable template partial specialization
- /// was a specialization of a member partial specialization.
- ///
- /// In the following example, the member template partial specialization
- /// \c X<int>::Inner<T*> is a member specialization.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> U Inner;
- /// template<typename U> U* Inner<U*> = (U*)(0);
- /// };
- ///
- /// template<> template<typename T>
- /// U* X<int>::Inner<T*> = (T*)(0) + 1;
- /// \endcode
- bool isMemberSpecialization() {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getInt();
- }
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- assert(First->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- return First->InstantiatedFromMember.setInt(true);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K == VarTemplatePartialSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Declaration of a variable template.
-class VarTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// variable template.
- struct Common : CommonBase {
- Common() : LazySpecializations() {}
-
- /// \brief The variable template specializations for this variable
- /// template, including explicit specializations and instantiations.
- llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
-
- /// \brief The variable template partial specializations for this variable
- /// template.
- llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
- PartialSpecializations;
-
- /// \brief If non-null, points to an array of specializations (including
- /// partial specializations) known ownly by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations/
- /// partial specializations that follow.
- uint32_t *LazySpecializations;
- };
-
- /// \brief Retrieve the set of specializations of this variable template.
- llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
- getSpecializations() const;
-
- /// \brief Retrieve the set of partial specializations of this class
- /// template.
- llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
- getPartialSpecializations();
-
- VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() const {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
-public:
- /// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
-
- /// \brief Get the underlying variable declarations of the template.
- VarDecl *getTemplatedDecl() const {
- return static_cast<VarDecl *>(TemplatedDecl);
- }
-
- /// \brief Returns whether this template declaration defines the primary
- /// variable pattern.
- bool isThisDeclarationADefinition() const {
- return getTemplatedDecl()->isThisDeclarationADefinition();
- }
-
- VarTemplateDecl *getDefinition();
-
- /// \brief Create a variable template node.
- static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params,
- VarDecl *Decl);
-
- /// \brief Create an empty variable template node.
- static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief Return the specialization with the provided arguments if it exists,
- /// otherwise return the insertion point.
- VarTemplateSpecializationDecl *
- findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- /// \brief Insert the specified specialization knowing that it is not already
- /// in. InsertPos must be obtained from findSpecialization.
- void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
-
- VarTemplateDecl *getCanonicalDecl() override {
- return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const VarTemplateDecl *getCanonicalDecl() const {
- return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this variable template, or
- /// NULL if no such declaration exists.
- VarTemplateDecl *getPreviousDecl() {
- return cast_or_null<VarTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this variable template, or
- /// NULL if no such declaration exists.
- const VarTemplateDecl *getPreviousDecl() const {
- return cast_or_null<VarTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(
- this)->getPreviousDecl());
- }
-
- VarTemplateDecl *getMostRecentDecl() {
- return cast<VarTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
- }
- const VarTemplateDecl *getMostRecentDecl() const {
- return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
- }
-
- VarTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<VarTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
- /// \brief Return the partial specialization with the provided arguments if it
- /// exists, otherwise return the insertion point.
- VarTemplatePartialSpecializationDecl *
- findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- /// \brief Insert the specified partial specialization knowing that it is not
- /// already in. InsertPos must be obtained from findPartialSpecialization.
- void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
- void *InsertPos);
-
- /// \brief Retrieve the partial specializations as an ordered list.
- void getPartialSpecializations(
- SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
-
- /// \brief Find a variable template partial specialization which was
- /// instantiated
- /// from the given member partial specialization.
- ///
- /// \param D a member variable template partial specialization.
- ///
- /// \returns the variable template partial specialization which was
- /// instantiated
- /// from the given member partial specialization, or NULL if no such partial
- /// specialization exists.
- VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
- VarTemplatePartialSpecializationDecl *D);
-
- typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
-
- spec_range specializations() const {
- return spec_range(spec_begin(), spec_end());
- }
-
- spec_iterator spec_begin() const {
- return makeSpecIterator(getSpecializations(), false);
- }
-
- spec_iterator spec_end() const {
- return makeSpecIterator(getSpecializations(), true);
- }
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == VarTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-} /* end of namespace clang */
-
-#endif
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
deleted file mode 100644
index 4eaae35..0000000
--- a/include/clang/AST/DeclVisitor.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===--- DeclVisitor.h - Visitor for Decl subclasses ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the DeclVisitor interface.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_DECLVISITOR_H
-#define LLVM_CLANG_AST_DECLVISITOR_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#include "clang/AST/DeclTemplate.h"
-
-namespace clang {
-namespace declvisitor {
-
-template <typename T> struct make_ptr { typedef T *type; };
-template <typename T> struct make_const_ptr { typedef const T *type; };
-
-/// \brief A simple visitor class that helps create declaration visitors.
-template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
-class Base {
-public:
-
-#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D))
-
- RetTy Visit(PTR(Decl) D) {
- switch (D->getKind()) {
-#define DECL(DERIVED, BASE) \
- case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl);
-#define ABSTRACT_DECL(DECL)
-#include "clang/AST/DeclNodes.inc"
- }
- llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
- }
-
- // If the implementation chooses not to implement a certain visit
- // method, fall back to the parent.
-#define DECL(DERIVED, BASE) \
- RetTy Visit##DERIVED##Decl(PTR(DERIVED##Decl) D) { DISPATCH(BASE, BASE); }
-#include "clang/AST/DeclNodes.inc"
-
- RetTy VisitDecl(PTR(Decl) D) { return RetTy(); }
-
-#undef PTR
-#undef DISPATCH
-};
-
-} // end namespace declvisitor
-
-/// \brief A simple visitor class that helps create declaration visitors.
-///
-/// This class does not preserve constness of Decl pointers (see also
-/// ConstDeclVisitor).
-template<typename ImplClass, typename RetTy=void>
-class DeclVisitor
- : public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
-
-/// \brief A simple visitor class that helps create declaration visitors.
-///
-/// This class preserves constness of Decl pointers (see also DeclVisitor).
-template<typename ImplClass, typename RetTy=void>
-class ConstDeclVisitor
- : public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_DECLVISITOR_H
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
deleted file mode 100644
index 9482e83e..0000000
--- a/include/clang/AST/DeclarationName.h
+++ /dev/null
@@ -1,598 +0,0 @@
-//===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the DeclarationName and DeclarationNameTable classes.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
-#define LLVM_CLANG_AST_DECLARATIONNAME_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm {
- template <typename T> struct DenseMapInfo;
-}
-
-namespace clang {
- class ASTContext;
- class CXXLiteralOperatorIdName;
- class CXXOperatorIdName;
- class CXXSpecialName;
- class DeclarationNameExtra;
- class IdentifierInfo;
- class MultiKeywordSelector;
- enum OverloadedOperatorKind : int;
- class QualType;
- class Type;
- class TypeSourceInfo;
- class UsingDirectiveDecl;
-
- template <typename> class CanQual;
- typedef CanQual<Type> CanQualType;
-
-/// DeclarationName - The name of a declaration. In the common case,
-/// this just stores an IdentifierInfo pointer to a normal
-/// name. However, it also provides encodings for Objective-C
-/// selectors (optimizing zero- and one-argument selectors, which make
-/// up 78% percent of all selectors in Cocoa.h) and special C++ names
-/// for constructors, destructors, and conversion functions.
-class DeclarationName {
-public:
- /// NameKind - The kind of name this object contains.
- enum NameKind {
- Identifier,
- ObjCZeroArgSelector,
- ObjCOneArgSelector,
- ObjCMultiArgSelector,
- CXXConstructorName,
- CXXDestructorName,
- CXXConversionFunctionName,
- CXXOperatorName,
- CXXLiteralOperatorName,
- CXXUsingDirective
- };
- static const unsigned NumNameKinds = CXXUsingDirective + 1;
-
-private:
- /// StoredNameKind - The kind of name that is actually stored in the
- /// upper bits of the Ptr field. This is only used internally.
- ///
- /// Note: The entries here are synchronized with the entries in Selector,
- /// for efficient translation between the two.
- enum StoredNameKind {
- StoredIdentifier = 0,
- StoredObjCZeroArgSelector = 0x01,
- StoredObjCOneArgSelector = 0x02,
- StoredDeclarationNameExtra = 0x03,
- PtrMask = 0x03
- };
-
- /// Ptr - The lowest two bits are used to express what kind of name
- /// we're actually storing, using the values of NameKind. Depending
- /// on the kind of name this is, the upper bits of Ptr may have one
- /// of several different meanings:
- ///
- /// StoredIdentifier - The name is a normal identifier, and Ptr is
- /// a normal IdentifierInfo pointer.
- ///
- /// StoredObjCZeroArgSelector - The name is an Objective-C
- /// selector with zero arguments, and Ptr is an IdentifierInfo
- /// pointer pointing to the selector name.
- ///
- /// StoredObjCOneArgSelector - The name is an Objective-C selector
- /// with one argument, and Ptr is an IdentifierInfo pointer
- /// pointing to the selector name.
- ///
- /// StoredDeclarationNameExtra - Ptr is actually a pointer to a
- /// DeclarationNameExtra structure, whose first value will tell us
- /// whether this is an Objective-C selector, C++ operator-id name,
- /// or special C++ name.
- uintptr_t Ptr;
-
- /// getStoredNameKind - Return the kind of object that is stored in
- /// Ptr.
- StoredNameKind getStoredNameKind() const {
- return static_cast<StoredNameKind>(Ptr & PtrMask);
- }
-
- /// getExtra - Get the "extra" information associated with this
- /// multi-argument selector or C++ special name.
- DeclarationNameExtra *getExtra() const {
- assert(getStoredNameKind() == StoredDeclarationNameExtra &&
- "Declaration name does not store an Extra structure");
- return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
- }
-
- /// getAsCXXSpecialName - If the stored pointer is actually a
- /// CXXSpecialName, returns a pointer to it. Otherwise, returns
- /// a NULL pointer.
- CXXSpecialName *getAsCXXSpecialName() const {
- NameKind Kind = getNameKind();
- if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
- return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
- return nullptr;
- }
-
- /// getAsCXXOperatorIdName
- CXXOperatorIdName *getAsCXXOperatorIdName() const {
- if (getNameKind() == CXXOperatorName)
- return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
- return nullptr;
- }
-
- CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
- if (getNameKind() == CXXLiteralOperatorName)
- return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
- return nullptr;
- }
-
- // Construct a declaration name from the name of a C++ constructor,
- // destructor, or conversion function.
- DeclarationName(CXXSpecialName *Name)
- : Ptr(reinterpret_cast<uintptr_t>(Name)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
- Ptr |= StoredDeclarationNameExtra;
- }
-
- // Construct a declaration name from the name of a C++ overloaded
- // operator.
- DeclarationName(CXXOperatorIdName *Name)
- : Ptr(reinterpret_cast<uintptr_t>(Name)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId");
- Ptr |= StoredDeclarationNameExtra;
- }
-
- DeclarationName(CXXLiteralOperatorIdName *Name)
- : Ptr(reinterpret_cast<uintptr_t>(Name)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
- Ptr |= StoredDeclarationNameExtra;
- }
-
- /// Construct a declaration name from a raw pointer.
- DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
-
- friend class DeclarationNameTable;
- friend class NamedDecl;
-
- /// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
- /// for this name as a void pointer if it's not an identifier.
- void *getFETokenInfoAsVoidSlow() const;
-
-public:
- /// DeclarationName - Used to create an empty selector.
- DeclarationName() : Ptr(0) { }
-
- // Construct a declaration name from an IdentifierInfo *.
- DeclarationName(const IdentifierInfo *II)
- : Ptr(reinterpret_cast<uintptr_t>(II)) {
- assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
- }
-
- // Construct a declaration name from an Objective-C selector.
- DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) { }
-
- /// getUsingDirectiveName - Return name for all using-directives.
- static DeclarationName getUsingDirectiveName();
-
- // operator bool() - Evaluates true when this declaration name is
- // non-empty.
- explicit operator bool() const {
- return ((Ptr & PtrMask) != 0) ||
- (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
- }
-
- /// \brief Evaluates true when this declaration name is empty.
- bool isEmpty() const {
- return !*this;
- }
-
- /// Predicate functions for querying what type of name this is.
- bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
- bool isObjCZeroArgSelector() const {
- return getStoredNameKind() == StoredObjCZeroArgSelector;
- }
- bool isObjCOneArgSelector() const {
- return getStoredNameKind() == StoredObjCOneArgSelector;
- }
-
- /// getNameKind - Determine what kind of name this is.
- NameKind getNameKind() const;
-
- /// \brief Determines whether the name itself is dependent, e.g., because it
- /// involves a C++ type that is itself dependent.
- ///
- /// Note that this does not capture all of the notions of "dependent name",
- /// because an identifier can be a dependent name if it is used as the
- /// callee in a call expression with dependent arguments.
- bool isDependentName() const;
-
- /// getNameAsString - Retrieve the human-readable string for this name.
- std::string getAsString() const;
-
- /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
- /// this declaration name, or NULL if this declaration name isn't a
- /// simple identifier.
- IdentifierInfo *getAsIdentifierInfo() const {
- if (isIdentifier())
- return reinterpret_cast<IdentifierInfo *>(Ptr);
- return nullptr;
- }
-
- /// getAsOpaqueInteger - Get the representation of this declaration
- /// name as an opaque integer.
- uintptr_t getAsOpaqueInteger() const { return Ptr; }
-
- /// getAsOpaquePtr - Get the representation of this declaration name as
- /// an opaque pointer.
- void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
-
- static DeclarationName getFromOpaquePtr(void *P) {
- DeclarationName N;
- N.Ptr = reinterpret_cast<uintptr_t> (P);
- return N;
- }
-
- static DeclarationName getFromOpaqueInteger(uintptr_t P) {
- DeclarationName N;
- N.Ptr = P;
- return N;
- }
-
- /// getCXXNameType - If this name is one of the C++ names (of a
- /// constructor, destructor, or conversion function), return the
- /// type associated with that name.
- QualType getCXXNameType() const;
-
- /// getCXXOverloadedOperator - If this name is the name of an
- /// overloadable operator in C++ (e.g., @c operator+), retrieve the
- /// kind of overloaded operator.
- OverloadedOperatorKind getCXXOverloadedOperator() const;
-
- /// getCXXLiteralIdentifier - If this name is the name of a literal
- /// operator, retrieve the identifier associated with it.
- IdentifierInfo *getCXXLiteralIdentifier() const;
-
- /// getObjCSelector - Get the Objective-C selector stored in this
- /// declaration name.
- Selector getObjCSelector() const {
- assert((getNameKind() == ObjCZeroArgSelector ||
- getNameKind() == ObjCOneArgSelector ||
- getNameKind() == ObjCMultiArgSelector ||
- Ptr == 0) && "Not a selector!");
- return Selector(Ptr);
- }
-
- /// getFETokenInfo/setFETokenInfo - The language front-end is
- /// allowed to associate arbitrary metadata with some kinds of
- /// declaration names, including normal identifiers and C++
- /// constructors, destructors, and conversion functions.
- template<typename T>
- T *getFETokenInfo() const {
- if (const IdentifierInfo *Info = getAsIdentifierInfo())
- return Info->getFETokenInfo<T>();
- return static_cast<T*>(getFETokenInfoAsVoidSlow());
- }
-
- void setFETokenInfo(void *T);
-
- /// operator== - Determine whether the specified names are identical..
- friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
- return LHS.Ptr == RHS.Ptr;
- }
-
- /// operator!= - Determine whether the specified names are different.
- friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
- return LHS.Ptr != RHS.Ptr;
- }
-
- static DeclarationName getEmptyMarker() {
- return DeclarationName(uintptr_t(-1));
- }
-
- static DeclarationName getTombstoneMarker() {
- return DeclarationName(uintptr_t(-2));
- }
-
- static int compare(DeclarationName LHS, DeclarationName RHS);
-
- void dump() const;
-};
-
-raw_ostream &operator<<(raw_ostream &OS, DeclarationName N);
-
-/// Ordering on two declaration names. If both names are identifiers,
-/// this provides a lexicographical ordering.
-inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
- return DeclarationName::compare(LHS, RHS) < 0;
-}
-
-/// Ordering on two declaration names. If both names are identifiers,
-/// this provides a lexicographical ordering.
-inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
- return DeclarationName::compare(LHS, RHS) > 0;
-}
-
-/// Ordering on two declaration names. If both names are identifiers,
-/// this provides a lexicographical ordering.
-inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
- return DeclarationName::compare(LHS, RHS) <= 0;
-}
-
-/// Ordering on two declaration names. If both names are identifiers,
-/// this provides a lexicographical ordering.
-inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
- return DeclarationName::compare(LHS, RHS) >= 0;
-}
-
-/// DeclarationNameTable - Used to store and retrieve DeclarationName
-/// instances for the various kinds of declaration names, e.g., normal
-/// identifiers, C++ constructor names, etc. This class contains
-/// uniqued versions of each of the C++ special names, which can be
-/// retrieved using its member functions (e.g.,
-/// getCXXConstructorName).
-class DeclarationNameTable {
- const ASTContext &Ctx;
- void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
- CXXOperatorIdName *CXXOperatorNames; // Operator names
- void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
-
- DeclarationNameTable(const DeclarationNameTable&) = delete;
- void operator=(const DeclarationNameTable&) = delete;
-
-public:
- DeclarationNameTable(const ASTContext &C);
- ~DeclarationNameTable();
-
- /// getIdentifier - Create a declaration name that is a simple
- /// identifier.
- DeclarationName getIdentifier(const IdentifierInfo *ID) {
- return DeclarationName(ID);
- }
-
- /// getCXXConstructorName - Returns the name of a C++ constructor
- /// for the given Type.
- DeclarationName getCXXConstructorName(CanQualType Ty);
-
- /// getCXXDestructorName - Returns the name of a C++ destructor
- /// for the given Type.
- DeclarationName getCXXDestructorName(CanQualType Ty);
-
- /// getCXXConversionFunctionName - Returns the name of a C++
- /// conversion function for the given Type.
- DeclarationName getCXXConversionFunctionName(CanQualType Ty);
-
- /// getCXXSpecialName - Returns a declaration name for special kind
- /// of C++ name, e.g., for a constructor, destructor, or conversion
- /// function.
- DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
- CanQualType Ty);
-
- /// getCXXOperatorName - Get the name of the overloadable C++
- /// operator corresponding to Op.
- DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
-
- /// getCXXLiteralOperatorName - Get the name of the literal operator function
- /// with II as the identifier.
- DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
-};
-
-/// DeclarationNameLoc - Additional source/type location info
-/// for a declaration name. Needs a DeclarationName in order
-/// to be interpreted correctly.
-struct DeclarationNameLoc {
- // The source location for identifier stored elsewhere.
- // struct {} Identifier;
-
- // Type info for constructors, destructors and conversion functions.
- // Locations (if any) for the tilde (destructor) or operator keyword
- // (conversion) are stored elsewhere.
- struct NT {
- TypeSourceInfo *TInfo;
- };
-
- // The location (if any) of the operator keyword is stored elsewhere.
- struct CXXOpName {
- unsigned BeginOpNameLoc;
- unsigned EndOpNameLoc;
- };
-
- // The location (if any) of the operator keyword is stored elsewhere.
- struct CXXLitOpName {
- unsigned OpNameLoc;
- };
-
- // struct {} CXXUsingDirective;
- // struct {} ObjCZeroArgSelector;
- // struct {} ObjCOneArgSelector;
- // struct {} ObjCMultiArgSelector;
- union {
- struct NT NamedType;
- struct CXXOpName CXXOperatorName;
- struct CXXLitOpName CXXLiteralOperatorName;
- };
-
- DeclarationNameLoc(DeclarationName Name);
- // FIXME: this should go away once all DNLocs are properly initialized.
- DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
-}; // struct DeclarationNameLoc
-
-
-/// DeclarationNameInfo - A collector data type for bundling together
-/// a DeclarationName and the correspnding source/type location info.
-struct DeclarationNameInfo {
-private:
- /// Name - The declaration name, also encoding name kind.
- DeclarationName Name;
- /// Loc - The main source location for the declaration name.
- SourceLocation NameLoc;
- /// Info - Further source/type location info for special kinds of names.
- DeclarationNameLoc LocInfo;
-
-public:
- // FIXME: remove it.
- DeclarationNameInfo() {}
-
- DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
- : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
-
- DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
- DeclarationNameLoc LocInfo)
- : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
-
- /// getName - Returns the embedded declaration name.
- DeclarationName getName() const { return Name; }
- /// setName - Sets the embedded declaration name.
- void setName(DeclarationName N) { Name = N; }
-
- /// getLoc - Returns the main location of the declaration name.
- SourceLocation getLoc() const { return NameLoc; }
- /// setLoc - Sets the main location of the declaration name.
- void setLoc(SourceLocation L) { NameLoc = L; }
-
- const DeclarationNameLoc &getInfo() const { return LocInfo; }
- DeclarationNameLoc &getInfo() { return LocInfo; }
- void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
-
- /// getNamedTypeInfo - Returns the source type info associated to
- /// the name. Assumes it is a constructor, destructor or conversion.
- TypeSourceInfo *getNamedTypeInfo() const {
- assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
- Name.getNameKind() == DeclarationName::CXXDestructorName ||
- Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
- return LocInfo.NamedType.TInfo;
- }
- /// setNamedTypeInfo - Sets the source type info associated to
- /// the name. Assumes it is a constructor, destructor or conversion.
- void setNamedTypeInfo(TypeSourceInfo *TInfo) {
- assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
- Name.getNameKind() == DeclarationName::CXXDestructorName ||
- Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
- LocInfo.NamedType.TInfo = TInfo;
- }
-
- /// getCXXOperatorNameRange - Gets the range of the operator name
- /// (without the operator keyword). Assumes it is a (non-literal) operator.
- SourceRange getCXXOperatorNameRange() const {
- assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
- return SourceRange(
- SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
- SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
- );
- }
- /// setCXXOperatorNameRange - Sets the range of the operator name
- /// (without the operator keyword). Assumes it is a C++ operator.
- void setCXXOperatorNameRange(SourceRange R) {
- assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
- LocInfo.CXXOperatorName.BeginOpNameLoc = R.getBegin().getRawEncoding();
- LocInfo.CXXOperatorName.EndOpNameLoc = R.getEnd().getRawEncoding();
- }
-
- /// getCXXLiteralOperatorNameLoc - Returns the location of the literal
- /// operator name (not the operator keyword).
- /// Assumes it is a literal operator.
- SourceLocation getCXXLiteralOperatorNameLoc() const {
- assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
- return SourceLocation::
- getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
- }
- /// setCXXLiteralOperatorNameLoc - Sets the location of the literal
- /// operator name (not the operator keyword).
- /// Assumes it is a literal operator.
- void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
- assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
- LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
- }
-
- /// \brief Determine whether this name involves a template parameter.
- bool isInstantiationDependent() const;
-
- /// \brief Determine whether this name contains an unexpanded
- /// parameter pack.
- bool containsUnexpandedParameterPack() const;
-
- /// getAsString - Retrieve the human-readable string for this name.
- std::string getAsString() const;
-
- /// printName - Print the human-readable name to a stream.
- void printName(raw_ostream &OS) const;
-
- /// getBeginLoc - Retrieve the location of the first token.
- SourceLocation getBeginLoc() const { return NameLoc; }
- /// getEndLoc - Retrieve the location of the last token.
- SourceLocation getEndLoc() const;
- /// getSourceRange - The range of the declaration name.
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
- }
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBeginLoc();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- SourceLocation EndLoc = getEndLoc();
- return EndLoc.isValid() ? EndLoc : getLocStart();
- }
-};
-
-/// Insertion operator for diagnostics. This allows sending DeclarationName's
-/// into a diagnostic with <<.
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- DeclarationName N) {
- DB.AddTaggedVal(N.getAsOpaqueInteger(),
- DiagnosticsEngine::ak_declarationname);
- return DB;
-}
-
-/// Insertion operator for partial diagnostics. This allows binding
-/// DeclarationName's into a partial diagnostic with <<.
-inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- DeclarationName N) {
- PD.AddTaggedVal(N.getAsOpaqueInteger(),
- DiagnosticsEngine::ak_declarationname);
- return PD;
-}
-
-inline raw_ostream &operator<<(raw_ostream &OS,
- DeclarationNameInfo DNInfo) {
- DNInfo.printName(OS);
- return OS;
-}
-
-} // end namespace clang
-
-namespace llvm {
-/// Define DenseMapInfo so that DeclarationNames can be used as keys
-/// in DenseMap and DenseSets.
-template<>
-struct DenseMapInfo<clang::DeclarationName> {
- static inline clang::DeclarationName getEmptyKey() {
- return clang::DeclarationName::getEmptyMarker();
- }
-
- static inline clang::DeclarationName getTombstoneKey() {
- return clang::DeclarationName::getTombstoneMarker();
- }
-
- static unsigned getHashValue(clang::DeclarationName Name) {
- return DenseMapInfo<void*>::getHashValue(Name.getAsOpaquePtr());
- }
-
- static inline bool
- isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
- return LHS == RHS;
- }
-};
-
-template <>
-struct isPodLike<clang::DeclarationName> { static const bool value = true; };
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
deleted file mode 100644
index 8e038c8..0000000
--- a/include/clang/AST/DependentDiagnostic.h
+++ /dev/null
@@ -1,189 +0,0 @@
-//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines interfaces for diagnostics which may or may
-// fire based on how a template is instantiated.
-//
-// At the moment, the only consumer of this interface is access
-// control.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
-#define LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H
-
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclContextInternals.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-class ASTContext;
-class CXXRecordDecl;
-class NamedDecl;
-
-/// A dependently-generated diagnostic.
-class DependentDiagnostic {
-public:
- enum AccessNonce { Access = 0 };
-
- static DependentDiagnostic *Create(ASTContext &Context,
- DeclContext *Parent,
- AccessNonce _,
- SourceLocation Loc,
- bool IsMemberAccess,
- AccessSpecifier AS,
- NamedDecl *TargetDecl,
- CXXRecordDecl *NamingClass,
- QualType BaseObjectType,
- const PartialDiagnostic &PDiag) {
- DependentDiagnostic *DD = Create(Context, Parent, PDiag);
- DD->AccessData.Loc = Loc.getRawEncoding();
- DD->AccessData.IsMember = IsMemberAccess;
- DD->AccessData.Access = AS;
- DD->AccessData.TargetDecl = TargetDecl;
- DD->AccessData.NamingClass = NamingClass;
- DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
- return DD;
- }
-
- unsigned getKind() const {
- return Access;
- }
-
- bool isAccessToMember() const {
- assert(getKind() == Access);
- return AccessData.IsMember;
- }
-
- AccessSpecifier getAccess() const {
- assert(getKind() == Access);
- return AccessSpecifier(AccessData.Access);
- }
-
- SourceLocation getAccessLoc() const {
- assert(getKind() == Access);
- return SourceLocation::getFromRawEncoding(AccessData.Loc);
- }
-
- NamedDecl *getAccessTarget() const {
- assert(getKind() == Access);
- return AccessData.TargetDecl;
- }
-
- NamedDecl *getAccessNamingClass() const {
- assert(getKind() == Access);
- return AccessData.NamingClass;
- }
-
- QualType getAccessBaseObjectType() const {
- assert(getKind() == Access);
- return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
- }
-
- const PartialDiagnostic &getDiagnostic() const {
- return Diag;
- }
-
-private:
- DependentDiagnostic(const PartialDiagnostic &PDiag,
- PartialDiagnostic::Storage *Storage)
- : Diag(PDiag, Storage) {}
-
- static DependentDiagnostic *Create(ASTContext &Context,
- DeclContext *Parent,
- const PartialDiagnostic &PDiag);
-
- friend class DependentStoredDeclsMap;
- friend class DeclContext::ddiag_iterator;
- DependentDiagnostic *NextDiagnostic;
-
- PartialDiagnostic Diag;
-
- struct {
- unsigned Loc;
- unsigned Access : 2;
- unsigned IsMember : 1;
- NamedDecl *TargetDecl;
- CXXRecordDecl *NamingClass;
- void *BaseObjectType;
- } AccessData;
-};
-
-///
-
-/// An iterator over the dependent diagnostics in a dependent context.
-class DeclContext::ddiag_iterator {
-public:
- ddiag_iterator() : Ptr(nullptr) {}
- explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
-
- typedef DependentDiagnostic *value_type;
- typedef DependentDiagnostic *reference;
- typedef DependentDiagnostic *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- reference operator*() const { return Ptr; }
-
- ddiag_iterator &operator++() {
- assert(Ptr && "attempt to increment past end of diag list");
- Ptr = Ptr->NextDiagnostic;
- return *this;
- }
-
- ddiag_iterator operator++(int) {
- ddiag_iterator tmp = *this;
- ++*this;
- return tmp;
- }
-
- bool operator==(ddiag_iterator Other) const {
- return Ptr == Other.Ptr;
- }
-
- bool operator!=(ddiag_iterator Other) const {
- return Ptr != Other.Ptr;
- }
-
- ddiag_iterator &operator+=(difference_type N) {
- assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
- while (N--)
- ++*this;
- return *this;
- }
-
- ddiag_iterator operator+(difference_type N) const {
- ddiag_iterator tmp = *this;
- tmp += N;
- return tmp;
- }
-
-private:
- DependentDiagnostic *Ptr;
-};
-
-inline DeclContext::ddiag_range DeclContext::ddiags() const {
- assert(isDependentContext()
- && "cannot iterate dependent diagnostics of non-dependent context");
- const DependentStoredDeclsMap *Map
- = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
-
- if (!Map)
- // Return an empty range using the always-end default constructor.
- return ddiag_range(ddiag_iterator(), ddiag_iterator());
-
- return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
-}
-
-}
-
-#endif
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
deleted file mode 100644
index aad7726..0000000
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the EvaluatedExprVisitor class template, which visits
-// the potentially-evaluated subexpressions of a potentially-evaluated
-// expression.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
-#define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/StmtVisitor.h"
-
-namespace clang {
-
-class ASTContext;
-
-/// \brief Given a potentially-evaluated expression, this visitor visits all
-/// of its potentially-evaluated subexpressions, recursively.
-template<template <typename> class Ptr, typename ImplClass>
-class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> {
-protected:
- const ASTContext &Context;
-
-public:
-#define PTR(CLASS) typename Ptr<CLASS>::type
-
- explicit EvaluatedExprVisitorBase(const ASTContext &Context) : Context(Context) { }
-
- // Expressions that have no potentially-evaluated subexpressions (but may have
- // other sub-expressions).
- void VisitDeclRefExpr(PTR(DeclRefExpr) E) { }
- void VisitOffsetOfExpr(PTR(OffsetOfExpr) E) { }
- void VisitUnaryExprOrTypeTraitExpr(PTR(UnaryExprOrTypeTraitExpr) E) { }
- void VisitExpressionTraitExpr(PTR(ExpressionTraitExpr) E) { }
- void VisitBlockExpr(PTR(BlockExpr) E) { }
- void VisitCXXUuidofExpr(PTR(CXXUuidofExpr) E) { }
- void VisitCXXNoexceptExpr(PTR(CXXNoexceptExpr) E) { }
-
- void VisitMemberExpr(PTR(MemberExpr) E) {
- // Only the base matters.
- return this->Visit(E->getBase());
- }
-
- void VisitChooseExpr(PTR(ChooseExpr) E) {
- // Don't visit either child expression if the condition is dependent.
- if (E->getCond()->isValueDependent())
- return;
- // Only the selected subexpression matters; the other one is not evaluated.
- return this->Visit(E->getChosenSubExpr());
- }
-
- void VisitGenericSelectionExpr(PTR(GenericSelectionExpr) E) {
- // The controlling expression of a generic selection is not evaluated.
-
- // Don't visit either child expression if the condition is type-dependent.
- if (E->isResultDependent())
- return;
- // Only the selected subexpression matters; the other subexpressions and the
- // controlling expression are not evaluated.
- return this->Visit(E->getResultExpr());
- }
-
- void VisitDesignatedInitExpr(PTR(DesignatedInitExpr) E) {
- // Only the actual initializer matters; the designators are all constant
- // expressions.
- return this->Visit(E->getInit());
- }
-
- void VisitCXXTypeidExpr(PTR(CXXTypeidExpr) E) {
- if (E->isPotentiallyEvaluated())
- return this->Visit(E->getExprOperand());
- }
-
- void VisitCallExpr(PTR(CallExpr) CE) {
- if (!CE->isUnevaluatedBuiltinCall(Context))
- return static_cast<ImplClass*>(this)->VisitExpr(CE);
- }
-
- void VisitLambdaExpr(PTR(LambdaExpr) LE) {
- // Only visit the capture initializers, and not the body.
- for (LambdaExpr::const_capture_init_iterator I = LE->capture_init_begin(),
- E = LE->capture_init_end();
- I != E; ++I)
- if (*I)
- this->Visit(*I);
- }
-
- /// \brief The basis case walks all of the children of the statement or
- /// expression, assuming they are all potentially evaluated.
- void VisitStmt(PTR(Stmt) S) {
- for (auto *SubStmt : S->children())
- if (SubStmt)
- this->Visit(SubStmt);
- }
-
-#undef PTR
-};
-
-/// EvaluatedExprVisitor - This class visits 'Expr *'s
-template<typename ImplClass>
-class EvaluatedExprVisitor
- : public EvaluatedExprVisitorBase<make_ptr, ImplClass> {
-public:
- explicit EvaluatedExprVisitor(const ASTContext &Context) :
- EvaluatedExprVisitorBase<make_ptr, ImplClass>(Context) { }
-};
-
-/// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
-template<typename ImplClass>
-class ConstEvaluatedExprVisitor
- : public EvaluatedExprVisitorBase<make_const_ptr, ImplClass> {
-public:
- explicit ConstEvaluatedExprVisitor(const ASTContext &Context) :
- EvaluatedExprVisitorBase<make_const_ptr, ImplClass>(Context) { }
-};
-
-}
-
-#endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
deleted file mode 100644
index 095dd6a..0000000
--- a/include/clang/AST/Expr.h
+++ /dev/null
@@ -1,4941 +0,0 @@
-//===--- Expr.h - Classes for representing expressions ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Expr interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPR_H
-#define LLVM_CLANG_AST_EXPR_H
-
-#include "clang/AST/APValue.h"
-#include "clang/AST/ASTVector.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclAccessPair.h"
-#include "clang/AST/OperationKinds.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/TypeTraits.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
- class APValue;
- class ASTContext;
- class BlockDecl;
- class CXXBaseSpecifier;
- class CXXMemberCallExpr;
- class CXXOperatorCallExpr;
- class CastExpr;
- class Decl;
- class IdentifierInfo;
- class MaterializeTemporaryExpr;
- class NamedDecl;
- class ObjCPropertyRefExpr;
- class OpaqueValueExpr;
- class ParmVarDecl;
- class StringLiteral;
- class TargetInfo;
- class ValueDecl;
-
-/// \brief A simple array of base specifiers.
-typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
-
-/// \brief An adjustment to be made to the temporary created when emitting a
-/// reference binding, which accesses a particular subobject of that temporary.
-struct SubobjectAdjustment {
- enum {
- DerivedToBaseAdjustment,
- FieldAdjustment,
- MemberPointerAdjustment
- } Kind;
-
- struct DTB {
- const CastExpr *BasePath;
- const CXXRecordDecl *DerivedClass;
- };
-
- struct P {
- const MemberPointerType *MPT;
- Expr *RHS;
- };
-
- union {
- struct DTB DerivedToBase;
- FieldDecl *Field;
- struct P Ptr;
- };
-
- SubobjectAdjustment(const CastExpr *BasePath,
- const CXXRecordDecl *DerivedClass)
- : Kind(DerivedToBaseAdjustment) {
- DerivedToBase.BasePath = BasePath;
- DerivedToBase.DerivedClass = DerivedClass;
- }
-
- SubobjectAdjustment(FieldDecl *Field)
- : Kind(FieldAdjustment) {
- this->Field = Field;
- }
-
- SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS)
- : Kind(MemberPointerAdjustment) {
- this->Ptr.MPT = MPT;
- this->Ptr.RHS = RHS;
- }
-};
-
-/// Expr - This represents one expression. Note that Expr's are subclasses of
-/// Stmt. This allows an expression to be transparently used any place a Stmt
-/// is required.
-///
-class Expr : public Stmt {
- QualType TR;
-
-protected:
- Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK,
- bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack)
- : Stmt(SC)
- {
- ExprBits.TypeDependent = TD;
- ExprBits.ValueDependent = VD;
- ExprBits.InstantiationDependent = ID;
- ExprBits.ValueKind = VK;
- ExprBits.ObjectKind = OK;
- ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
- setType(T);
- }
-
- /// \brief Construct an empty expression.
- explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { }
-
-public:
- QualType getType() const { return TR; }
- void setType(QualType t) {
- // In C++, the type of an expression is always adjusted so that it
- // will not have reference type (C++ [expr]p6). Use
- // QualType::getNonReferenceType() to retrieve the non-reference
- // type. Additionally, inspect Expr::isLvalue to determine whether
- // an expression that is adjusted in this manner should be
- // considered an lvalue.
- assert((t.isNull() || !t->isReferenceType()) &&
- "Expressions can't have reference type");
-
- TR = t;
- }
-
- /// isValueDependent - Determines whether this expression is
- /// value-dependent (C++ [temp.dep.constexpr]). For example, the
- /// array bound of "Chars" in the following example is
- /// value-dependent.
- /// @code
- /// template<int Size, char (&Chars)[Size]> struct meta_string;
- /// @endcode
- bool isValueDependent() const { return ExprBits.ValueDependent; }
-
- /// \brief Set whether this expression is value-dependent or not.
- void setValueDependent(bool VD) {
- ExprBits.ValueDependent = VD;
- }
-
- /// isTypeDependent - Determines whether this expression is
- /// type-dependent (C++ [temp.dep.expr]), which means that its type
- /// could change from one template instantiation to the next. For
- /// example, the expressions "x" and "x + y" are type-dependent in
- /// the following code, but "y" is not type-dependent:
- /// @code
- /// template<typename T>
- /// void add(T x, int y) {
- /// x + y;
- /// }
- /// @endcode
- bool isTypeDependent() const { return ExprBits.TypeDependent; }
-
- /// \brief Set whether this expression is type-dependent or not.
- void setTypeDependent(bool TD) {
- ExprBits.TypeDependent = TD;
- }
-
- /// \brief Whether this expression is instantiation-dependent, meaning that
- /// it depends in some way on a template parameter, even if neither its type
- /// nor (constant) value can change due to the template instantiation.
- ///
- /// In the following example, the expression \c sizeof(sizeof(T() + T())) is
- /// instantiation-dependent (since it involves a template parameter \c T), but
- /// is neither type- nor value-dependent, since the type of the inner
- /// \c sizeof is known (\c std::size_t) and therefore the size of the outer
- /// \c sizeof is known.
- ///
- /// \code
- /// template<typename T>
- /// void f(T x, T y) {
- /// sizeof(sizeof(T() + T());
- /// }
- /// \endcode
- ///
- bool isInstantiationDependent() const {
- return ExprBits.InstantiationDependent;
- }
-
- /// \brief Set whether this expression is instantiation-dependent or not.
- void setInstantiationDependent(bool ID) {
- ExprBits.InstantiationDependent = ID;
- }
-
- /// \brief Whether this expression contains an unexpanded parameter
- /// pack (for C++11 variadic templates).
- ///
- /// Given the following function template:
- ///
- /// \code
- /// template<typename F, typename ...Types>
- /// void forward(const F &f, Types &&...args) {
- /// f(static_cast<Types&&>(args)...);
- /// }
- /// \endcode
- ///
- /// The expressions \c args and \c static_cast<Types&&>(args) both
- /// contain parameter packs.
- bool containsUnexpandedParameterPack() const {
- return ExprBits.ContainsUnexpandedParameterPack;
- }
-
- /// \brief Set the bit that describes whether this expression
- /// contains an unexpanded parameter pack.
- void setContainsUnexpandedParameterPack(bool PP = true) {
- ExprBits.ContainsUnexpandedParameterPack = PP;
- }
-
- /// getExprLoc - Return the preferred location for the arrow when diagnosing
- /// a problem with a generic expression.
- SourceLocation getExprLoc() const LLVM_READONLY;
-
- /// isUnusedResultAWarning - Return true if this immediate expression should
- /// be warned about if the result is unused. If so, fill in expr, location,
- /// and ranges with expr to warn on and source locations/ranges appropriate
- /// for a warning.
- bool isUnusedResultAWarning(const Expr *&WarnExpr, SourceLocation &Loc,
- SourceRange &R1, SourceRange &R2,
- ASTContext &Ctx) const;
-
- /// isLValue - True if this expression is an "l-value" according to
- /// the rules of the current language. C and C++ give somewhat
- /// different rules for this concept, but in general, the result of
- /// an l-value expression identifies a specific object whereas the
- /// result of an r-value expression is a value detached from any
- /// specific storage.
- ///
- /// C++11 divides the concept of "r-value" into pure r-values
- /// ("pr-values") and so-called expiring values ("x-values"), which
- /// identify specific objects that can be safely cannibalized for
- /// their resources. This is an unfortunate abuse of terminology on
- /// the part of the C++ committee. In Clang, when we say "r-value",
- /// we generally mean a pr-value.
- bool isLValue() const { return getValueKind() == VK_LValue; }
- bool isRValue() const { return getValueKind() == VK_RValue; }
- bool isXValue() const { return getValueKind() == VK_XValue; }
- bool isGLValue() const { return getValueKind() != VK_RValue; }
-
- enum LValueClassification {
- LV_Valid,
- LV_NotObjectType,
- LV_IncompleteVoidType,
- LV_DuplicateVectorComponents,
- LV_InvalidExpression,
- LV_InvalidMessageExpression,
- LV_MemberFunction,
- LV_SubObjCPropertySetting,
- LV_ClassTemporary,
- LV_ArrayTemporary
- };
- /// Reasons why an expression might not be an l-value.
- LValueClassification ClassifyLValue(ASTContext &Ctx) const;
-
- enum isModifiableLvalueResult {
- MLV_Valid,
- MLV_NotObjectType,
- MLV_IncompleteVoidType,
- MLV_DuplicateVectorComponents,
- MLV_InvalidExpression,
- MLV_LValueCast, // Specialized form of MLV_InvalidExpression.
- MLV_IncompleteType,
- MLV_ConstQualified,
- MLV_ConstAddrSpace,
- MLV_ArrayType,
- MLV_NoSetterProperty,
- MLV_MemberFunction,
- MLV_SubObjCPropertySetting,
- MLV_InvalidMessageExpression,
- MLV_ClassTemporary,
- MLV_ArrayTemporary
- };
- /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
- /// does not have an incomplete type, does not have a const-qualified type,
- /// and if it is a structure or union, does not have any member (including,
- /// recursively, any member or element of all contained aggregates or unions)
- /// with a const-qualified type.
- ///
- /// \param Loc [in,out] - A source location which *may* be filled
- /// in with the location of the expression making this a
- /// non-modifiable lvalue, if specified.
- isModifiableLvalueResult
- isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = nullptr) const;
-
- /// \brief The return type of classify(). Represents the C++11 expression
- /// taxonomy.
- class Classification {
- public:
- /// \brief The various classification results. Most of these mean prvalue.
- enum Kinds {
- CL_LValue,
- CL_XValue,
- CL_Function, // Functions cannot be lvalues in C.
- CL_Void, // Void cannot be an lvalue in C.
- CL_AddressableVoid, // Void expression whose address can be taken in C.
- CL_DuplicateVectorComponents, // A vector shuffle with dupes.
- CL_MemberFunction, // An expression referring to a member function
- CL_SubObjCPropertySetting,
- CL_ClassTemporary, // A temporary of class type, or subobject thereof.
- CL_ArrayTemporary, // A temporary of array type.
- CL_ObjCMessageRValue, // ObjC message is an rvalue
- CL_PRValue // A prvalue for any other reason, of any other type
- };
- /// \brief The results of modification testing.
- enum ModifiableType {
- CM_Untested, // testModifiable was false.
- CM_Modifiable,
- CM_RValue, // Not modifiable because it's an rvalue
- CM_Function, // Not modifiable because it's a function; C++ only
- CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
- CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
- CM_ConstQualified,
- CM_ConstAddrSpace,
- CM_ArrayType,
- CM_IncompleteType
- };
-
- private:
- friend class Expr;
-
- unsigned short Kind;
- unsigned short Modifiable;
-
- explicit Classification(Kinds k, ModifiableType m)
- : Kind(k), Modifiable(m)
- {}
-
- public:
- Classification() {}
-
- Kinds getKind() const { return static_cast<Kinds>(Kind); }
- ModifiableType getModifiable() const {
- assert(Modifiable != CM_Untested && "Did not test for modifiability.");
- return static_cast<ModifiableType>(Modifiable);
- }
- bool isLValue() const { return Kind == CL_LValue; }
- bool isXValue() const { return Kind == CL_XValue; }
- bool isGLValue() const { return Kind <= CL_XValue; }
- bool isPRValue() const { return Kind >= CL_Function; }
- bool isRValue() const { return Kind >= CL_XValue; }
- bool isModifiable() const { return getModifiable() == CM_Modifiable; }
-
- /// \brief Create a simple, modifiably lvalue
- static Classification makeSimpleLValue() {
- return Classification(CL_LValue, CM_Modifiable);
- }
-
- };
- /// \brief Classify - Classify this expression according to the C++11
- /// expression taxonomy.
- ///
- /// C++11 defines ([basic.lval]) a new taxonomy of expressions to replace the
- /// old lvalue vs rvalue. This function determines the type of expression this
- /// is. There are three expression types:
- /// - lvalues are classical lvalues as in C++03.
- /// - prvalues are equivalent to rvalues in C++03.
- /// - xvalues are expressions yielding unnamed rvalue references, e.g. a
- /// function returning an rvalue reference.
- /// lvalues and xvalues are collectively referred to as glvalues, while
- /// prvalues and xvalues together form rvalues.
- Classification Classify(ASTContext &Ctx) const {
- return ClassifyImpl(Ctx, nullptr);
- }
-
- /// \brief ClassifyModifiable - Classify this expression according to the
- /// C++11 expression taxonomy, and see if it is valid on the left side
- /// of an assignment.
- ///
- /// This function extends classify in that it also tests whether the
- /// expression is modifiable (C99 6.3.2.1p1).
- /// \param Loc A source location that might be filled with a relevant location
- /// if the expression is not modifiable.
- Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const{
- return ClassifyImpl(Ctx, &Loc);
- }
-
- /// getValueKindForType - Given a formal return or parameter type,
- /// give its value kind.
- static ExprValueKind getValueKindForType(QualType T) {
- if (const ReferenceType *RT = T->getAs<ReferenceType>())
- return (isa<LValueReferenceType>(RT)
- ? VK_LValue
- : (RT->getPointeeType()->isFunctionType()
- ? VK_LValue : VK_XValue));
- return VK_RValue;
- }
-
- /// getValueKind - The value kind that this expression produces.
- ExprValueKind getValueKind() const {
- return static_cast<ExprValueKind>(ExprBits.ValueKind);
- }
-
- /// getObjectKind - The object kind that this expression produces.
- /// Object kinds are meaningful only for expressions that yield an
- /// l-value or x-value.
- ExprObjectKind getObjectKind() const {
- return static_cast<ExprObjectKind>(ExprBits.ObjectKind);
- }
-
- bool isOrdinaryOrBitFieldObject() const {
- ExprObjectKind OK = getObjectKind();
- return (OK == OK_Ordinary || OK == OK_BitField);
- }
-
- /// setValueKind - Set the value kind produced by this expression.
- void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; }
-
- /// setObjectKind - Set the object kind produced by this expression.
- void setObjectKind(ExprObjectKind Cat) { ExprBits.ObjectKind = Cat; }
-
-private:
- Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const;
-
-public:
-
- /// \brief Returns true if this expression is a gl-value that
- /// potentially refers to a bit-field.
- ///
- /// In C++, whether a gl-value refers to a bitfield is essentially
- /// an aspect of the value-kind type system.
- bool refersToBitField() const { return getObjectKind() == OK_BitField; }
-
- /// \brief If this expression refers to a bit-field, retrieve the
- /// declaration of that bit-field.
- ///
- /// Note that this returns a non-null pointer in subtly different
- /// places than refersToBitField returns true. In particular, this can
- /// return a non-null pointer even for r-values loaded from
- /// bit-fields, but it will return null for a conditional bit-field.
- FieldDecl *getSourceBitField();
-
- const FieldDecl *getSourceBitField() const {
- return const_cast<Expr*>(this)->getSourceBitField();
- }
-
- /// \brief If this expression is an l-value for an Objective C
- /// property, find the underlying property reference expression.
- const ObjCPropertyRefExpr *getObjCProperty() const;
-
- /// \brief Check if this expression is the ObjC 'self' implicit parameter.
- bool isObjCSelfExpr() const;
-
- /// \brief Returns whether this expression refers to a vector element.
- bool refersToVectorElement() const;
-
- /// \brief Returns whether this expression refers to a global register
- /// variable.
- bool refersToGlobalRegisterVar() const;
-
- /// \brief Returns whether this expression has a placeholder type.
- bool hasPlaceholderType() const {
- return getType()->isPlaceholderType();
- }
-
- /// \brief Returns whether this expression has a specific placeholder type.
- bool hasPlaceholderType(BuiltinType::Kind K) const {
- assert(BuiltinType::isPlaceholderTypeKind(K));
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(getType()))
- return BT->getKind() == K;
- return false;
- }
-
- /// isKnownToHaveBooleanValue - Return true if this is an integer expression
- /// that is known to return 0 or 1. This happens for _Bool/bool expressions
- /// but also int expressions which are produced by things like comparisons in
- /// C.
- bool isKnownToHaveBooleanValue() const;
-
- /// isIntegerConstantExpr - Return true if this expression is a valid integer
- /// constant expression, and, if so, return its value in Result. If not a
- /// valid i-c-e, return false and fill in Loc (if specified) with the location
- /// of the invalid expression.
- ///
- /// Note: This does not perform the implicit conversions required by C++11
- /// [expr.const]p5.
- bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx,
- SourceLocation *Loc = nullptr,
- bool isEvaluated = true) const;
- bool isIntegerConstantExpr(const ASTContext &Ctx,
- SourceLocation *Loc = nullptr) const;
-
- /// isCXX98IntegralConstantExpr - Return true if this expression is an
- /// integral constant expression in C++98. Can only be used in C++.
- bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const;
-
- /// isCXX11ConstantExpr - Return true if this expression is a constant
- /// expression in C++11. Can only be used in C++.
- ///
- /// Note: This does not perform the implicit conversions required by C++11
- /// [expr.const]p5.
- bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = nullptr,
- SourceLocation *Loc = nullptr) const;
-
- /// isPotentialConstantExpr - Return true if this function's definition
- /// might be usable in a constant expression in C++11, if it were marked
- /// constexpr. Return false if the function can never produce a constant
- /// expression, along with diagnostics describing why not.
- static bool isPotentialConstantExpr(const FunctionDecl *FD,
- SmallVectorImpl<
- PartialDiagnosticAt> &Diags);
-
- /// isPotentialConstantExprUnevaluted - Return true if this expression might
- /// be usable in a constant expression in C++11 in an unevaluated context, if
- /// it were in function FD marked constexpr. Return false if the function can
- /// never produce a constant expression, along with diagnostics describing
- /// why not.
- static bool isPotentialConstantExprUnevaluated(Expr *E,
- const FunctionDecl *FD,
- SmallVectorImpl<
- PartialDiagnosticAt> &Diags);
-
- /// isConstantInitializer - Returns true if this expression can be emitted to
- /// IR as a constant, and thus can be used as a constant initializer in C.
- /// If this expression is not constant and Culprit is non-null,
- /// it is used to store the address of first non constant expr.
- bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
- const Expr **Culprit = nullptr) const;
-
- /// EvalStatus is a struct with detailed info about an evaluation in progress.
- struct EvalStatus {
- /// \brief Whether the evaluated expression has side effects.
- /// For example, (f() && 0) can be folded, but it still has side effects.
- bool HasSideEffects;
-
- /// \brief Whether the evaluation hit undefined behavior.
- /// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
- /// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
- bool HasUndefinedBehavior;
-
- /// Diag - If this is non-null, it will be filled in with a stack of notes
- /// indicating why evaluation failed (or why it failed to produce a constant
- /// expression).
- /// If the expression is unfoldable, the notes will indicate why it's not
- /// foldable. If the expression is foldable, but not a constant expression,
- /// the notes will describes why it isn't a constant expression. If the
- /// expression *is* a constant expression, no notes will be produced.
- SmallVectorImpl<PartialDiagnosticAt> *Diag;
-
- EvalStatus()
- : HasSideEffects(false), HasUndefinedBehavior(false), Diag(nullptr) {}
-
- // hasSideEffects - Return true if the evaluated expression has
- // side effects.
- bool hasSideEffects() const {
- return HasSideEffects;
- }
- };
-
- /// EvalResult is a struct with detailed info about an evaluated expression.
- struct EvalResult : EvalStatus {
- /// Val - This is the value the expression can be folded to.
- APValue Val;
-
- // isGlobalLValue - Return true if the evaluated lvalue expression
- // is global.
- bool isGlobalLValue() const;
- };
-
- /// EvaluateAsRValue - Return true if this is a constant which we can fold to
- /// an rvalue using any crazy technique (that has nothing to do with language
- /// standards) that we want to, even if the expression has side-effects. If
- /// this function returns true, it returns the folded constant in Result. If
- /// the expression is a glvalue, an lvalue-to-rvalue conversion will be
- /// applied.
- bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const;
-
- /// EvaluateAsBooleanCondition - Return true if this is a constant
- /// which we we can fold and convert to a boolean condition using
- /// any crazy technique that we want to, even if the expression has
- /// side-effects.
- bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const;
-
- enum SideEffectsKind {
- SE_NoSideEffects, ///< Strictly evaluate the expression.
- SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not
- ///< arbitrary unmodeled side effects.
- SE_AllowSideEffects ///< Allow any unmodeled side effect.
- };
-
- /// EvaluateAsInt - Return true if this is a constant which we can fold and
- /// convert to an integer, using any crazy technique that we want to.
- bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,
- SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
-
- /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
- /// constant folded without side-effects, but discard the result.
- bool isEvaluatable(const ASTContext &Ctx,
- SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
-
- /// HasSideEffects - This routine returns true for all those expressions
- /// which have any effect other than producing a value. Example is a function
- /// call, volatile variable read, or throwing an exception. If
- /// IncludePossibleEffects is false, this call treats certain expressions with
- /// potential side effects (such as function call-like expressions,
- /// instantiation-dependent expressions, or invocations from a macro) as not
- /// having side effects.
- bool HasSideEffects(const ASTContext &Ctx,
- bool IncludePossibleEffects = true) const;
-
- /// \brief Determine whether this expression involves a call to any function
- /// that is not trivial.
- bool hasNonTrivialCall(const ASTContext &Ctx) const;
-
- /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
- /// integer. This must be called on an expression that constant folds to an
- /// integer.
- llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
- SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
-
- void EvaluateForOverflow(const ASTContext &Ctx) const;
-
- /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an
- /// lvalue with link time known address, with no side-effects.
- bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const;
-
- /// EvaluateAsInitializer - Evaluate an expression as if it were the
- /// initializer of the given declaration. Returns true if the initializer
- /// can be folded to a constant, and produces any relevant notes. In C++11,
- /// notes will be produced if the expression is not a constant expression.
- bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx,
- const VarDecl *VD,
- SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
-
- /// EvaluateWithSubstitution - Evaluate an expression as if from the context
- /// of a call to the given function with the given arguments, inside an
- /// unevaluated context. Returns true if the expression could be folded to a
- /// constant.
- bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
- const FunctionDecl *Callee,
- ArrayRef<const Expr*> Args) const;
-
- /// \brief If the current Expr is a pointer, this will try to statically
- /// determine the number of bytes available where the pointer is pointing.
- /// Returns true if all of the above holds and we were able to figure out the
- /// size, false otherwise.
- ///
- /// \param Type - How to evaluate the size of the Expr, as defined by the
- /// "type" parameter of __builtin_object_size
- bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
- unsigned Type) const;
-
- /// \brief Enumeration used to describe the kind of Null pointer constant
- /// returned from \c isNullPointerConstant().
- enum NullPointerConstantKind {
- /// \brief Expression is not a Null pointer constant.
- NPCK_NotNull = 0,
-
- /// \brief Expression is a Null pointer constant built from a zero integer
- /// expression that is not a simple, possibly parenthesized, zero literal.
- /// C++ Core Issue 903 will classify these expressions as "not pointers"
- /// once it is adopted.
- /// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903
- NPCK_ZeroExpression,
-
- /// \brief Expression is a Null pointer constant built from a literal zero.
- NPCK_ZeroLiteral,
-
- /// \brief Expression is a C++11 nullptr.
- NPCK_CXX11_nullptr,
-
- /// \brief Expression is a GNU-style __null constant.
- NPCK_GNUNull
- };
-
- /// \brief Enumeration used to describe how \c isNullPointerConstant()
- /// should cope with value-dependent expressions.
- enum NullPointerConstantValueDependence {
- /// \brief Specifies that the expression should never be value-dependent.
- NPC_NeverValueDependent = 0,
-
- /// \brief Specifies that a value-dependent expression of integral or
- /// dependent type should be considered a null pointer constant.
- NPC_ValueDependentIsNull,
-
- /// \brief Specifies that a value-dependent expression should be considered
- /// to never be a null pointer constant.
- NPC_ValueDependentIsNotNull
- };
-
- /// isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to
- /// a Null pointer constant. The return value can further distinguish the
- /// kind of NULL pointer constant that was detected.
- NullPointerConstantKind isNullPointerConstant(
- ASTContext &Ctx,
- NullPointerConstantValueDependence NPC) const;
-
- /// isOBJCGCCandidate - Return true if this expression may be used in a read/
- /// write barrier.
- bool isOBJCGCCandidate(ASTContext &Ctx) const;
-
- /// \brief Returns true if this expression is a bound member function.
- bool isBoundMemberFunction(ASTContext &Ctx) const;
-
- /// \brief Given an expression of bound-member type, find the type
- /// of the member. Returns null if this is an *overloaded* bound
- /// member expression.
- static QualType findBoundMemberType(const Expr *expr);
-
- /// IgnoreImpCasts - Skip past any implicit casts which might
- /// surround this expression. Only skips ImplicitCastExprs.
- Expr *IgnoreImpCasts() LLVM_READONLY;
-
- /// IgnoreImplicit - Skip past any implicit AST nodes which might
- /// surround this expression.
- Expr *IgnoreImplicit() LLVM_READONLY {
- return cast<Expr>(Stmt::IgnoreImplicit());
- }
-
- const Expr *IgnoreImplicit() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreImplicit();
- }
-
- /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return
- /// its subexpression. If that subexpression is also a ParenExpr,
- /// then this method recursively returns its subexpression, and so forth.
- /// Otherwise, the method returns the current Expr.
- Expr *IgnoreParens() LLVM_READONLY;
-
- /// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
- /// or CastExprs, returning their operand.
- Expr *IgnoreParenCasts() LLVM_READONLY;
-
- /// Ignore casts. Strip off any CastExprs, returning their operand.
- Expr *IgnoreCasts() LLVM_READONLY;
-
- /// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
- /// any ParenExpr or ImplicitCastExprs, returning their operand.
- Expr *IgnoreParenImpCasts() LLVM_READONLY;
-
- /// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a
- /// call to a conversion operator, return the argument.
- Expr *IgnoreConversionOperator() LLVM_READONLY;
-
- const Expr *IgnoreConversionOperator() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreConversionOperator();
- }
-
- const Expr *IgnoreParenImpCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenImpCasts();
- }
-
- /// Ignore parentheses and lvalue casts. Strip off any ParenExpr and
- /// CastExprs that represent lvalue casts, returning their operand.
- Expr *IgnoreParenLValueCasts() LLVM_READONLY;
-
- const Expr *IgnoreParenLValueCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenLValueCasts();
- }
-
- /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
- /// value (including ptr->int casts of the same size). Strip off any
- /// ParenExpr or CastExprs, returning their operand.
- Expr *IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY;
-
- /// Ignore parentheses and derived-to-base casts.
- Expr *ignoreParenBaseCasts() LLVM_READONLY;
-
- const Expr *ignoreParenBaseCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->ignoreParenBaseCasts();
- }
-
- /// \brief Determine whether this expression is a default function argument.
- ///
- /// Default arguments are implicitly generated in the abstract syntax tree
- /// by semantic analysis for function calls, object constructions, etc. in
- /// C++. Default arguments are represented by \c CXXDefaultArgExpr nodes;
- /// this routine also looks through any implicit casts to determine whether
- /// the expression is a default argument.
- bool isDefaultArgument() const;
-
- /// \brief Determine whether the result of this expression is a
- /// temporary object of the given class type.
- bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const;
-
- /// \brief Whether this expression is an implicit reference to 'this' in C++.
- bool isImplicitCXXThis() const;
-
- const Expr *IgnoreImpCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreImpCasts();
- }
- const Expr *IgnoreParens() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParens();
- }
- const Expr *IgnoreParenCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenCasts();
- }
- /// Strip off casts, but keep parentheses.
- const Expr *IgnoreCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreCasts();
- }
-
- const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
- }
-
- static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs);
-
- /// \brief For an expression of class type or pointer to class type,
- /// return the most derived class decl the expression is known to refer to.
- ///
- /// If this expression is a cast, this method looks through it to find the
- /// most derived decl that can be inferred from the expression.
- /// This is valid because derived-to-base conversions have undefined
- /// behavior if the object isn't dynamically of the derived type.
- const CXXRecordDecl *getBestDynamicClassType() const;
-
- /// Walk outwards from an expression we want to bind a reference to and
- /// find the expression whose lifetime needs to be extended. Record
- /// the LHSs of comma expressions and adjustments needed along the path.
- const Expr *skipRValueSubobjectAdjustments(
- SmallVectorImpl<const Expr *> &CommaLHS,
- SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstExprConstant &&
- T->getStmtClass() <= lastExprConstant;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// Primary Expressions.
-//===----------------------------------------------------------------------===//
-
-/// OpaqueValueExpr - An expression referring to an opaque object of a
-/// fixed type and value class. These don't correspond to concrete
-/// syntax; instead they're used to express operations (usually copy
-/// operations) on values whose source is generally obvious from
-/// context.
-class OpaqueValueExpr : public Expr {
- friend class ASTStmtReader;
- Expr *SourceExpr;
- SourceLocation Loc;
-
-public:
- OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
- ExprObjectKind OK = OK_Ordinary,
- Expr *SourceExpr = nullptr)
- : Expr(OpaqueValueExprClass, T, VK, OK,
- T->isDependentType(),
- T->isDependentType() ||
- (SourceExpr && SourceExpr->isValueDependent()),
- T->isInstantiationDependentType(),
- false),
- SourceExpr(SourceExpr), Loc(Loc) {
- }
-
- /// Given an expression which invokes a copy constructor --- i.e. a
- /// CXXConstructExpr, possibly wrapped in an ExprWithCleanups ---
- /// find the OpaqueValueExpr that's the source of the construction.
- static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr);
-
- explicit OpaqueValueExpr(EmptyShell Empty)
- : Expr(OpaqueValueExprClass, Empty) { }
-
- /// \brief Retrieve the location of this expression.
- SourceLocation getLocation() const { return Loc; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getLocStart() : Loc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SourceExpr ? SourceExpr->getLocEnd() : Loc;
- }
- SourceLocation getExprLoc() const LLVM_READONLY {
- if (SourceExpr) return SourceExpr->getExprLoc();
- return Loc;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- /// The source expression of an opaque value expression is the
- /// expression which originally generated the value. This is
- /// provided as a convenience for analyses that don't wish to
- /// precisely model the execution behavior of the program.
- ///
- /// The source expression is typically set when building the
- /// expression which binds the opaque value expression in the first
- /// place.
- Expr *getSourceExpr() const { return SourceExpr; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OpaqueValueExprClass;
- }
-};
-
-/// \brief A reference to a declared variable, function, enum, etc.
-/// [C99 6.5.1p2]
-///
-/// This encodes all the information about how a declaration is referenced
-/// within an expression.
-///
-/// There are several optional constructs attached to DeclRefExprs only when
-/// they apply in order to conserve memory. These are laid out past the end of
-/// the object, and flags in the DeclRefExprBitfield track whether they exist:
-///
-/// DeclRefExprBits.HasQualifier:
-/// Specifies when this declaration reference expression has a C++
-/// nested-name-specifier.
-/// DeclRefExprBits.HasFoundDecl:
-/// Specifies when this declaration reference expression has a record of
-/// a NamedDecl (different from the referenced ValueDecl) which was found
-/// during name lookup and/or overload resolution.
-/// DeclRefExprBits.HasTemplateKWAndArgsInfo:
-/// Specifies when this declaration reference expression has an explicit
-/// C++ template keyword and/or template argument list.
-/// DeclRefExprBits.RefersToEnclosingVariableOrCapture
-/// Specifies when this declaration reference expression (validly)
-/// refers to an enclosed local or a captured variable.
-class DeclRefExpr final
- : public Expr,
- private llvm::TrailingObjects<DeclRefExpr, NestedNameSpecifierLoc,
- NamedDecl *, ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// \brief The declaration that we are referencing.
- ValueDecl *D;
-
- /// \brief The location of the declaration name itself.
- SourceLocation Loc;
-
- /// \brief Provides source/type location info for the declaration name
- /// embedded in D.
- DeclarationNameLoc DNLoc;
-
- size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
- return hasQualifier() ? 1 : 0;
- }
-
- size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
- return hasFoundDecl() ? 1 : 0;
- }
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return hasTemplateKWAndArgsInfo() ? 1 : 0;
- }
-
- /// \brief Test whether there is a distinct FoundDecl attached to the end of
- /// this DRE.
- bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
-
- DeclRefExpr(const ASTContext &Ctx,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D, bool RefersToEnlosingVariableOrCapture,
- const DeclarationNameInfo &NameInfo,
- NamedDecl *FoundD,
- const TemplateArgumentListInfo *TemplateArgs,
- QualType T, ExprValueKind VK);
-
- /// \brief Construct an empty declaration reference expression.
- explicit DeclRefExpr(EmptyShell Empty)
- : Expr(DeclRefExprClass, Empty) { }
-
- /// \brief Computes the type- and value-dependence flags for this
- /// declaration reference expression.
- void computeDependence(const ASTContext &C);
-
-public:
- DeclRefExpr(ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T,
- ExprValueKind VK, SourceLocation L,
- const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
- : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
- D(D), Loc(L), DNLoc(LocInfo) {
- DeclRefExprBits.HasQualifier = 0;
- DeclRefExprBits.HasTemplateKWAndArgsInfo = 0;
- DeclRefExprBits.HasFoundDecl = 0;
- DeclRefExprBits.HadMultipleCandidates = 0;
- DeclRefExprBits.RefersToEnclosingVariableOrCapture =
- RefersToEnclosingVariableOrCapture;
- computeDependence(D->getASTContext());
- }
-
- static DeclRefExpr *
- Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *D,
- bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc,
- QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr,
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
-
- static DeclRefExpr *
- Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *D,
- bool RefersToEnclosingVariableOrCapture,
- const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
- NamedDecl *FoundD = nullptr,
- const TemplateArgumentListInfo *TemplateArgs = nullptr);
-
- /// \brief Construct an empty declaration reference expression.
- static DeclRefExpr *CreateEmpty(const ASTContext &Context,
- bool HasQualifier,
- bool HasFoundDecl,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- ValueDecl *getDecl() { return D; }
- const ValueDecl *getDecl() const { return D; }
- void setDecl(ValueDecl *NewD) { D = NewD; }
-
- DeclarationNameInfo getNameInfo() const {
- return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc);
- }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- /// \brief Determine whether this declaration reference was preceded by a
- /// C++ nested-name-specifier, e.g., \c N::foo.
- bool hasQualifier() const { return DeclRefExprBits.HasQualifier; }
-
- /// \brief If the name was qualified, retrieves the nested-name-specifier
- /// that precedes the name, with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const {
- if (!hasQualifier())
- return NestedNameSpecifierLoc();
- return *getTrailingObjects<NestedNameSpecifierLoc>();
- }
-
- /// \brief If the name was qualified, retrieves the nested-name-specifier
- /// that precedes the name. Otherwise, returns NULL.
- NestedNameSpecifier *getQualifier() const {
- return getQualifierLoc().getNestedNameSpecifier();
- }
-
- /// \brief Get the NamedDecl through which this reference occurred.
- ///
- /// This Decl may be different from the ValueDecl actually referred to in the
- /// presence of using declarations, etc. It always returns non-NULL, and may
- /// simple return the ValueDecl when appropriate.
-
- NamedDecl *getFoundDecl() {
- return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
- }
-
- /// \brief Get the NamedDecl through which this reference occurred.
- /// See non-const variant.
- const NamedDecl *getFoundDecl() const {
- return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D;
- }
-
- bool hasTemplateKWAndArgsInfo() const {
- return DeclRefExprBits.HasTemplateKWAndArgsInfo;
- }
-
- /// \brief Retrieve the location of the template keyword preceding
- /// this name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
- }
-
- /// \brief Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the name, if any.
- SourceLocation getLAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
- }
-
- /// \brief Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the name, if any.
- SourceLocation getRAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
-
- /// \brief Determines whether the name in this declaration reference
- /// was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// \brief Determines whether this declaration reference was followed by an
- /// explicit template argument list.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- /// \brief Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- /// \brief Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- /// \brief Returns true if this expression refers to a function that
- /// was resolved from an overloaded set having size greater than 1.
- bool hadMultipleCandidates() const {
- return DeclRefExprBits.HadMultipleCandidates;
- }
- /// \brief Sets the flag telling whether this expression refers to
- /// a function that was resolved from an overloaded set having size
- /// greater than 1.
- void setHadMultipleCandidates(bool V = true) {
- DeclRefExprBits.HadMultipleCandidates = V;
- }
-
- /// \brief Does this DeclRefExpr refer to an enclosing local or a captured
- /// variable?
- bool refersToEnclosingVariableOrCapture() const {
- return DeclRefExprBits.RefersToEnclosingVariableOrCapture;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclRefExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief [C99 6.4.2.2] - A predefined identifier such as __func__.
-class PredefinedExpr : public Expr {
-public:
- enum IdentType {
- Func,
- Function,
- LFunction, // Same as Function, but as wide string.
- FuncDName,
- FuncSig,
- PrettyFunction,
- /// \brief The same as PrettyFunction, except that the
- /// 'virtual' keyword is omitted for virtual member functions.
- PrettyFunctionNoVirtual
- };
-
-private:
- SourceLocation Loc;
- IdentType Type;
- Stmt *FnName;
-
-public:
- PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT,
- StringLiteral *SL);
-
- /// \brief Construct an empty predefined expression.
- explicit PredefinedExpr(EmptyShell Empty)
- : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {}
-
- IdentType getIdentType() const { return Type; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- StringLiteral *getFunctionName();
- const StringLiteral *getFunctionName() const {
- return const_cast<PredefinedExpr *>(this)->getFunctionName();
- }
-
- static StringRef getIdentTypeName(IdentType IT);
- static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PredefinedExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&FnName, &FnName + 1); }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without
-/// leaking memory.
-///
-/// For large floats/integers, APFloat/APInt will allocate memory from the heap
-/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator
-/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
-/// the APFloat/APInt values will never get freed. APNumericStorage uses
-/// ASTContext's allocator for memory allocation.
-class APNumericStorage {
- union {
- uint64_t VAL; ///< Used to store the <= 64 bits integer value.
- uint64_t *pVal; ///< Used to store the >64 bits integer value.
- };
- unsigned BitWidth;
-
- bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
-
- APNumericStorage(const APNumericStorage &) = delete;
- void operator=(const APNumericStorage &) = delete;
-
-protected:
- APNumericStorage() : VAL(0), BitWidth(0) { }
-
- llvm::APInt getIntValue() const {
- unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
- if (NumWords > 1)
- return llvm::APInt(BitWidth, NumWords, pVal);
- else
- return llvm::APInt(BitWidth, VAL);
- }
- void setIntValue(const ASTContext &C, const llvm::APInt &Val);
-};
-
-class APIntStorage : private APNumericStorage {
-public:
- llvm::APInt getValue() const { return getIntValue(); }
- void setValue(const ASTContext &C, const llvm::APInt &Val) {
- setIntValue(C, Val);
- }
-};
-
-class APFloatStorage : private APNumericStorage {
-public:
- llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
- return llvm::APFloat(Semantics, getIntValue());
- }
- void setValue(const ASTContext &C, const llvm::APFloat &Val) {
- setIntValue(C, Val.bitcastToAPInt());
- }
-};
-
-class IntegerLiteral : public Expr, public APIntStorage {
- SourceLocation Loc;
-
- /// \brief Construct an empty integer literal.
- explicit IntegerLiteral(EmptyShell Empty)
- : Expr(IntegerLiteralClass, Empty) { }
-
-public:
- // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
- // or UnsignedLongLongTy
- IntegerLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
- SourceLocation l);
-
- /// \brief Returns a new integer literal with value 'V' and type 'type'.
- /// \param type - either IntTy, LongTy, LongLongTy, UnsignedIntTy,
- /// UnsignedLongTy, or UnsignedLongLongTy which should match the size of V
- /// \param V - the value that the returned integer literal contains.
- static IntegerLiteral *Create(const ASTContext &C, const llvm::APInt &V,
- QualType type, SourceLocation l);
- /// \brief Returns a new empty integer literal.
- static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty);
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- /// \brief Retrieve the location of the literal.
- SourceLocation getLocation() const { return Loc; }
-
- void setLocation(SourceLocation Location) { Loc = Location; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IntegerLiteralClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-class CharacterLiteral : public Expr {
-public:
- enum CharacterKind {
- Ascii,
- Wide,
- UTF16,
- UTF32
- };
-
-private:
- unsigned Value;
- SourceLocation Loc;
-public:
- // type should be IntTy
- CharacterLiteral(unsigned value, CharacterKind kind, QualType type,
- SourceLocation l)
- : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Value(value), Loc(l) {
- CharacterLiteralBits.Kind = kind;
- }
-
- /// \brief Construct an empty character literal.
- CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
-
- SourceLocation getLocation() const { return Loc; }
- CharacterKind getKind() const {
- return static_cast<CharacterKind>(CharacterLiteralBits.Kind);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- unsigned getValue() const { return Value; }
-
- void setLocation(SourceLocation Location) { Loc = Location; }
- void setKind(CharacterKind kind) { CharacterLiteralBits.Kind = kind; }
- void setValue(unsigned Val) { Value = Val; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CharacterLiteralClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-class FloatingLiteral : public Expr, private APFloatStorage {
- SourceLocation Loc;
-
- FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact,
- QualType Type, SourceLocation L);
-
- /// \brief Construct an empty floating-point literal.
- explicit FloatingLiteral(const ASTContext &C, EmptyShell Empty);
-
-public:
- static FloatingLiteral *Create(const ASTContext &C, const llvm::APFloat &V,
- bool isexact, QualType Type, SourceLocation L);
- static FloatingLiteral *Create(const ASTContext &C, EmptyShell Empty);
-
- llvm::APFloat getValue() const {
- return APFloatStorage::getValue(getSemantics());
- }
- void setValue(const ASTContext &C, const llvm::APFloat &Val) {
- assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics");
- APFloatStorage::setValue(C, Val);
- }
-
- /// Get a raw enumeration value representing the floating-point semantics of
- /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
- APFloatSemantics getRawSemantics() const {
- return static_cast<APFloatSemantics>(FloatingLiteralBits.Semantics);
- }
-
- /// Set the raw enumeration value representing the floating-point semantics of
- /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
- void setRawSemantics(APFloatSemantics Sem) {
- FloatingLiteralBits.Semantics = Sem;
- }
-
- /// Return the APFloat semantics this literal uses.
- const llvm::fltSemantics &getSemantics() const;
-
- /// Set the APFloat semantics this literal uses.
- void setSemantics(const llvm::fltSemantics &Sem);
-
- bool isExact() const { return FloatingLiteralBits.IsExact; }
- void setExact(bool E) { FloatingLiteralBits.IsExact = E; }
-
- /// getValueAsApproximateDouble - This returns the value as an inaccurate
- /// double. Note that this may cause loss of precision, but is useful for
- /// debugging dumps, etc.
- double getValueAsApproximateDouble() const;
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == FloatingLiteralClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ImaginaryLiteral - We support imaginary integer and floating point literals,
-/// like "1.0i". We represent these as a wrapper around FloatingLiteral and
-/// IntegerLiteral classes. Instances of this class always have a Complex type
-/// whose element type matches the subexpression.
-///
-class ImaginaryLiteral : public Expr {
- Stmt *Val;
-public:
- ImaginaryLiteral(Expr *val, QualType Ty)
- : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Val(val) {}
-
- /// \brief Build an empty imaginary literal.
- explicit ImaginaryLiteral(EmptyShell Empty)
- : Expr(ImaginaryLiteralClass, Empty) { }
-
- const Expr *getSubExpr() const { return cast<Expr>(Val); }
- Expr *getSubExpr() { return cast<Expr>(Val); }
- void setSubExpr(Expr *E) { Val = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Val->getLocStart(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Val->getLocEnd(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ImaginaryLiteralClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Val, &Val+1); }
-};
-
-/// StringLiteral - This represents a string literal expression, e.g. "foo"
-/// or L"bar" (wide strings). The actual string is returned by getBytes()
-/// is NOT null-terminated, and the length of the string is determined by
-/// calling getByteLength(). The C type for a string is always a
-/// ConstantArrayType. In C++, the char type is const qualified, in C it is
-/// not.
-///
-/// Note that strings in C can be formed by concatenation of multiple string
-/// literal pptokens in translation phase #6. This keeps track of the locations
-/// of each of these pieces.
-///
-/// Strings in C can also be truncated and extended by assigning into arrays,
-/// e.g. with constructs like:
-/// char X[2] = "foobar";
-/// In this case, getByteLength() will return 6, but the string literal will
-/// have type "char[2]".
-class StringLiteral : public Expr {
-public:
- enum StringKind {
- Ascii,
- Wide,
- UTF8,
- UTF16,
- UTF32
- };
-
-private:
- friend class ASTStmtReader;
-
- union {
- const char *asChar;
- const uint16_t *asUInt16;
- const uint32_t *asUInt32;
- } StrData;
- unsigned Length;
- unsigned CharByteWidth : 4;
- unsigned Kind : 3;
- unsigned IsPascal : 1;
- unsigned NumConcatenated;
- SourceLocation TokLocs[1];
-
- StringLiteral(QualType Ty) :
- Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false,
- false) {}
-
- static int mapCharByteWidth(TargetInfo const &target,StringKind k);
-
-public:
- /// This is the "fully general" constructor that allows representation of
- /// strings formed from multiple concatenated tokens.
- static StringLiteral *Create(const ASTContext &C, StringRef Str,
- StringKind Kind, bool Pascal, QualType Ty,
- const SourceLocation *Loc, unsigned NumStrs);
-
- /// Simple constructor for string literals made from one token.
- static StringLiteral *Create(const ASTContext &C, StringRef Str,
- StringKind Kind, bool Pascal, QualType Ty,
- SourceLocation Loc) {
- return Create(C, Str, Kind, Pascal, Ty, &Loc, 1);
- }
-
- /// \brief Construct an empty string literal.
- static StringLiteral *CreateEmpty(const ASTContext &C, unsigned NumStrs);
-
- StringRef getString() const {
- assert(CharByteWidth==1
- && "This function is used in places that assume strings use char");
- return StringRef(StrData.asChar, getByteLength());
- }
-
- /// Allow access to clients that need the byte representation, such as
- /// ASTWriterStmt::VisitStringLiteral().
- StringRef getBytes() const {
- // FIXME: StringRef may not be the right type to use as a result for this.
- if (CharByteWidth == 1)
- return StringRef(StrData.asChar, getByteLength());
- if (CharByteWidth == 4)
- return StringRef(reinterpret_cast<const char*>(StrData.asUInt32),
- getByteLength());
- assert(CharByteWidth == 2 && "unsupported CharByteWidth");
- return StringRef(reinterpret_cast<const char*>(StrData.asUInt16),
- getByteLength());
- }
-
- void outputString(raw_ostream &OS) const;
-
- uint32_t getCodeUnit(size_t i) const {
- assert(i < Length && "out of bounds access");
- if (CharByteWidth == 1)
- return static_cast<unsigned char>(StrData.asChar[i]);
- if (CharByteWidth == 4)
- return StrData.asUInt32[i];
- assert(CharByteWidth == 2 && "unsupported CharByteWidth");
- return StrData.asUInt16[i];
- }
-
- unsigned getByteLength() const { return CharByteWidth*Length; }
- unsigned getLength() const { return Length; }
- unsigned getCharByteWidth() const { return CharByteWidth; }
-
- /// \brief Sets the string data to the given string data.
- void setString(const ASTContext &C, StringRef Str,
- StringKind Kind, bool IsPascal);
-
- StringKind getKind() const { return static_cast<StringKind>(Kind); }
-
-
- bool isAscii() const { return Kind == Ascii; }
- bool isWide() const { return Kind == Wide; }
- bool isUTF8() const { return Kind == UTF8; }
- bool isUTF16() const { return Kind == UTF16; }
- bool isUTF32() const { return Kind == UTF32; }
- bool isPascal() const { return IsPascal; }
-
- bool containsNonAsciiOrNull() const {
- StringRef Str = getString();
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- if (!isASCII(Str[i]) || !Str[i])
- return true;
- return false;
- }
-
- /// getNumConcatenated - Get the number of string literal tokens that were
- /// concatenated in translation phase #6 to form this string literal.
- unsigned getNumConcatenated() const { return NumConcatenated; }
-
- SourceLocation getStrTokenLoc(unsigned TokNum) const {
- assert(TokNum < NumConcatenated && "Invalid tok number");
- return TokLocs[TokNum];
- }
- void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
- assert(TokNum < NumConcatenated && "Invalid tok number");
- TokLocs[TokNum] = L;
- }
-
- /// getLocationOfByte - Return a source location that points to the specified
- /// byte of this string literal.
- ///
- /// Strings are amazingly complex. They can be formed from multiple tokens
- /// and can have escape sequences in them in addition to the usual trigraph
- /// and escaped newline business. This routine handles this complexity.
- ///
- SourceLocation
- getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
- const LangOptions &Features, const TargetInfo &Target,
- unsigned *StartToken = nullptr,
- unsigned *StartTokenByteOffset = nullptr) const;
-
- typedef const SourceLocation *tokloc_iterator;
- tokloc_iterator tokloc_begin() const { return TokLocs; }
- tokloc_iterator tokloc_end() const { return TokLocs + NumConcatenated; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return TokLocs[0]; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return TokLocs[NumConcatenated - 1];
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == StringLiteralClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
-/// AST node is only formed if full location information is requested.
-class ParenExpr : public Expr {
- SourceLocation L, R;
- Stmt *Val;
-public:
- ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
- : Expr(ParenExprClass, val->getType(),
- val->getValueKind(), val->getObjectKind(),
- val->isTypeDependent(), val->isValueDependent(),
- val->isInstantiationDependent(),
- val->containsUnexpandedParameterPack()),
- L(l), R(r), Val(val) {}
-
- /// \brief Construct an empty parenthesized expression.
- explicit ParenExpr(EmptyShell Empty)
- : Expr(ParenExprClass, Empty) { }
-
- const Expr *getSubExpr() const { return cast<Expr>(Val); }
- Expr *getSubExpr() { return cast<Expr>(Val); }
- void setSubExpr(Expr *E) { Val = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return L; }
- SourceLocation getLocEnd() const LLVM_READONLY { return R; }
-
- /// \brief Get the location of the left parentheses '('.
- SourceLocation getLParen() const { return L; }
- void setLParen(SourceLocation Loc) { L = Loc; }
-
- /// \brief Get the location of the right parentheses ')'.
- SourceLocation getRParen() const { return R; }
- void setRParen(SourceLocation Loc) { R = Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ParenExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Val, &Val+1); }
-};
-
-/// UnaryOperator - This represents the unary-expression's (except sizeof and
-/// alignof), the postinc/postdec operators from postfix-expression, and various
-/// extensions.
-///
-/// Notes on various nodes:
-///
-/// Real/Imag - These return the real/imag part of a complex operand. If
-/// applied to a non-complex value, the former returns its operand and the
-/// later returns zero in the type of the operand.
-///
-class UnaryOperator : public Expr {
-public:
- typedef UnaryOperatorKind Opcode;
-
-private:
- unsigned Opc : 5;
- SourceLocation Loc;
- Stmt *Val;
-public:
-
- UnaryOperator(Expr *input, Opcode opc, QualType type,
- ExprValueKind VK, ExprObjectKind OK, SourceLocation l)
- : Expr(UnaryOperatorClass, type, VK, OK,
- input->isTypeDependent() || type->isDependentType(),
- input->isValueDependent(),
- (input->isInstantiationDependent() ||
- type->isInstantiationDependentType()),
- input->containsUnexpandedParameterPack()),
- Opc(opc), Loc(l), Val(input) {}
-
- /// \brief Build an empty unary operator.
- explicit UnaryOperator(EmptyShell Empty)
- : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { }
-
- Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
- void setOpcode(Opcode O) { Opc = O; }
-
- Expr *getSubExpr() const { return cast<Expr>(Val); }
- void setSubExpr(Expr *E) { Val = E; }
-
- /// getOperatorLoc - Return the location of the operator.
- SourceLocation getOperatorLoc() const { return Loc; }
- void setOperatorLoc(SourceLocation L) { Loc = L; }
-
- /// isPostfix - Return true if this is a postfix operation, like x++.
- static bool isPostfix(Opcode Op) {
- return Op == UO_PostInc || Op == UO_PostDec;
- }
-
- /// isPrefix - Return true if this is a prefix operation, like --x.
- static bool isPrefix(Opcode Op) {
- return Op == UO_PreInc || Op == UO_PreDec;
- }
-
- bool isPrefix() const { return isPrefix(getOpcode()); }
- bool isPostfix() const { return isPostfix(getOpcode()); }
-
- static bool isIncrementOp(Opcode Op) {
- return Op == UO_PreInc || Op == UO_PostInc;
- }
- bool isIncrementOp() const {
- return isIncrementOp(getOpcode());
- }
-
- static bool isDecrementOp(Opcode Op) {
- return Op == UO_PreDec || Op == UO_PostDec;
- }
- bool isDecrementOp() const {
- return isDecrementOp(getOpcode());
- }
-
- static bool isIncrementDecrementOp(Opcode Op) { return Op <= UO_PreDec; }
- bool isIncrementDecrementOp() const {
- return isIncrementDecrementOp(getOpcode());
- }
-
- static bool isArithmeticOp(Opcode Op) {
- return Op >= UO_Plus && Op <= UO_LNot;
- }
- bool isArithmeticOp() const { return isArithmeticOp(getOpcode()); }
-
- /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
- /// corresponds to, e.g. "sizeof" or "[pre]++"
- static StringRef getOpcodeStr(Opcode Op);
-
- /// \brief Retrieve the unary opcode that corresponds to the given
- /// overloaded operator.
- static Opcode getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix);
-
- /// \brief Retrieve the overloaded operator kind that corresponds to
- /// the given unary opcode.
- static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return isPostfix() ? Val->getLocStart() : Loc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return isPostfix() ? Loc : Val->getLocEnd();
- }
- SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnaryOperatorClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Val, &Val+1); }
-};
-
-/// Helper class for OffsetOfExpr.
-
-// __builtin_offsetof(type, identifier(.identifier|[expr])*)
-class OffsetOfNode {
-public:
- /// \brief The kind of offsetof node we have.
- enum Kind {
- /// \brief An index into an array.
- Array = 0x00,
- /// \brief A field.
- Field = 0x01,
- /// \brief A field in a dependent type, known only by its name.
- Identifier = 0x02,
- /// \brief An implicit indirection through a C++ base class, when the
- /// field found is in a base class.
- Base = 0x03
- };
-
-private:
- enum { MaskBits = 2, Mask = 0x03 };
-
- /// \brief The source range that covers this part of the designator.
- SourceRange Range;
-
- /// \brief The data describing the designator, which comes in three
- /// different forms, depending on the lower two bits.
- /// - An unsigned index into the array of Expr*'s stored after this node
- /// in memory, for [constant-expression] designators.
- /// - A FieldDecl*, for references to a known field.
- /// - An IdentifierInfo*, for references to a field with a given name
- /// when the class type is dependent.
- /// - A CXXBaseSpecifier*, for references that look at a field in a
- /// base class.
- uintptr_t Data;
-
-public:
- /// \brief Create an offsetof node that refers to an array element.
- OffsetOfNode(SourceLocation LBracketLoc, unsigned Index,
- SourceLocation RBracketLoc)
- : Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) {}
-
- /// \brief Create an offsetof node that refers to a field.
- OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field, SourceLocation NameLoc)
- : Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
- Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) {}
-
- /// \brief Create an offsetof node that refers to an identifier.
- OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name,
- SourceLocation NameLoc)
- : Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
- Data(reinterpret_cast<uintptr_t>(Name) | Identifier) {}
-
- /// \brief Create an offsetof node that refers into a C++ base class.
- explicit OffsetOfNode(const CXXBaseSpecifier *Base)
- : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
-
- /// \brief Determine what kind of offsetof node this is.
- Kind getKind() const { return static_cast<Kind>(Data & Mask); }
-
- /// \brief For an array element node, returns the index into the array
- /// of expressions.
- unsigned getArrayExprIndex() const {
- assert(getKind() == Array);
- return Data >> 2;
- }
-
- /// \brief For a field offsetof node, returns the field.
- FieldDecl *getField() const {
- assert(getKind() == Field);
- return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask);
- }
-
- /// \brief For a field or identifier offsetof node, returns the name of
- /// the field.
- IdentifierInfo *getFieldName() const;
-
- /// \brief For a base class node, returns the base specifier.
- CXXBaseSpecifier *getBase() const {
- assert(getKind() == Base);
- return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask);
- }
-
- /// \brief Retrieve the source range that covers this offsetof node.
- ///
- /// For an array element node, the source range contains the locations of
- /// the square brackets. For a field or identifier node, the source range
- /// contains the location of the period (if there is one) and the
- /// identifier.
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
-};
-
-/// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
-/// offsetof(record-type, member-designator). For example, given:
-/// @code
-/// struct S {
-/// float f;
-/// double d;
-/// };
-/// struct T {
-/// int i;
-/// struct S s[10];
-/// };
-/// @endcode
-/// we can represent and evaluate the expression @c offsetof(struct T, s[2].d).
-
-class OffsetOfExpr final
- : public Expr,
- private llvm::TrailingObjects<OffsetOfExpr, OffsetOfNode, Expr *> {
- SourceLocation OperatorLoc, RParenLoc;
- // Base type;
- TypeSourceInfo *TSInfo;
- // Number of sub-components (i.e. instances of OffsetOfNode).
- unsigned NumComps;
- // Number of sub-expressions (i.e. array subscript expressions).
- unsigned NumExprs;
-
- size_t numTrailingObjects(OverloadToken<OffsetOfNode>) const {
- return NumComps;
- }
-
- OffsetOfExpr(const ASTContext &C, QualType type,
- SourceLocation OperatorLoc, TypeSourceInfo *tsi,
- ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
- SourceLocation RParenLoc);
-
- explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
- : Expr(OffsetOfExprClass, EmptyShell()),
- TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {}
-
-public:
-
- static OffsetOfExpr *Create(const ASTContext &C, QualType type,
- SourceLocation OperatorLoc, TypeSourceInfo *tsi,
- ArrayRef<OffsetOfNode> comps,
- ArrayRef<Expr*> exprs, SourceLocation RParenLoc);
-
- static OffsetOfExpr *CreateEmpty(const ASTContext &C,
- unsigned NumComps, unsigned NumExprs);
-
- /// getOperatorLoc - Return the location of the operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
- void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
-
- /// \brief Return the location of the right parentheses.
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation R) { RParenLoc = R; }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return TSInfo;
- }
- void setTypeSourceInfo(TypeSourceInfo *tsi) {
- TSInfo = tsi;
- }
-
- const OffsetOfNode &getComponent(unsigned Idx) const {
- assert(Idx < NumComps && "Subscript out of range");
- return getTrailingObjects<OffsetOfNode>()[Idx];
- }
-
- void setComponent(unsigned Idx, OffsetOfNode ON) {
- assert(Idx < NumComps && "Subscript out of range");
- getTrailingObjects<OffsetOfNode>()[Idx] = ON;
- }
-
- unsigned getNumComponents() const {
- return NumComps;
- }
-
- Expr* getIndexExpr(unsigned Idx) {
- assert(Idx < NumExprs && "Subscript out of range");
- return getTrailingObjects<Expr *>()[Idx];
- }
-
- const Expr *getIndexExpr(unsigned Idx) const {
- assert(Idx < NumExprs && "Subscript out of range");
- return getTrailingObjects<Expr *>()[Idx];
- }
-
- void setIndexExpr(unsigned Idx, Expr* E) {
- assert(Idx < NumComps && "Subscript out of range");
- getTrailingObjects<Expr *>()[Idx] = E;
- }
-
- unsigned getNumExpressions() const {
- return NumExprs;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OffsetOfExprClass;
- }
-
- // Iterators
- child_range children() {
- Stmt **begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
- return child_range(begin, begin + NumExprs);
- }
- friend TrailingObjects;
-};
-
-/// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated)
-/// expression operand. Used for sizeof/alignof (C99 6.5.3.4) and
-/// vec_step (OpenCL 1.1 6.11.12).
-class UnaryExprOrTypeTraitExpr : public Expr {
- union {
- TypeSourceInfo *Ty;
- Stmt *Ex;
- } Argument;
- SourceLocation OpLoc, RParenLoc;
-
-public:
- UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo,
- QualType resultType, SourceLocation op,
- SourceLocation rp) :
- Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
- false, // Never type-dependent (C++ [temp.dep.expr]p3).
- // Value-dependent if the argument is type-dependent.
- TInfo->getType()->isDependentType(),
- TInfo->getType()->isInstantiationDependentType(),
- TInfo->getType()->containsUnexpandedParameterPack()),
- OpLoc(op), RParenLoc(rp) {
- UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
- UnaryExprOrTypeTraitExprBits.IsType = true;
- Argument.Ty = TInfo;
- }
-
- UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E,
- QualType resultType, SourceLocation op,
- SourceLocation rp);
-
- /// \brief Construct an empty sizeof/alignof expression.
- explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty)
- : Expr(UnaryExprOrTypeTraitExprClass, Empty) { }
-
- UnaryExprOrTypeTrait getKind() const {
- return static_cast<UnaryExprOrTypeTrait>(UnaryExprOrTypeTraitExprBits.Kind);
- }
- void setKind(UnaryExprOrTypeTrait K) { UnaryExprOrTypeTraitExprBits.Kind = K;}
-
- bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; }
- QualType getArgumentType() const {
- return getArgumentTypeInfo()->getType();
- }
- TypeSourceInfo *getArgumentTypeInfo() const {
- assert(isArgumentType() && "calling getArgumentType() when arg is expr");
- return Argument.Ty;
- }
- Expr *getArgumentExpr() {
- assert(!isArgumentType() && "calling getArgumentExpr() when arg is type");
- return static_cast<Expr*>(Argument.Ex);
- }
- const Expr *getArgumentExpr() const {
- return const_cast<UnaryExprOrTypeTraitExpr*>(this)->getArgumentExpr();
- }
-
- void setArgument(Expr *E) {
- Argument.Ex = E;
- UnaryExprOrTypeTraitExprBits.IsType = false;
- }
- void setArgument(TypeSourceInfo *TInfo) {
- Argument.Ty = TInfo;
- UnaryExprOrTypeTraitExprBits.IsType = true;
- }
-
- /// Gets the argument type, or the type of the argument expression, whichever
- /// is appropriate.
- QualType getTypeOfArgument() const {
- return isArgumentType() ? getArgumentType() : getArgumentExpr()->getType();
- }
-
- SourceLocation getOperatorLoc() const { return OpLoc; }
- void setOperatorLoc(SourceLocation L) { OpLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return OpLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
- }
-
- // Iterators
- child_range children();
-};
-
-//===----------------------------------------------------------------------===//
-// Postfix Operators.
-//===----------------------------------------------------------------------===//
-
-/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
-class ArraySubscriptExpr : public Expr {
- enum { LHS, RHS, END_EXPR=2 };
- Stmt* SubExprs[END_EXPR];
- SourceLocation RBracketLoc;
-public:
- ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation rbracketloc)
- : Expr(ArraySubscriptExprClass, t, VK, OK,
- lhs->isTypeDependent() || rhs->isTypeDependent(),
- lhs->isValueDependent() || rhs->isValueDependent(),
- (lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- RBracketLoc(rbracketloc) {
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- /// \brief Create an empty array subscript expression.
- explicit ArraySubscriptExpr(EmptyShell Shell)
- : Expr(ArraySubscriptExprClass, Shell) { }
-
- /// An array access can be written A[4] or 4[A] (both are equivalent).
- /// - getBase() and getIdx() always present the normalized view: A[4].
- /// In this case getBase() returns "A" and getIdx() returns "4".
- /// - getLHS() and getRHS() present the syntactic view. e.g. for
- /// 4[A] getLHS() returns "4".
- /// Note: Because vector element access is also written A[4] we must
- /// predicate the format conversion in getBase and getIdx only on the
- /// the type of the RHS, as it is possible for the LHS to be a vector of
- /// integer type
- Expr *getLHS() { return cast<Expr>(SubExprs[LHS]); }
- const Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- void setLHS(Expr *E) { SubExprs[LHS] = E; }
-
- Expr *getRHS() { return cast<Expr>(SubExprs[RHS]); }
- const Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- void setRHS(Expr *E) { SubExprs[RHS] = E; }
-
- Expr *getBase() {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
- }
-
- const Expr *getBase() const {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
- }
-
- Expr *getIdx() {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
- }
-
- const Expr *getIdx() const {
- return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getLHS()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
-
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getBase()->getExprLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ArraySubscriptExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
-/// CallExpr itself represents a normal function call, e.g., "f(x, 2)",
-/// while its subclasses may represent alternative syntax that (semantically)
-/// results in a function call. For example, CXXOperatorCallExpr is
-/// a subclass for overloaded operator calls that use operator syntax, e.g.,
-/// "str1 + str2" to resolve to a function call.
-class CallExpr : public Expr {
- enum { FN=0, PREARGS_START=1 };
- Stmt **SubExprs;
- unsigned NumArgs;
- SourceLocation RParenLoc;
-
-protected:
- // These versions of the constructor are for derived classes.
- CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation rparenloc);
- CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
- EmptyShell Empty);
-
- Stmt *getPreArg(unsigned i) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
- }
- const Stmt *getPreArg(unsigned i) const {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- return SubExprs[PREARGS_START+i];
- }
- void setPreArg(unsigned i, Stmt *PreArg) {
- assert(i < getNumPreArgs() && "Prearg access out of range!");
- SubExprs[PREARGS_START+i] = PreArg;
- }
-
- unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
-
-public:
- CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
- ExprValueKind VK, SourceLocation rparenloc);
-
- /// \brief Build an empty call expression.
- CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty);
-
- const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
- Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
- void setCallee(Expr *F) { SubExprs[FN] = F; }
-
- Decl *getCalleeDecl();
- const Decl *getCalleeDecl() const {
- return const_cast<CallExpr*>(this)->getCalleeDecl();
- }
-
- /// \brief If the callee is a FunctionDecl, return it. Otherwise return 0.
- FunctionDecl *getDirectCallee();
- const FunctionDecl *getDirectCallee() const {
- return const_cast<CallExpr*>(this)->getDirectCallee();
- }
-
- /// getNumArgs - Return the number of actual arguments to this call.
- ///
- unsigned getNumArgs() const { return NumArgs; }
-
- /// \brief Retrieve the call arguments.
- Expr **getArgs() {
- return reinterpret_cast<Expr **>(SubExprs+getNumPreArgs()+PREARGS_START);
- }
- const Expr *const *getArgs() const {
- return reinterpret_cast<Expr **>(SubExprs + getNumPreArgs() +
- PREARGS_START);
- }
-
- /// getArg - Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast_or_null<Expr>(SubExprs[Arg + getNumPreArgs() + PREARGS_START]);
- }
-
- /// setArg - Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr;
- }
-
- /// setNumArgs - This changes the number of arguments present in this call.
- /// Any orphaned expressions are deleted by this, and any new operands are set
- /// to null.
- void setNumArgs(const ASTContext& C, unsigned NumArgs);
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
- typedef llvm::iterator_range<arg_iterator> arg_range;
- typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
-
- arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
- }
-
- arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
- arg_iterator arg_end() {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
- }
- const_arg_iterator arg_begin() const {
- return SubExprs+PREARGS_START+getNumPreArgs();
- }
- const_arg_iterator arg_end() const {
- return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
- }
-
- /// This method provides fast access to all the subexpressions of
- /// a CallExpr without going through the slower virtual child_iterator
- /// interface. This provides efficient reverse iteration of the
- /// subexpressions. This is currently used for CFG construction.
- ArrayRef<Stmt*> getRawSubExprs() {
- return llvm::makeArrayRef(SubExprs,
- getNumPreArgs() + PREARGS_START + getNumArgs());
- }
-
- /// getNumCommas - Return the number of commas that must have been present in
- /// this function call.
- unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
-
- /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
- /// of the callee. If not, return 0.
- unsigned getBuiltinCallee() const;
-
- /// \brief Returns \c true if this is a call to a builtin which does not
- /// evaluate side-effects within its arguments.
- bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const;
-
- /// getCallReturnType - Get the return type of the call expr. This is not
- /// always the type of the expr itself, if the return type is a reference
- /// type.
- QualType getCallReturnType(const ASTContext &Ctx) const;
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstCallExprConstant &&
- T->getStmtClass() <= lastCallExprConstant;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0],
- &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
- }
-};
-
-/// Extra data stored in some MemberExpr objects.
-struct MemberExprNameQualifier {
- /// \brief The nested-name-specifier that qualifies the name, including
- /// source-location information.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The DeclAccessPair through which the MemberDecl was found due to
- /// name qualifiers.
- DeclAccessPair FoundDecl;
-};
-
-/// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F.
-///
-class MemberExpr final
- : public Expr,
- private llvm::TrailingObjects<MemberExpr, MemberExprNameQualifier,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// Base - the expression for the base pointer or structure references. In
- /// X.F, this is "X".
- Stmt *Base;
-
- /// MemberDecl - This is the decl being referenced by the field/member name.
- /// In X.F, this is the decl referenced by F.
- ValueDecl *MemberDecl;
-
- /// MemberDNLoc - Provides source/type location info for the
- /// declaration name embedded in MemberDecl.
- DeclarationNameLoc MemberDNLoc;
-
- /// MemberLoc - This is the location of the member name.
- SourceLocation MemberLoc;
-
- /// This is the location of the -> or . in the expression.
- SourceLocation OperatorLoc;
-
- /// IsArrow - True if this is "X->F", false if this is "X.F".
- bool IsArrow : 1;
-
- /// \brief True if this member expression used a nested-name-specifier to
- /// refer to the member, e.g., "x->Base::f", or found its member via a using
- /// declaration. When true, a MemberExprNameQualifier
- /// structure is allocated immediately after the MemberExpr.
- bool HasQualifierOrFoundDecl : 1;
-
- /// \brief True if this member expression specified a template keyword
- /// and/or a template argument list explicitly, e.g., x->f<int>,
- /// x->template f, x->template f<int>.
- /// When true, an ASTTemplateKWAndArgsInfo structure and its
- /// TemplateArguments (if any) are present.
- bool HasTemplateKWAndArgsInfo : 1;
-
- /// \brief True if this member expression refers to a method that
- /// was resolved from an overloaded set having size greater than 1.
- bool HadMultipleCandidates : 1;
-
- size_t numTrailingObjects(OverloadToken<MemberExprNameQualifier>) const {
- return HasQualifierOrFoundDecl ? 1 : 0;
- }
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
-public:
- MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc,
- ValueDecl *memberdecl, const DeclarationNameInfo &NameInfo,
- QualType ty, ExprValueKind VK, ExprObjectKind OK)
- : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(),
- base->isValueDependent(), base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()),
- MemberLoc(NameInfo.getLoc()), OperatorLoc(operatorloc),
- IsArrow(isarrow), HasQualifierOrFoundDecl(false),
- HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) {
- assert(memberdecl->getDeclName() == NameInfo.getName());
- }
-
- // NOTE: this constructor should be used only when it is known that
- // the member name can not provide additional syntactic info
- // (i.e., source locations for C++ operator names or type source info
- // for constructors, destructors and conversion operators).
- MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc,
- ValueDecl *memberdecl, SourceLocation l, QualType ty,
- ExprValueKind VK, ExprObjectKind OK)
- : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(),
- base->isValueDependent(), base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l),
- OperatorLoc(operatorloc), IsArrow(isarrow),
- HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false),
- HadMultipleCandidates(false) {}
-
- static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *memberdecl,
- DeclAccessPair founddecl,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *targs, QualType ty,
- ExprValueKind VK, ExprObjectKind OK);
-
- void setBase(Expr *E) { Base = E; }
- Expr *getBase() const { return cast<Expr>(Base); }
-
- /// \brief Retrieve the member declaration to which this expression refers.
- ///
- /// The returned declaration will either be a FieldDecl or (in C++)
- /// a CXXMethodDecl.
- ValueDecl *getMemberDecl() const { return MemberDecl; }
- void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
-
- /// \brief Retrieves the declaration found by lookup.
- DeclAccessPair getFoundDecl() const {
- if (!HasQualifierOrFoundDecl)
- return DeclAccessPair::make(getMemberDecl(),
- getMemberDecl()->getAccess());
- return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
- }
-
- /// \brief Determines whether this member expression actually had
- /// a C++ nested-name-specifier prior to the name of the member, e.g.,
- /// x->Base::foo.
- bool hasQualifier() const { return getQualifier() != nullptr; }
-
- /// \brief If the member name was qualified, retrieves the
- /// nested-name-specifier that precedes the member name, with source-location
- /// information.
- NestedNameSpecifierLoc getQualifierLoc() const {
- if (!HasQualifierOrFoundDecl)
- return NestedNameSpecifierLoc();
-
- return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc;
- }
-
- /// \brief If the member name was qualified, retrieves the
- /// nested-name-specifier that precedes the member name. Otherwise, returns
- /// NULL.
- NestedNameSpecifier *getQualifier() const {
- return getQualifierLoc().getNestedNameSpecifier();
- }
-
- /// \brief Retrieve the location of the template keyword preceding
- /// the member name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
- }
-
- /// \brief Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the member name, if any.
- SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
- }
-
- /// \brief Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the member name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
-
- /// Determines whether the member name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// \brief Determines whether the member name was followed by an
- /// explicit template argument list.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- /// \brief Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- /// \brief Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- /// \brief Retrieve the member declaration name info.
- DeclarationNameInfo getMemberNameInfo() const {
- return DeclarationNameInfo(MemberDecl->getDeclName(),
- MemberLoc, MemberDNLoc);
- }
-
- SourceLocation getOperatorLoc() const LLVM_READONLY { return OperatorLoc; }
-
- bool isArrow() const { return IsArrow; }
- void setArrow(bool A) { IsArrow = A; }
-
- /// getMemberLoc - Return the location of the "member", in X->F, it is the
- /// location of 'F'.
- SourceLocation getMemberLoc() const { return MemberLoc; }
- void setMemberLoc(SourceLocation L) { MemberLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- SourceLocation getExprLoc() const LLVM_READONLY { return MemberLoc; }
-
- /// \brief Determine whether the base of this explicit is implicit.
- bool isImplicitAccess() const {
- return getBase() && getBase()->isImplicitCXXThis();
- }
-
- /// \brief Returns true if this member expression refers to a method that
- /// was resolved from an overloaded set having size greater than 1.
- bool hadMultipleCandidates() const {
- return HadMultipleCandidates;
- }
- /// \brief Sets the flag telling whether this expression refers to
- /// a method that was resolved from an overloaded set having size
- /// greater than 1.
- void setHadMultipleCandidates(bool V = true) {
- HadMultipleCandidates = V;
- }
-
- /// \brief Returns true if virtual dispatch is performed.
- /// If the member access is fully qualified, (i.e. X::f()), virtual
- /// dispatching is not performed. In -fapple-kext mode qualified
- /// calls to virtual method will still go through the vtable.
- bool performsVirtualDispatch(const LangOptions &LO) const {
- return LO.AppleKext || !hasQualifier();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MemberExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
-
- friend TrailingObjects;
- friend class ASTReader;
- friend class ASTStmtWriter;
-};
-
-/// CompoundLiteralExpr - [C99 6.5.2.5]
-///
-class CompoundLiteralExpr : public Expr {
- /// LParenLoc - If non-null, this is the location of the left paren in a
- /// compound literal like "(int){4}". This can be null if this is a
- /// synthesized compound expression.
- SourceLocation LParenLoc;
-
- /// The type as written. This can be an incomplete array type, in
- /// which case the actual expression type will be different.
- /// The int part of the pair stores whether this expr is file scope.
- llvm::PointerIntPair<TypeSourceInfo *, 1, bool> TInfoAndScope;
- Stmt *Init;
-public:
- CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo,
- QualType T, ExprValueKind VK, Expr *init, bool fileScope)
- : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary,
- tinfo->getType()->isDependentType(),
- init->isValueDependent(),
- (init->isInstantiationDependent() ||
- tinfo->getType()->isInstantiationDependentType()),
- init->containsUnexpandedParameterPack()),
- LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {}
-
- /// \brief Construct an empty compound literal.
- explicit CompoundLiteralExpr(EmptyShell Empty)
- : Expr(CompoundLiteralExprClass, Empty) { }
-
- const Expr *getInitializer() const { return cast<Expr>(Init); }
- Expr *getInitializer() { return cast<Expr>(Init); }
- void setInitializer(Expr *E) { Init = E; }
-
- bool isFileScope() const { return TInfoAndScope.getInt(); }
- void setFileScope(bool FS) { TInfoAndScope.setInt(FS); }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return TInfoAndScope.getPointer();
- }
- void setTypeSourceInfo(TypeSourceInfo *tinfo) {
- TInfoAndScope.setPointer(tinfo);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- // FIXME: Init should never be null.
- if (!Init)
- return SourceLocation();
- if (LParenLoc.isInvalid())
- return Init->getLocStart();
- return LParenLoc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- // FIXME: Init should never be null.
- if (!Init)
- return SourceLocation();
- return Init->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CompoundLiteralExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Init, &Init+1); }
-};
-
-/// CastExpr - Base class for type casts, including both implicit
-/// casts (ImplicitCastExpr) and explicit casts that have some
-/// representation in the source code (ExplicitCastExpr's derived
-/// classes).
-class CastExpr : public Expr {
-private:
- Stmt *Op;
-
- bool CastConsistency() const;
-
- const CXXBaseSpecifier * const *path_buffer() const {
- return const_cast<CastExpr*>(this)->path_buffer();
- }
- CXXBaseSpecifier **path_buffer();
-
- void setBasePathSize(unsigned basePathSize) {
- CastExprBits.BasePathSize = basePathSize;
- assert(CastExprBits.BasePathSize == basePathSize &&
- "basePathSize doesn't fit in bits of CastExprBits.BasePathSize!");
- }
-
-protected:
- CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
- Expr *op, unsigned BasePathSize)
- : Expr(SC, ty, VK, OK_Ordinary,
- // Cast expressions are type-dependent if the type is
- // dependent (C++ [temp.dep.expr]p3).
- ty->isDependentType(),
- // Cast expressions are value-dependent if the type is
- // dependent or if the subexpression is value-dependent.
- ty->isDependentType() || (op && op->isValueDependent()),
- (ty->isInstantiationDependentType() ||
- (op && op->isInstantiationDependent())),
- // An implicit cast expression doesn't (lexically) contain an
- // unexpanded pack, even if its target type does.
- ((SC != ImplicitCastExprClass &&
- ty->containsUnexpandedParameterPack()) ||
- (op && op->containsUnexpandedParameterPack()))),
- Op(op) {
- assert(kind != CK_Invalid && "creating cast with invalid cast kind");
- CastExprBits.Kind = kind;
- setBasePathSize(BasePathSize);
- assert(CastConsistency());
- }
-
- /// \brief Construct an empty cast.
- CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
- : Expr(SC, Empty) {
- setBasePathSize(BasePathSize);
- }
-
-public:
- CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; }
- void setCastKind(CastKind K) { CastExprBits.Kind = K; }
- const char *getCastKindName() const;
-
- Expr *getSubExpr() { return cast<Expr>(Op); }
- const Expr *getSubExpr() const { return cast<Expr>(Op); }
- void setSubExpr(Expr *E) { Op = E; }
-
- /// \brief Retrieve the cast subexpression as it was written in the source
- /// code, looking through any implicit casts or other intermediate nodes
- /// introduced by semantic analysis.
- Expr *getSubExprAsWritten();
- const Expr *getSubExprAsWritten() const {
- return const_cast<CastExpr *>(this)->getSubExprAsWritten();
- }
-
- typedef CXXBaseSpecifier **path_iterator;
- typedef const CXXBaseSpecifier * const *path_const_iterator;
- bool path_empty() const { return CastExprBits.BasePathSize == 0; }
- unsigned path_size() const { return CastExprBits.BasePathSize; }
- path_iterator path_begin() { return path_buffer(); }
- path_iterator path_end() { return path_buffer() + path_size(); }
- path_const_iterator path_begin() const { return path_buffer(); }
- path_const_iterator path_end() const { return path_buffer() + path_size(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstCastExprConstant &&
- T->getStmtClass() <= lastCastExprConstant;
- }
-
- // Iterators
- child_range children() { return child_range(&Op, &Op+1); }
-};
-
-/// ImplicitCastExpr - Allows us to explicitly represent implicit type
-/// conversions, which have no direct representation in the original
-/// source code. For example: converting T[]->T*, void f()->void
-/// (*f)(), float->double, short->int, etc.
-///
-/// In C, implicit casts always produce rvalues. However, in C++, an
-/// implicit cast whose result is being bound to a reference will be
-/// an lvalue or xvalue. For example:
-///
-/// @code
-/// class Base { };
-/// class Derived : public Base { };
-/// Derived &&ref();
-/// void f(Derived d) {
-/// Base& b = d; // initializer is an ImplicitCastExpr
-/// // to an lvalue of type Base
-/// Base&& r = ref(); // initializer is an ImplicitCastExpr
-/// // to an xvalue of type Base
-/// }
-/// @endcode
-class ImplicitCastExpr final
- : public CastExpr,
- private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *> {
-private:
- ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
- unsigned BasePathLength, ExprValueKind VK)
- : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) {
- }
-
- /// \brief Construct an empty implicit cast.
- explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
- : CastExpr(ImplicitCastExprClass, Shell, PathSize) { }
-
-public:
- enum OnStack_t { OnStack };
- ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
- ExprValueKind VK)
- : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) {
- }
-
- static ImplicitCastExpr *Create(const ASTContext &Context, QualType T,
- CastKind Kind, Expr *Operand,
- const CXXCastPath *BasePath,
- ExprValueKind Cat);
-
- static ImplicitCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSubExpr()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ImplicitCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-inline Expr *Expr::IgnoreImpCasts() {
- Expr *e = this;
- while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
- e = ice->getSubExpr();
- return e;
-}
-
-/// ExplicitCastExpr - An explicit cast written in the source
-/// code.
-///
-/// This class is effectively an abstract class, because it provides
-/// the basic representation of an explicitly-written cast without
-/// specifying which kind of cast (C cast, functional cast, static
-/// cast, etc.) was written; specific derived classes represent the
-/// particular style of cast and its location information.
-///
-/// Unlike implicit casts, explicit cast nodes have two different
-/// types: the type that was written into the source code, and the
-/// actual type of the expression as determined by semantic
-/// analysis. These types may differ slightly. For example, in C++ one
-/// can cast to a reference type, which indicates that the resulting
-/// expression will be an lvalue or xvalue. The reference type, however,
-/// will not be used as the type of the expression.
-class ExplicitCastExpr : public CastExpr {
- /// TInfo - Source type info for the (written) type
- /// this expression is casting to.
- TypeSourceInfo *TInfo;
-
-protected:
- ExplicitCastExpr(StmtClass SC, QualType exprTy, ExprValueKind VK,
- CastKind kind, Expr *op, unsigned PathSize,
- TypeSourceInfo *writtenTy)
- : CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {}
-
- /// \brief Construct an empty explicit cast.
- ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
- : CastExpr(SC, Shell, PathSize) { }
-
-public:
- /// getTypeInfoAsWritten - Returns the type source info for the type
- /// that this expression is casting to.
- TypeSourceInfo *getTypeInfoAsWritten() const { return TInfo; }
- void setTypeInfoAsWritten(TypeSourceInfo *writtenTy) { TInfo = writtenTy; }
-
- /// getTypeAsWritten - Returns the type that this expression is
- /// casting to, as written in the source code.
- QualType getTypeAsWritten() const { return TInfo->getType(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstExplicitCastExprConstant &&
- T->getStmtClass() <= lastExplicitCastExprConstant;
- }
-};
-
-/// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style
-/// cast in C++ (C++ [expr.cast]), which uses the syntax
-/// (Type)expr. For example: @c (int)f.
-class CStyleCastExpr final
- : public ExplicitCastExpr,
- private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *> {
- SourceLocation LPLoc; // the location of the left paren
- SourceLocation RPLoc; // the location of the right paren
-
- CStyleCastExpr(QualType exprTy, ExprValueKind vk, CastKind kind, Expr *op,
- unsigned PathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation r)
- : ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize,
- writtenTy), LPLoc(l), RPLoc(r) {}
-
- /// \brief Construct an empty C-style explicit cast.
- explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
-
-public:
- static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind K,
- Expr *Op, const CXXCastPath *BasePath,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation R);
-
- static CStyleCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- SourceLocation getLParenLoc() const { return LPLoc; }
- void setLParenLoc(SourceLocation L) { LPLoc = L; }
-
- SourceLocation getRParenLoc() const { return RPLoc; }
- void setRParenLoc(SourceLocation L) { RPLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LPLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CStyleCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A builtin binary operation expression such as "x + y" or "x <= y".
-///
-/// This expression node kind describes a builtin binary operation,
-/// such as "x + y" for integer values "x" and "y". The operands will
-/// already have been converted to appropriate types (e.g., by
-/// performing promotions or conversions).
-///
-/// In C++, where operators may be overloaded, a different kind of
-/// expression node (CXXOperatorCallExpr) is used to express the
-/// invocation of an overloaded operator with operator syntax. Within
-/// a C++ template, whether BinaryOperator or CXXOperatorCallExpr is
-/// used to store an expression "x + y" depends on the subexpressions
-/// for x and y. If neither x or y is type-dependent, and the "+"
-/// operator resolves to a built-in operation, BinaryOperator will be
-/// used to express the computation (x and y may still be
-/// value-dependent). If either x or y is type-dependent, or if the
-/// "+" resolves to an overloaded operator, CXXOperatorCallExpr will
-/// be used to express the computation.
-class BinaryOperator : public Expr {
-public:
- typedef BinaryOperatorKind Opcode;
-
-private:
- unsigned Opc : 6;
-
- // Records the FP_CONTRACT pragma status at the point that this binary
- // operator was parsed. This bit is only meaningful for operations on
- // floating point types. For all other types it should default to
- // false.
- unsigned FPContractable : 1;
- SourceLocation OpLoc;
-
- enum { LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR];
-public:
-
- BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, bool fpContractable)
- : Expr(BinaryOperatorClass, ResTy, VK, OK,
- lhs->isTypeDependent() || rhs->isTypeDependent(),
- lhs->isValueDependent() || rhs->isValueDependent(),
- (lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- assert(!isCompoundAssignmentOp() &&
- "Use CompoundAssignOperator for compound assignments");
- }
-
- /// \brief Construct an empty binary operator.
- explicit BinaryOperator(EmptyShell Empty)
- : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
-
- SourceLocation getExprLoc() const LLVM_READONLY { return OpLoc; }
- SourceLocation getOperatorLoc() const { return OpLoc; }
- void setOperatorLoc(SourceLocation L) { OpLoc = L; }
-
- Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
- void setOpcode(Opcode O) { Opc = O; }
-
- Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- void setLHS(Expr *E) { SubExprs[LHS] = E; }
- Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- void setRHS(Expr *E) { SubExprs[RHS] = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getLHS()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getRHS()->getLocEnd();
- }
-
- /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
- /// corresponds to, e.g. "<<=".
- static StringRef getOpcodeStr(Opcode Op);
-
- StringRef getOpcodeStr() const { return getOpcodeStr(getOpcode()); }
-
- /// \brief Retrieve the binary opcode that corresponds to the given
- /// overloaded operator.
- static Opcode getOverloadedOpcode(OverloadedOperatorKind OO);
-
- /// \brief Retrieve the overloaded operator kind that corresponds to
- /// the given binary opcode.
- static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
-
- /// predicates to categorize the respective opcodes.
- bool isPtrMemOp() const { return Opc == BO_PtrMemD || Opc == BO_PtrMemI; }
- static bool isMultiplicativeOp(Opcode Opc) {
- return Opc >= BO_Mul && Opc <= BO_Rem;
- }
- bool isMultiplicativeOp() const { return isMultiplicativeOp(getOpcode()); }
- static bool isAdditiveOp(Opcode Opc) { return Opc == BO_Add || Opc==BO_Sub; }
- bool isAdditiveOp() const { return isAdditiveOp(getOpcode()); }
- static bool isShiftOp(Opcode Opc) { return Opc == BO_Shl || Opc == BO_Shr; }
- bool isShiftOp() const { return isShiftOp(getOpcode()); }
-
- static bool isBitwiseOp(Opcode Opc) { return Opc >= BO_And && Opc <= BO_Or; }
- bool isBitwiseOp() const { return isBitwiseOp(getOpcode()); }
-
- static bool isRelationalOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_GE; }
- bool isRelationalOp() const { return isRelationalOp(getOpcode()); }
-
- static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
- bool isEqualityOp() const { return isEqualityOp(getOpcode()); }
-
- static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; }
- bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
-
- static Opcode negateComparisonOp(Opcode Opc) {
- switch (Opc) {
- default:
- llvm_unreachable("Not a comparsion operator.");
- case BO_LT: return BO_GE;
- case BO_GT: return BO_LE;
- case BO_LE: return BO_GT;
- case BO_GE: return BO_LT;
- case BO_EQ: return BO_NE;
- case BO_NE: return BO_EQ;
- }
- }
-
- static Opcode reverseComparisonOp(Opcode Opc) {
- switch (Opc) {
- default:
- llvm_unreachable("Not a comparsion operator.");
- case BO_LT: return BO_GT;
- case BO_GT: return BO_LT;
- case BO_LE: return BO_GE;
- case BO_GE: return BO_LE;
- case BO_EQ:
- case BO_NE:
- return Opc;
- }
- }
-
- static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; }
- bool isLogicalOp() const { return isLogicalOp(getOpcode()); }
-
- static bool isAssignmentOp(Opcode Opc) {
- return Opc >= BO_Assign && Opc <= BO_OrAssign;
- }
- bool isAssignmentOp() const { return isAssignmentOp(getOpcode()); }
-
- static bool isCompoundAssignmentOp(Opcode Opc) {
- return Opc > BO_Assign && Opc <= BO_OrAssign;
- }
- bool isCompoundAssignmentOp() const {
- return isCompoundAssignmentOp(getOpcode());
- }
- static Opcode getOpForCompoundAssignment(Opcode Opc) {
- assert(isCompoundAssignmentOp(Opc));
- if (Opc >= BO_AndAssign)
- return Opcode(unsigned(Opc) - BO_AndAssign + BO_And);
- else
- return Opcode(unsigned(Opc) - BO_MulAssign + BO_Mul);
- }
-
- static bool isShiftAssignOp(Opcode Opc) {
- return Opc == BO_ShlAssign || Opc == BO_ShrAssign;
- }
- bool isShiftAssignOp() const {
- return isShiftAssignOp(getOpcode());
- }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() >= firstBinaryOperatorConstant &&
- S->getStmtClass() <= lastBinaryOperatorConstant;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-
- // Set the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- void setFPContractable(bool FPC) { FPContractable = FPC; }
-
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- bool isFPContractable() const { return FPContractable; }
-
-protected:
- BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, bool fpContractable, bool dead2)
- : Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
- lhs->isTypeDependent() || rhs->isTypeDependent(),
- lhs->isValueDependent() || rhs->isValueDependent(),
- (lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- BinaryOperator(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Opc(BO_MulAssign) { }
-};
-
-/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
-/// track of the type the operation is performed in. Due to the semantics of
-/// these operators, the operands are promoted, the arithmetic performed, an
-/// implicit conversion back to the result type done, then the assignment takes
-/// place. This captures the intermediate type which the computation is done
-/// in.
-class CompoundAssignOperator : public BinaryOperator {
- QualType ComputationLHSType;
- QualType ComputationResultType;
-public:
- CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
- ExprValueKind VK, ExprObjectKind OK,
- QualType CompLHSType, QualType CompResultType,
- SourceLocation OpLoc, bool fpContractable)
- : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable,
- true),
- ComputationLHSType(CompLHSType),
- ComputationResultType(CompResultType) {
- assert(isCompoundAssignmentOp() &&
- "Only should be used for compound assignments");
- }
-
- /// \brief Build an empty compound assignment operator expression.
- explicit CompoundAssignOperator(EmptyShell Empty)
- : BinaryOperator(CompoundAssignOperatorClass, Empty) { }
-
- // The two computation types are the type the LHS is converted
- // to for the computation and the type of the result; the two are
- // distinct in a few cases (specifically, int+=ptr and ptr-=ptr).
- QualType getComputationLHSType() const { return ComputationLHSType; }
- void setComputationLHSType(QualType T) { ComputationLHSType = T; }
-
- QualType getComputationResultType() const { return ComputationResultType; }
- void setComputationResultType(QualType T) { ComputationResultType = T; }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == CompoundAssignOperatorClass;
- }
-};
-
-/// AbstractConditionalOperator - An abstract base class for
-/// ConditionalOperator and BinaryConditionalOperator.
-class AbstractConditionalOperator : public Expr {
- SourceLocation QuestionLoc, ColonLoc;
- friend class ASTStmtReader;
-
-protected:
- AbstractConditionalOperator(StmtClass SC, QualType T,
- ExprValueKind VK, ExprObjectKind OK,
- bool TD, bool VD, bool ID,
- bool ContainsUnexpandedParameterPack,
- SourceLocation qloc,
- SourceLocation cloc)
- : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack),
- QuestionLoc(qloc), ColonLoc(cloc) {}
-
- AbstractConditionalOperator(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty) { }
-
-public:
- // getCond - Return the expression representing the condition for
- // the ?: operator.
- Expr *getCond() const;
-
- // getTrueExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to true.
- Expr *getTrueExpr() const;
-
- // getFalseExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to false. This is
- // the same as getRHS.
- Expr *getFalseExpr() const;
-
- SourceLocation getQuestionLoc() const { return QuestionLoc; }
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConditionalOperatorClass ||
- T->getStmtClass() == BinaryConditionalOperatorClass;
- }
-};
-
-/// ConditionalOperator - The ?: ternary operator. The GNU "missing
-/// middle" extension is a BinaryConditionalOperator.
-class ConditionalOperator : public AbstractConditionalOperator {
- enum { COND, LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
-
- friend class ASTStmtReader;
-public:
- ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs,
- SourceLocation CLoc, Expr *rhs,
- QualType t, ExprValueKind VK, ExprObjectKind OK)
- : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK,
- // FIXME: the type of the conditional operator doesn't
- // depend on the type of the conditional, but the standard
- // seems to imply that it could. File a bug!
- (lhs->isTypeDependent() || rhs->isTypeDependent()),
- (cond->isValueDependent() || lhs->isValueDependent() ||
- rhs->isValueDependent()),
- (cond->isInstantiationDependent() ||
- lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (cond->containsUnexpandedParameterPack() ||
- lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack()),
- QLoc, CLoc) {
- SubExprs[COND] = cond;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- /// \brief Build an empty conditional operator.
- explicit ConditionalOperator(EmptyShell Empty)
- : AbstractConditionalOperator(ConditionalOperatorClass, Empty) { }
-
- // getCond - Return the expression representing the condition for
- // the ?: operator.
- Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
-
- // getTrueExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to true.
- Expr *getTrueExpr() const { return cast<Expr>(SubExprs[LHS]); }
-
- // getFalseExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to false. This is
- // the same as getRHS.
- Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); }
-
- Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCond()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getRHS()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConditionalOperatorClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// BinaryConditionalOperator - The GNU extension to the conditional
-/// operator which allows the middle operand to be omitted.
-///
-/// This is a different expression kind on the assumption that almost
-/// every client ends up needing to know that these are different.
-class BinaryConditionalOperator : public AbstractConditionalOperator {
- enum { COMMON, COND, LHS, RHS, NUM_SUBEXPRS };
-
- /// - the common condition/left-hand-side expression, which will be
- /// evaluated as the opaque value
- /// - the condition, expressed in terms of the opaque value
- /// - the left-hand-side, expressed in terms of the opaque value
- /// - the right-hand-side
- Stmt *SubExprs[NUM_SUBEXPRS];
- OpaqueValueExpr *OpaqueValue;
-
- friend class ASTStmtReader;
-public:
- BinaryConditionalOperator(Expr *common, OpaqueValueExpr *opaqueValue,
- Expr *cond, Expr *lhs, Expr *rhs,
- SourceLocation qloc, SourceLocation cloc,
- QualType t, ExprValueKind VK, ExprObjectKind OK)
- : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK,
- (common->isTypeDependent() || rhs->isTypeDependent()),
- (common->isValueDependent() || rhs->isValueDependent()),
- (common->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (common->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack()),
- qloc, cloc),
- OpaqueValue(opaqueValue) {
- SubExprs[COMMON] = common;
- SubExprs[COND] = cond;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- assert(OpaqueValue->getSourceExpr() == common && "Wrong opaque value");
- }
-
- /// \brief Build an empty conditional operator.
- explicit BinaryConditionalOperator(EmptyShell Empty)
- : AbstractConditionalOperator(BinaryConditionalOperatorClass, Empty) { }
-
- /// \brief getCommon - Return the common expression, written to the
- /// left of the condition. The opaque value will be bound to the
- /// result of this expression.
- Expr *getCommon() const { return cast<Expr>(SubExprs[COMMON]); }
-
- /// \brief getOpaqueValue - Return the opaque value placeholder.
- OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
-
- /// \brief getCond - Return the condition expression; this is defined
- /// in terms of the opaque value.
- Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
-
- /// \brief getTrueExpr - Return the subexpression which will be
- /// evaluated if the condition evaluates to true; this is defined
- /// in terms of the opaque value.
- Expr *getTrueExpr() const {
- return cast<Expr>(SubExprs[LHS]);
- }
-
- /// \brief getFalseExpr - Return the subexpression which will be
- /// evaluated if the condnition evaluates to false; this is
- /// defined in terms of the opaque value.
- Expr *getFalseExpr() const {
- return cast<Expr>(SubExprs[RHS]);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCommon()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getFalseExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BinaryConditionalOperatorClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(SubExprs, SubExprs + NUM_SUBEXPRS);
- }
-};
-
-inline Expr *AbstractConditionalOperator::getCond() const {
- if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
- return co->getCond();
- return cast<BinaryConditionalOperator>(this)->getCond();
-}
-
-inline Expr *AbstractConditionalOperator::getTrueExpr() const {
- if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
- return co->getTrueExpr();
- return cast<BinaryConditionalOperator>(this)->getTrueExpr();
-}
-
-inline Expr *AbstractConditionalOperator::getFalseExpr() const {
- if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
- return co->getFalseExpr();
- return cast<BinaryConditionalOperator>(this)->getFalseExpr();
-}
-
-/// AddrLabelExpr - The GNU address of label extension, representing &&label.
-class AddrLabelExpr : public Expr {
- SourceLocation AmpAmpLoc, LabelLoc;
- LabelDecl *Label;
-public:
- AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L,
- QualType t)
- : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false,
- false),
- AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
-
- /// \brief Build an empty address of a label expression.
- explicit AddrLabelExpr(EmptyShell Empty)
- : Expr(AddrLabelExprClass, Empty) { }
-
- SourceLocation getAmpAmpLoc() const { return AmpAmpLoc; }
- void setAmpAmpLoc(SourceLocation L) { AmpAmpLoc = L; }
- SourceLocation getLabelLoc() const { return LabelLoc; }
- void setLabelLoc(SourceLocation L) { LabelLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AmpAmpLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
-
- LabelDecl *getLabel() const { return Label; }
- void setLabel(LabelDecl *L) { Label = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AddrLabelExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
-/// The StmtExpr contains a single CompoundStmt node, which it evaluates and
-/// takes the value of the last subexpression.
-///
-/// A StmtExpr is always an r-value; values "returned" out of a
-/// StmtExpr will be copied.
-class StmtExpr : public Expr {
- Stmt *SubStmt;
- SourceLocation LParenLoc, RParenLoc;
-public:
- // FIXME: Does type-dependence need to be computed differently?
- // FIXME: Do we need to compute instantiation instantiation-dependence for
- // statements? (ugh!)
- StmtExpr(CompoundStmt *substmt, QualType T,
- SourceLocation lp, SourceLocation rp) :
- Expr(StmtExprClass, T, VK_RValue, OK_Ordinary,
- T->isDependentType(), false, false, false),
- SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
-
- /// \brief Build an empty statement expression.
- explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { }
-
- CompoundStmt *getSubStmt() { return cast<CompoundStmt>(SubStmt); }
- const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
- void setSubStmt(CompoundStmt *S) { SubStmt = S; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == StmtExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubStmt, &SubStmt+1); }
-};
-
-/// ShuffleVectorExpr - clang-specific builtin-in function
-/// __builtin_shufflevector.
-/// This AST node represents a operator that does a constant
-/// shuffle, similar to LLVM's shufflevector instruction. It takes
-/// two vectors and a variable number of constant indices,
-/// and returns the appropriately shuffled vector.
-class ShuffleVectorExpr : public Expr {
- SourceLocation BuiltinLoc, RParenLoc;
-
- // SubExprs - the list of values passed to the __builtin_shufflevector
- // function. The first two are vectors, and the rest are constant
- // indices. The number of values in this list is always
- // 2+the number of indices in the vector type.
- Stmt **SubExprs;
- unsigned NumExprs;
-
-public:
- ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type,
- SourceLocation BLoc, SourceLocation RP);
-
- /// \brief Build an empty vector-shuffle expression.
- explicit ShuffleVectorExpr(EmptyShell Empty)
- : Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { }
-
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
- void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ShuffleVectorExprClass;
- }
-
- /// getNumSubExprs - Return the size of the SubExprs array. This includes the
- /// constant expression, the actual arguments passed in, and the function
- /// pointers.
- unsigned getNumSubExprs() const { return NumExprs; }
-
- /// \brief Retrieve the array of expressions.
- Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
-
- /// getExpr - Return the Expr at the specified index.
- Expr *getExpr(unsigned Index) {
- assert((Index < NumExprs) && "Arg access out of range!");
- return cast<Expr>(SubExprs[Index]);
- }
- const Expr *getExpr(unsigned Index) const {
- assert((Index < NumExprs) && "Arg access out of range!");
- return cast<Expr>(SubExprs[Index]);
- }
-
- void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs);
-
- llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const {
- assert((N < NumExprs - 2) && "Shuffle idx out of range!");
- return getExpr(N+2)->EvaluateKnownConstInt(Ctx);
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+NumExprs);
- }
-};
-
-/// ConvertVectorExpr - Clang builtin function __builtin_convertvector
-/// This AST node provides support for converting a vector type to another
-/// vector type of the same arity.
-class ConvertVectorExpr : public Expr {
-private:
- Stmt *SrcExpr;
- TypeSourceInfo *TInfo;
- SourceLocation BuiltinLoc, RParenLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {}
-
-public:
- ConvertVectorExpr(Expr* SrcExpr, TypeSourceInfo *TI, QualType DstType,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation BuiltinLoc, SourceLocation RParenLoc)
- : Expr(ConvertVectorExprClass, DstType, VK, OK,
- DstType->isDependentType(),
- DstType->isDependentType() || SrcExpr->isValueDependent(),
- (DstType->isInstantiationDependentType() ||
- SrcExpr->isInstantiationDependent()),
- (DstType->containsUnexpandedParameterPack() ||
- SrcExpr->containsUnexpandedParameterPack())),
- SrcExpr(SrcExpr), TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
-
- /// getSrcExpr - Return the Expr to be converted.
- Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
-
- /// getTypeSourceInfo - Return the destination type.
- TypeSourceInfo *getTypeSourceInfo() const {
- return TInfo;
- }
- void setTypeSourceInfo(TypeSourceInfo *ti) {
- TInfo = ti;
- }
-
- /// getBuiltinLoc - Return the location of the __builtin_convertvector token.
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
-
- /// getRParenLoc - Return the location of final right parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ConvertVectorExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
-};
-
-/// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
-/// This AST node is similar to the conditional operator (?:) in C, with
-/// the following exceptions:
-/// - the test expression must be a integer constant expression.
-/// - the expression returned acts like the chosen subexpression in every
-/// visible way: the type is the same as that of the chosen subexpression,
-/// and all predicates (whether it's an l-value, whether it's an integer
-/// constant expression, etc.) return the same result as for the chosen
-/// sub-expression.
-class ChooseExpr : public Expr {
- enum { COND, LHS, RHS, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
- SourceLocation BuiltinLoc, RParenLoc;
- bool CondIsTrue;
-public:
- ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs,
- QualType t, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation RP, bool condIsTrue,
- bool TypeDependent, bool ValueDependent)
- : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent,
- (cond->isInstantiationDependent() ||
- lhs->isInstantiationDependent() ||
- rhs->isInstantiationDependent()),
- (cond->containsUnexpandedParameterPack() ||
- lhs->containsUnexpandedParameterPack() ||
- rhs->containsUnexpandedParameterPack())),
- BuiltinLoc(BLoc), RParenLoc(RP), CondIsTrue(condIsTrue) {
- SubExprs[COND] = cond;
- SubExprs[LHS] = lhs;
- SubExprs[RHS] = rhs;
- }
-
- /// \brief Build an empty __builtin_choose_expr.
- explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { }
-
- /// isConditionTrue - Return whether the condition is true (i.e. not
- /// equal to zero).
- bool isConditionTrue() const {
- assert(!isConditionDependent() &&
- "Dependent condition isn't true or false");
- return CondIsTrue;
- }
- void setIsConditionTrue(bool isTrue) { CondIsTrue = isTrue; }
-
- bool isConditionDependent() const {
- return getCond()->isTypeDependent() || getCond()->isValueDependent();
- }
-
- /// getChosenSubExpr - Return the subexpression chosen according to the
- /// condition.
- Expr *getChosenSubExpr() const {
- return isConditionTrue() ? getLHS() : getRHS();
- }
-
- Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
- void setCond(Expr *E) { SubExprs[COND] = E; }
- Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
- void setLHS(Expr *E) { SubExprs[LHS] = E; }
- Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- void setRHS(Expr *E) { SubExprs[RHS] = E; }
-
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
- void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ChooseExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// GNUNullExpr - Implements the GNU __null extension, which is a name
-/// for a null pointer constant that has integral type (e.g., int or
-/// long) and is the same size and alignment as a pointer. The __null
-/// extension is typically only used by system headers, which define
-/// NULL as __null in C++ rather than using 0 (which is an integer
-/// that may not match the size of a pointer).
-class GNUNullExpr : public Expr {
- /// TokenLoc - The location of the __null keyword.
- SourceLocation TokenLoc;
-
-public:
- GNUNullExpr(QualType Ty, SourceLocation Loc)
- : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false,
- false),
- TokenLoc(Loc) { }
-
- /// \brief Build an empty GNU __null expression.
- explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { }
-
- /// getTokenLocation - The location of the __null token.
- SourceLocation getTokenLocation() const { return TokenLoc; }
- void setTokenLocation(SourceLocation L) { TokenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return TokenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return TokenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GNUNullExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// Represents a call to the builtin function \c __builtin_va_arg.
-class VAArgExpr : public Expr {
- Stmt *Val;
- llvm::PointerIntPair<TypeSourceInfo *, 1, bool> TInfo;
- SourceLocation BuiltinLoc, RParenLoc;
-public:
- VAArgExpr(SourceLocation BLoc, Expr *e, TypeSourceInfo *TInfo,
- SourceLocation RPLoc, QualType t, bool IsMS)
- : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, t->isDependentType(),
- false, (TInfo->getType()->isInstantiationDependentType() ||
- e->isInstantiationDependent()),
- (TInfo->getType()->containsUnexpandedParameterPack() ||
- e->containsUnexpandedParameterPack())),
- Val(e), TInfo(TInfo, IsMS), BuiltinLoc(BLoc), RParenLoc(RPLoc) {}
-
- /// Create an empty __builtin_va_arg expression.
- explicit VAArgExpr(EmptyShell Empty)
- : Expr(VAArgExprClass, Empty), Val(nullptr), TInfo(nullptr, false) {}
-
- const Expr *getSubExpr() const { return cast<Expr>(Val); }
- Expr *getSubExpr() { return cast<Expr>(Val); }
- void setSubExpr(Expr *E) { Val = E; }
-
- /// Returns whether this is really a Win64 ABI va_arg expression.
- bool isMicrosoftABI() const { return TInfo.getInt(); }
- void setIsMicrosoftABI(bool IsMS) { TInfo.setInt(IsMS); }
-
- TypeSourceInfo *getWrittenTypeInfo() const { return TInfo.getPointer(); }
- void setWrittenTypeInfo(TypeSourceInfo *TI) { TInfo.setPointer(TI); }
-
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
- void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == VAArgExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Val, &Val+1); }
-};
-
-/// @brief Describes an C or C++ initializer list.
-///
-/// InitListExpr describes an initializer list, which can be used to
-/// initialize objects of different types, including
-/// struct/class/union types, arrays, and vectors. For example:
-///
-/// @code
-/// struct foo x = { 1, { 2, 3 } };
-/// @endcode
-///
-/// Prior to semantic analysis, an initializer list will represent the
-/// initializer list as written by the user, but will have the
-/// placeholder type "void". This initializer list is called the
-/// syntactic form of the initializer, and may contain C99 designated
-/// initializers (represented as DesignatedInitExprs), initializations
-/// of subobject members without explicit braces, and so on. Clients
-/// interested in the original syntax of the initializer list should
-/// use the syntactic form of the initializer list.
-///
-/// After semantic analysis, the initializer list will represent the
-/// semantic form of the initializer, where the initializations of all
-/// subobjects are made explicit with nested InitListExpr nodes and
-/// C99 designators have been eliminated by placing the designated
-/// initializations into the subobject they initialize. Additionally,
-/// any "holes" in the initialization, where no initializer has been
-/// specified for a particular subobject, will be replaced with
-/// implicitly-generated ImplicitValueInitExpr expressions that
-/// value-initialize the subobjects. Note, however, that the
-/// initializer lists may still have fewer initializers than there are
-/// elements to initialize within the object.
-///
-/// After semantic analysis has completed, given an initializer list,
-/// method isSemanticForm() returns true if and only if this is the
-/// semantic form of the initializer list (note: the same AST node
-/// may at the same time be the syntactic form).
-/// Given the semantic form of the initializer list, one can retrieve
-/// the syntactic form of that initializer list (when different)
-/// using method getSyntacticForm(); the method returns null if applied
-/// to a initializer list which is already in syntactic form.
-/// Similarly, given the syntactic form (i.e., an initializer list such
-/// that isSemanticForm() returns false), one can retrieve the semantic
-/// form using method getSemanticForm().
-/// Since many initializer lists have the same syntactic and semantic forms,
-/// getSyntacticForm() may return NULL, indicating that the current
-/// semantic initializer list also serves as its syntactic form.
-class InitListExpr : public Expr {
- // FIXME: Eliminate this vector in favor of ASTContext allocation
- typedef ASTVector<Stmt *> InitExprsTy;
- InitExprsTy InitExprs;
- SourceLocation LBraceLoc, RBraceLoc;
-
- /// The alternative form of the initializer list (if it exists).
- /// The int part of the pair stores whether this initializer list is
- /// in semantic form. If not null, the pointer points to:
- /// - the syntactic form, if this is in semantic form;
- /// - the semantic form, if this is in syntactic form.
- llvm::PointerIntPair<InitListExpr *, 1, bool> AltForm;
-
- /// \brief Either:
- /// If this initializer list initializes an array with more elements than
- /// there are initializers in the list, specifies an expression to be used
- /// for value initialization of the rest of the elements.
- /// Or
- /// If this initializer list initializes a union, specifies which
- /// field within the union will be initialized.
- llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
-
-public:
- InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
- ArrayRef<Expr*> initExprs, SourceLocation rbraceloc);
-
- /// \brief Build an empty initializer list.
- explicit InitListExpr(EmptyShell Empty)
- : Expr(InitListExprClass, Empty) { }
-
- unsigned getNumInits() const { return InitExprs.size(); }
-
- /// \brief Retrieve the set of initializers.
- Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); }
-
- ArrayRef<Expr *> inits() {
- return llvm::makeArrayRef(getInits(), getNumInits());
- }
-
- const Expr *getInit(unsigned Init) const {
- assert(Init < getNumInits() && "Initializer access out of range!");
- return cast_or_null<Expr>(InitExprs[Init]);
- }
-
- Expr *getInit(unsigned Init) {
- assert(Init < getNumInits() && "Initializer access out of range!");
- return cast_or_null<Expr>(InitExprs[Init]);
- }
-
- void setInit(unsigned Init, Expr *expr) {
- assert(Init < getNumInits() && "Initializer access out of range!");
- InitExprs[Init] = expr;
-
- if (expr) {
- ExprBits.TypeDependent |= expr->isTypeDependent();
- ExprBits.ValueDependent |= expr->isValueDependent();
- ExprBits.InstantiationDependent |= expr->isInstantiationDependent();
- ExprBits.ContainsUnexpandedParameterPack |=
- expr->containsUnexpandedParameterPack();
- }
- }
-
- /// \brief Reserve space for some number of initializers.
- void reserveInits(const ASTContext &C, unsigned NumInits);
-
- /// @brief Specify the number of initializers
- ///
- /// If there are more than @p NumInits initializers, the remaining
- /// initializers will be destroyed. If there are fewer than @p
- /// NumInits initializers, NULL expressions will be added for the
- /// unknown initializers.
- void resizeInits(const ASTContext &Context, unsigned NumInits);
-
- /// @brief Updates the initializer at index @p Init with the new
- /// expression @p expr, and returns the old expression at that
- /// location.
- ///
- /// When @p Init is out of range for this initializer list, the
- /// initializer list will be extended with NULL expressions to
- /// accommodate the new entry.
- Expr *updateInit(const ASTContext &C, unsigned Init, Expr *expr);
-
- /// \brief If this initializer list initializes an array with more elements
- /// than there are initializers in the list, specifies an expression to be
- /// used for value initialization of the rest of the elements.
- Expr *getArrayFiller() {
- return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
- }
- const Expr *getArrayFiller() const {
- return const_cast<InitListExpr *>(this)->getArrayFiller();
- }
- void setArrayFiller(Expr *filler);
-
- /// \brief Return true if this is an array initializer and its array "filler"
- /// has been set.
- bool hasArrayFiller() const { return getArrayFiller(); }
-
- /// \brief If this initializes a union, specifies which field in the
- /// union to initialize.
- ///
- /// Typically, this field is the first named field within the
- /// union. However, a designated initializer can specify the
- /// initialization of a different field within the union.
- FieldDecl *getInitializedFieldInUnion() {
- return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
- }
- const FieldDecl *getInitializedFieldInUnion() const {
- return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion();
- }
- void setInitializedFieldInUnion(FieldDecl *FD) {
- assert((FD == nullptr
- || getInitializedFieldInUnion() == nullptr
- || getInitializedFieldInUnion() == FD)
- && "Only one field of a union may be initialized at a time!");
- ArrayFillerOrUnionFieldInit = FD;
- }
-
- // Explicit InitListExpr's originate from source code (and have valid source
- // locations). Implicit InitListExpr's are created by the semantic analyzer.
- bool isExplicit() {
- return LBraceLoc.isValid() && RBraceLoc.isValid();
- }
-
- // Is this an initializer for an array of characters, initialized by a string
- // literal or an @encode?
- bool isStringLiteralInit() const;
-
- SourceLocation getLBraceLoc() const { return LBraceLoc; }
- void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
- SourceLocation getRBraceLoc() const { return RBraceLoc; }
- void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }
-
- bool isSemanticForm() const { return AltForm.getInt(); }
- InitListExpr *getSemanticForm() const {
- return isSemanticForm() ? nullptr : AltForm.getPointer();
- }
- InitListExpr *getSyntacticForm() const {
- return isSemanticForm() ? AltForm.getPointer() : nullptr;
- }
-
- void setSyntacticForm(InitListExpr *Init) {
- AltForm.setPointer(Init);
- AltForm.setInt(true);
- Init->AltForm.setPointer(this);
- Init->AltForm.setInt(false);
- }
-
- bool hadArrayRangeDesignator() const {
- return InitListExprBits.HadArrayRangeDesignator != 0;
- }
- void sawArrayRangeDesignator(bool ARD = true) {
- InitListExprBits.HadArrayRangeDesignator = ARD;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == InitListExprClass;
- }
-
- // Iterators
- child_range children() {
- // FIXME: This does not include the array filler expression.
- if (InitExprs.empty())
- return child_range(child_iterator(), child_iterator());
- return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
- }
-
- typedef InitExprsTy::iterator iterator;
- typedef InitExprsTy::const_iterator const_iterator;
- typedef InitExprsTy::reverse_iterator reverse_iterator;
- typedef InitExprsTy::const_reverse_iterator const_reverse_iterator;
-
- iterator begin() { return InitExprs.begin(); }
- const_iterator begin() const { return InitExprs.begin(); }
- iterator end() { return InitExprs.end(); }
- const_iterator end() const { return InitExprs.end(); }
- reverse_iterator rbegin() { return InitExprs.rbegin(); }
- const_reverse_iterator rbegin() const { return InitExprs.rbegin(); }
- reverse_iterator rend() { return InitExprs.rend(); }
- const_reverse_iterator rend() const { return InitExprs.rend(); }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// @brief Represents a C99 designated initializer expression.
-///
-/// A designated initializer expression (C99 6.7.8) contains one or
-/// more designators (which can be field designators, array
-/// designators, or GNU array-range designators) followed by an
-/// expression that initializes the field or element(s) that the
-/// designators refer to. For example, given:
-///
-/// @code
-/// struct point {
-/// double x;
-/// double y;
-/// };
-/// struct point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
-/// @endcode
-///
-/// The InitListExpr contains three DesignatedInitExprs, the first of
-/// which covers @c [2].y=1.0. This DesignatedInitExpr will have two
-/// designators, one array designator for @c [2] followed by one field
-/// designator for @c .y. The initialization expression will be 1.0.
-class DesignatedInitExpr final
- : public Expr,
- private llvm::TrailingObjects<DesignatedInitExpr, Stmt *> {
-public:
- /// \brief Forward declaration of the Designator class.
- class Designator;
-
-private:
- /// The location of the '=' or ':' prior to the actual initializer
- /// expression.
- SourceLocation EqualOrColonLoc;
-
- /// Whether this designated initializer used the GNU deprecated
- /// syntax rather than the C99 '=' syntax.
- bool GNUSyntax : 1;
-
- /// The number of designators in this initializer expression.
- unsigned NumDesignators : 15;
-
- /// The number of subexpressions of this initializer expression,
- /// which contains both the initializer and any additional
- /// expressions used by array and array-range designators.
- unsigned NumSubExprs : 16;
-
- /// \brief The designators in this designated initialization
- /// expression.
- Designator *Designators;
-
-
- DesignatedInitExpr(const ASTContext &C, QualType Ty, unsigned NumDesignators,
- const Designator *Designators,
- SourceLocation EqualOrColonLoc, bool GNUSyntax,
- ArrayRef<Expr*> IndexExprs, Expr *Init);
-
- explicit DesignatedInitExpr(unsigned NumSubExprs)
- : Expr(DesignatedInitExprClass, EmptyShell()),
- NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
-
-public:
- /// A field designator, e.g., ".x".
- struct FieldDesignator {
- /// Refers to the field that is being initialized. The low bit
- /// of this field determines whether this is actually a pointer
- /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
- /// initially constructed, a field designator will store an
- /// IdentifierInfo*. After semantic analysis has resolved that
- /// name, the field designator will instead store a FieldDecl*.
- uintptr_t NameOrField;
-
- /// The location of the '.' in the designated initializer.
- unsigned DotLoc;
-
- /// The location of the field name in the designated initializer.
- unsigned FieldLoc;
- };
-
- /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
- struct ArrayOrRangeDesignator {
- /// Location of the first index expression within the designated
- /// initializer expression's list of subexpressions.
- unsigned Index;
- /// The location of the '[' starting the array range designator.
- unsigned LBracketLoc;
- /// The location of the ellipsis separating the start and end
- /// indices. Only valid for GNU array-range designators.
- unsigned EllipsisLoc;
- /// The location of the ']' terminating the array range designator.
- unsigned RBracketLoc;
- };
-
- /// @brief Represents a single C99 designator.
- ///
- /// @todo This class is infuriatingly similar to clang::Designator,
- /// but minor differences (storing indices vs. storing pointers)
- /// keep us from reusing it. Try harder, later, to rectify these
- /// differences.
- class Designator {
- /// @brief The kind of designator this describes.
- enum {
- FieldDesignator,
- ArrayDesignator,
- ArrayRangeDesignator
- } Kind;
-
- union {
- /// A field designator, e.g., ".x".
- struct FieldDesignator Field;
- /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
- struct ArrayOrRangeDesignator ArrayOrRange;
- };
- friend class DesignatedInitExpr;
-
- public:
- Designator() {}
-
- /// @brief Initializes a field designator.
- Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc,
- SourceLocation FieldLoc)
- : Kind(FieldDesignator) {
- Field.NameOrField = reinterpret_cast<uintptr_t>(FieldName) | 0x01;
- Field.DotLoc = DotLoc.getRawEncoding();
- Field.FieldLoc = FieldLoc.getRawEncoding();
- }
-
- /// @brief Initializes an array designator.
- Designator(unsigned Index, SourceLocation LBracketLoc,
- SourceLocation RBracketLoc)
- : Kind(ArrayDesignator) {
- ArrayOrRange.Index = Index;
- ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
- ArrayOrRange.EllipsisLoc = SourceLocation().getRawEncoding();
- ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
- }
-
- /// @brief Initializes a GNU array-range designator.
- Designator(unsigned Index, SourceLocation LBracketLoc,
- SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
- : Kind(ArrayRangeDesignator) {
- ArrayOrRange.Index = Index;
- ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
- ArrayOrRange.EllipsisLoc = EllipsisLoc.getRawEncoding();
- ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
- }
-
- bool isFieldDesignator() const { return Kind == FieldDesignator; }
- bool isArrayDesignator() const { return Kind == ArrayDesignator; }
- bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
-
- IdentifierInfo *getFieldName() const;
-
- FieldDecl *getField() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- if (Field.NameOrField & 0x01)
- return nullptr;
- else
- return reinterpret_cast<FieldDecl *>(Field.NameOrField);
- }
-
- void setField(FieldDecl *FD) {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- Field.NameOrField = reinterpret_cast<uintptr_t>(FD);
- }
-
- SourceLocation getDotLoc() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- return SourceLocation::getFromRawEncoding(Field.DotLoc);
- }
-
- SourceLocation getFieldLoc() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- return SourceLocation::getFromRawEncoding(Field.FieldLoc);
- }
-
- SourceLocation getLBracketLoc() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
- "Only valid on an array or array-range designator");
- return SourceLocation::getFromRawEncoding(ArrayOrRange.LBracketLoc);
- }
-
- SourceLocation getRBracketLoc() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
- "Only valid on an array or array-range designator");
- return SourceLocation::getFromRawEncoding(ArrayOrRange.RBracketLoc);
- }
-
- SourceLocation getEllipsisLoc() const {
- assert(Kind == ArrayRangeDesignator &&
- "Only valid on an array-range designator");
- return SourceLocation::getFromRawEncoding(ArrayOrRange.EllipsisLoc);
- }
-
- unsigned getFirstExprIndex() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
- "Only valid on an array or array-range designator");
- return ArrayOrRange.Index;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (Kind == FieldDesignator)
- return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
- else
- return getLBracketLoc();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
- }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
- }
- };
-
- static DesignatedInitExpr *Create(const ASTContext &C,
- Designator *Designators,
- unsigned NumDesignators,
- ArrayRef<Expr*> IndexExprs,
- SourceLocation EqualOrColonLoc,
- bool GNUSyntax, Expr *Init);
-
- static DesignatedInitExpr *CreateEmpty(const ASTContext &C,
- unsigned NumIndexExprs);
-
- /// @brief Returns the number of designators in this initializer.
- unsigned size() const { return NumDesignators; }
-
- // Iterator access to the designators.
- typedef Designator *designators_iterator;
- designators_iterator designators_begin() { return Designators; }
- designators_iterator designators_end() {
- return Designators + NumDesignators;
- }
-
- typedef const Designator *const_designators_iterator;
- const_designators_iterator designators_begin() const { return Designators; }
- const_designators_iterator designators_end() const {
- return Designators + NumDesignators;
- }
-
- typedef llvm::iterator_range<designators_iterator> designators_range;
- designators_range designators() {
- return designators_range(designators_begin(), designators_end());
- }
-
- typedef llvm::iterator_range<const_designators_iterator>
- designators_const_range;
- designators_const_range designators() const {
- return designators_const_range(designators_begin(), designators_end());
- }
-
- typedef std::reverse_iterator<designators_iterator>
- reverse_designators_iterator;
- reverse_designators_iterator designators_rbegin() {
- return reverse_designators_iterator(designators_end());
- }
- reverse_designators_iterator designators_rend() {
- return reverse_designators_iterator(designators_begin());
- }
-
- typedef std::reverse_iterator<const_designators_iterator>
- const_reverse_designators_iterator;
- const_reverse_designators_iterator designators_rbegin() const {
- return const_reverse_designators_iterator(designators_end());
- }
- const_reverse_designators_iterator designators_rend() const {
- return const_reverse_designators_iterator(designators_begin());
- }
-
- Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; }
-
- void setDesignators(const ASTContext &C, const Designator *Desigs,
- unsigned NumDesigs);
-
- Expr *getArrayIndex(const Designator &D) const;
- Expr *getArrayRangeStart(const Designator &D) const;
- Expr *getArrayRangeEnd(const Designator &D) const;
-
- /// @brief Retrieve the location of the '=' that precedes the
- /// initializer value itself, if present.
- SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
- void setEqualOrColonLoc(SourceLocation L) { EqualOrColonLoc = L; }
-
- /// @brief Determines whether this designated initializer used the
- /// deprecated GNU syntax for designated initializers.
- bool usesGNUSyntax() const { return GNUSyntax; }
- void setGNUSyntax(bool GNU) { GNUSyntax = GNU; }
-
- /// @brief Retrieve the initializer value.
- Expr *getInit() const {
- return cast<Expr>(*const_cast<DesignatedInitExpr*>(this)->child_begin());
- }
-
- void setInit(Expr *init) {
- *child_begin() = init;
- }
-
- /// \brief Retrieve the total number of subexpressions in this
- /// designated initializer expression, including the actual
- /// initialized value and any expressions that occur within array
- /// and array-range designators.
- unsigned getNumSubExprs() const { return NumSubExprs; }
-
- Expr *getSubExpr(unsigned Idx) const {
- assert(Idx < NumSubExprs && "Subscript out of range");
- return cast<Expr>(getTrailingObjects<Stmt *>()[Idx]);
- }
-
- void setSubExpr(unsigned Idx, Expr *E) {
- assert(Idx < NumSubExprs && "Subscript out of range");
- getTrailingObjects<Stmt *>()[Idx] = E;
- }
-
- /// \brief Replaces the designator at index @p Idx with the series
- /// of designators in [First, Last).
- void ExpandDesignator(const ASTContext &C, unsigned Idx,
- const Designator *First, const Designator *Last);
-
- SourceRange getDesignatorsSourceRange() const;
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DesignatedInitExprClass;
- }
-
- // Iterators
- child_range children() {
- Stmt **begin = getTrailingObjects<Stmt *>();
- return child_range(begin, begin + NumSubExprs);
- }
-
- friend TrailingObjects;
-};
-
-/// \brief Represents a place-holder for an object not to be initialized by
-/// anything.
-///
-/// This only makes sense when it appears as part of an updater of a
-/// DesignatedInitUpdateExpr (see below). The base expression of a DIUE
-/// initializes a big object, and the NoInitExpr's mark the spots within the
-/// big object not to be overwritten by the updater.
-///
-/// \see DesignatedInitUpdateExpr
-class NoInitExpr : public Expr {
-public:
- explicit NoInitExpr(QualType ty)
- : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary,
- false, false, ty->isInstantiationDependentType(), false) { }
-
- explicit NoInitExpr(EmptyShell Empty)
- : Expr(NoInitExprClass, Empty) { }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == NoInitExprClass;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-// In cases like:
-// struct Q { int a, b, c; };
-// Q *getQ();
-// void foo() {
-// struct A { Q q; } a = { *getQ(), .q.b = 3 };
-// }
-//
-// We will have an InitListExpr for a, with type A, and then a
-// DesignatedInitUpdateExpr for "a.q" with type Q. The "base" for this DIUE
-// is the call expression *getQ(); the "updater" for the DIUE is ".q.b = 3"
-//
-class DesignatedInitUpdateExpr : public Expr {
- // BaseAndUpdaterExprs[0] is the base expression;
- // BaseAndUpdaterExprs[1] is an InitListExpr overwriting part of the base.
- Stmt *BaseAndUpdaterExprs[2];
-
-public:
- DesignatedInitUpdateExpr(const ASTContext &C, SourceLocation lBraceLoc,
- Expr *baseExprs, SourceLocation rBraceLoc);
-
- explicit DesignatedInitUpdateExpr(EmptyShell Empty)
- : Expr(DesignatedInitUpdateExprClass, Empty) { }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DesignatedInitUpdateExprClass;
- }
-
- Expr *getBase() const { return cast<Expr>(BaseAndUpdaterExprs[0]); }
- void setBase(Expr *Base) { BaseAndUpdaterExprs[0] = Base; }
-
- InitListExpr *getUpdater() const {
- return cast<InitListExpr>(BaseAndUpdaterExprs[1]);
- }
- void setUpdater(Expr *Updater) { BaseAndUpdaterExprs[1] = Updater; }
-
- // Iterators
- // children = the base and the updater
- child_range children() {
- return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2);
- }
-};
-
-/// \brief Represents an implicitly-generated value initialization of
-/// an object of a given type.
-///
-/// Implicit value initializations occur within semantic initializer
-/// list expressions (InitListExpr) as placeholders for subobject
-/// initializations not explicitly specified by the user.
-///
-/// \see InitListExpr
-class ImplicitValueInitExpr : public Expr {
-public:
- explicit ImplicitValueInitExpr(QualType ty)
- : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary,
- false, false, ty->isInstantiationDependentType(), false) { }
-
- /// \brief Construct an empty implicit value initialization.
- explicit ImplicitValueInitExpr(EmptyShell Empty)
- : Expr(ImplicitValueInitExprClass, Empty) { }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ImplicitValueInitExprClass;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-class ParenListExpr : public Expr {
- Stmt **Exprs;
- unsigned NumExprs;
- SourceLocation LParenLoc, RParenLoc;
-
-public:
- ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
- ArrayRef<Expr*> exprs, SourceLocation rparenloc);
-
- /// \brief Build an empty paren list.
- explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
-
- unsigned getNumExprs() const { return NumExprs; }
-
- const Expr* getExpr(unsigned Init) const {
- assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
- }
-
- Expr* getExpr(unsigned Init) {
- assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
- }
-
- Expr **getExprs() { return reinterpret_cast<Expr **>(Exprs); }
-
- ArrayRef<Expr *> exprs() {
- return llvm::makeArrayRef(getExprs(), getNumExprs());
- }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ParenListExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Exprs[0], &Exprs[0]+NumExprs);
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief Represents a C11 generic selection.
-///
-/// A generic selection (C11 6.5.1.1) contains an unevaluated controlling
-/// expression, followed by one or more generic associations. Each generic
-/// association specifies a type name and an expression, or "default" and an
-/// expression (in which case it is known as a default generic association).
-/// The type and value of the generic selection are identical to those of its
-/// result expression, which is defined as the expression in the generic
-/// association with a type name that is compatible with the type of the
-/// controlling expression, or the expression in the default generic association
-/// if no types are compatible. For example:
-///
-/// @code
-/// _Generic(X, double: 1, float: 2, default: 3)
-/// @endcode
-///
-/// The above expression evaluates to 1 if 1.0 is substituted for X, 2 if 1.0f
-/// or 3 if "hello".
-///
-/// As an extension, generic selections are allowed in C++, where the following
-/// additional semantics apply:
-///
-/// Any generic selection whose controlling expression is type-dependent or
-/// which names a dependent type in its association list is result-dependent,
-/// which means that the choice of result expression is dependent.
-/// Result-dependent generic associations are both type- and value-dependent.
-class GenericSelectionExpr : public Expr {
- enum { CONTROLLING, END_EXPR };
- TypeSourceInfo **AssocTypes;
- Stmt **SubExprs;
- unsigned NumAssocs, ResultIndex;
- SourceLocation GenericLoc, DefaultLoc, RParenLoc;
-
-public:
- GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc, SourceLocation RParenLoc,
- bool ContainsUnexpandedParameterPack,
- unsigned ResultIndex);
-
- /// This constructor is used in the result-dependent case.
- GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc, SourceLocation RParenLoc,
- bool ContainsUnexpandedParameterPack);
-
- explicit GenericSelectionExpr(EmptyShell Empty)
- : Expr(GenericSelectionExprClass, Empty) { }
-
- unsigned getNumAssocs() const { return NumAssocs; }
-
- SourceLocation getGenericLoc() const { return GenericLoc; }
- SourceLocation getDefaultLoc() const { return DefaultLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- const Expr *getAssocExpr(unsigned i) const {
- return cast<Expr>(SubExprs[END_EXPR+i]);
- }
- Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
-
- const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
- return AssocTypes[i];
- }
- TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
-
- QualType getAssocType(unsigned i) const {
- if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))
- return TS->getType();
- else
- return QualType();
- }
-
- const Expr *getControllingExpr() const {
- return cast<Expr>(SubExprs[CONTROLLING]);
- }
- Expr *getControllingExpr() { return cast<Expr>(SubExprs[CONTROLLING]); }
-
- /// Whether this generic selection is result-dependent.
- bool isResultDependent() const { return ResultIndex == -1U; }
-
- /// The zero-based index of the result expression's generic association in
- /// the generic selection's association list. Defined only if the
- /// generic selection is not result-dependent.
- unsigned getResultIndex() const {
- assert(!isResultDependent() && "Generic selection is result-dependent");
- return ResultIndex;
- }
-
- /// The generic selection's result expression. Defined only if the
- /// generic selection is not result-dependent.
- const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
- Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return GenericLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GenericSelectionExprClass;
- }
-
- child_range children() {
- return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs);
- }
-
- friend class ASTStmtReader;
-};
-
-//===----------------------------------------------------------------------===//
-// Clang Extensions
-//===----------------------------------------------------------------------===//
-
-/// ExtVectorElementExpr - This represents access to specific elements of a
-/// vector, and may occur on the left hand side or right hand side. For example
-/// the following is legal: "V.xy = V.zw" if V is a 4 element extended vector.
-///
-/// Note that the base may have either vector or pointer to vector type, just
-/// like a struct field reference.
-///
-class ExtVectorElementExpr : public Expr {
- Stmt *Base;
- IdentifierInfo *Accessor;
- SourceLocation AccessorLoc;
-public:
- ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base,
- IdentifierInfo &accessor, SourceLocation loc)
- : Expr(ExtVectorElementExprClass, ty, VK,
- (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent),
- base->isTypeDependent(), base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- Base(base), Accessor(&accessor), AccessorLoc(loc) {}
-
- /// \brief Build an empty vector element expression.
- explicit ExtVectorElementExpr(EmptyShell Empty)
- : Expr(ExtVectorElementExprClass, Empty) { }
-
- const Expr *getBase() const { return cast<Expr>(Base); }
- Expr *getBase() { return cast<Expr>(Base); }
- void setBase(Expr *E) { Base = E; }
-
- IdentifierInfo &getAccessor() const { return *Accessor; }
- void setAccessor(IdentifierInfo *II) { Accessor = II; }
-
- SourceLocation getAccessorLoc() const { return AccessorLoc; }
- void setAccessorLoc(SourceLocation L) { AccessorLoc = L; }
-
- /// getNumElements - Get the number of components being selected.
- unsigned getNumElements() const;
-
- /// containsDuplicateElements - Return true if any element access is
- /// repeated.
- bool containsDuplicateElements() const;
-
- /// getEncodedElementAccess - Encode the elements accessed into an llvm
- /// aggregate Constant of ConstantInt(s).
- void getEncodedElementAccess(SmallVectorImpl<uint32_t> &Elts) const;
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return AccessorLoc; }
-
- /// isArrow - Return true if the base expression is a pointer to vector,
- /// return false if the base expression is a vector.
- bool isArrow() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExtVectorElementExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
-};
-
-/// BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
-/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
-class BlockExpr : public Expr {
-protected:
- BlockDecl *TheBlock;
-public:
- BlockExpr(BlockDecl *BD, QualType ty)
- : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary,
- ty->isDependentType(), ty->isDependentType(),
- ty->isInstantiationDependentType() || BD->isDependentContext(),
- false),
- TheBlock(BD) {}
-
- /// \brief Build an empty block expression.
- explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { }
-
- const BlockDecl *getBlockDecl() const { return TheBlock; }
- BlockDecl *getBlockDecl() { return TheBlock; }
- void setBlockDecl(BlockDecl *BD) { TheBlock = BD; }
-
- // Convenience functions for probing the underlying BlockDecl.
- SourceLocation getCaretLocation() const;
- const Stmt *getBody() const;
- Stmt *getBody();
-
- SourceLocation getLocStart() const LLVM_READONLY { return getCaretLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getBody()->getLocEnd(); }
-
- /// getFunctionType - Return the underlying function type for this block.
- const FunctionProtoType *getFunctionType() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BlockExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
-/// This AST node provides support for reinterpreting a type to another
-/// type of the same size.
-class AsTypeExpr : public Expr {
-private:
- Stmt *SrcExpr;
- SourceLocation BuiltinLoc, RParenLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {}
-
-public:
- AsTypeExpr(Expr* SrcExpr, QualType DstType,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation BuiltinLoc, SourceLocation RParenLoc)
- : Expr(AsTypeExprClass, DstType, VK, OK,
- DstType->isDependentType(),
- DstType->isDependentType() || SrcExpr->isValueDependent(),
- (DstType->isInstantiationDependentType() ||
- SrcExpr->isInstantiationDependent()),
- (DstType->containsUnexpandedParameterPack() ||
- SrcExpr->containsUnexpandedParameterPack())),
- SrcExpr(SrcExpr), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
-
- /// getSrcExpr - Return the Expr to be converted.
- Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
-
- /// getBuiltinLoc - Return the location of the __builtin_astype token.
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
-
- /// getRParenLoc - Return the location of final right parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AsTypeExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
-};
-
-/// PseudoObjectExpr - An expression which accesses a pseudo-object
-/// l-value. A pseudo-object is an abstract object, accesses to which
-/// are translated to calls. The pseudo-object expression has a
-/// syntactic form, which shows how the expression was actually
-/// written in the source code, and a semantic form, which is a series
-/// of expressions to be executed in order which detail how the
-/// operation is actually evaluated. Optionally, one of the semantic
-/// forms may also provide a result value for the expression.
-///
-/// If any of the semantic-form expressions is an OpaqueValueExpr,
-/// that OVE is required to have a source expression, and it is bound
-/// to the result of that source expression. Such OVEs may appear
-/// only in subsequent semantic-form expressions and as
-/// sub-expressions of the syntactic form.
-///
-/// PseudoObjectExpr should be used only when an operation can be
-/// usefully described in terms of fairly simple rewrite rules on
-/// objects and functions that are meant to be used by end-developers.
-/// For example, under the Itanium ABI, dynamic casts are implemented
-/// as a call to a runtime function called __dynamic_cast; using this
-/// class to describe that would be inappropriate because that call is
-/// not really part of the user-visible semantics, and instead the
-/// cast is properly reflected in the AST and IR-generation has been
-/// taught to generate the call as necessary. In contrast, an
-/// Objective-C property access is semantically defined to be
-/// equivalent to a particular message send, and this is very much
-/// part of the user model. The name of this class encourages this
-/// modelling design.
-class PseudoObjectExpr final
- : public Expr,
- private llvm::TrailingObjects<PseudoObjectExpr, Expr *> {
- // PseudoObjectExprBits.NumSubExprs - The number of sub-expressions.
- // Always at least two, because the first sub-expression is the
- // syntactic form.
-
- // PseudoObjectExprBits.ResultIndex - The index of the
- // sub-expression holding the result. 0 means the result is void,
- // which is unambiguous because it's the index of the syntactic
- // form. Note that this is therefore 1 higher than the value passed
- // in to Create, which is an index within the semantic forms.
- // Note also that ASTStmtWriter assumes this encoding.
-
- Expr **getSubExprsBuffer() { return getTrailingObjects<Expr *>(); }
- const Expr * const *getSubExprsBuffer() const {
- return getTrailingObjects<Expr *>();
- }
-
- PseudoObjectExpr(QualType type, ExprValueKind VK,
- Expr *syntactic, ArrayRef<Expr*> semantic,
- unsigned resultIndex);
-
- PseudoObjectExpr(EmptyShell shell, unsigned numSemanticExprs);
-
- unsigned getNumSubExprs() const {
- return PseudoObjectExprBits.NumSubExprs;
- }
-
-public:
- /// NoResult - A value for the result index indicating that there is
- /// no semantic result.
- enum : unsigned { NoResult = ~0U };
-
- static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic,
- ArrayRef<Expr*> semantic,
- unsigned resultIndex);
-
- static PseudoObjectExpr *Create(const ASTContext &Context, EmptyShell shell,
- unsigned numSemanticExprs);
-
- /// Return the syntactic form of this expression, i.e. the
- /// expression it actually looks like. Likely to be expressed in
- /// terms of OpaqueValueExprs bound in the semantic form.
- Expr *getSyntacticForm() { return getSubExprsBuffer()[0]; }
- const Expr *getSyntacticForm() const { return getSubExprsBuffer()[0]; }
-
- /// Return the index of the result-bearing expression into the semantics
- /// expressions, or PseudoObjectExpr::NoResult if there is none.
- unsigned getResultExprIndex() const {
- if (PseudoObjectExprBits.ResultIndex == 0) return NoResult;
- return PseudoObjectExprBits.ResultIndex - 1;
- }
-
- /// Return the result-bearing expression, or null if there is none.
- Expr *getResultExpr() {
- if (PseudoObjectExprBits.ResultIndex == 0)
- return nullptr;
- return getSubExprsBuffer()[PseudoObjectExprBits.ResultIndex];
- }
- const Expr *getResultExpr() const {
- return const_cast<PseudoObjectExpr*>(this)->getResultExpr();
- }
-
- unsigned getNumSemanticExprs() const { return getNumSubExprs() - 1; }
-
- typedef Expr * const *semantics_iterator;
- typedef const Expr * const *const_semantics_iterator;
- semantics_iterator semantics_begin() {
- return getSubExprsBuffer() + 1;
- }
- const_semantics_iterator semantics_begin() const {
- return getSubExprsBuffer() + 1;
- }
- semantics_iterator semantics_end() {
- return getSubExprsBuffer() + getNumSubExprs();
- }
- const_semantics_iterator semantics_end() const {
- return getSubExprsBuffer() + getNumSubExprs();
- }
-
- llvm::iterator_range<semantics_iterator> semantics() {
- return llvm::make_range(semantics_begin(), semantics_end());
- }
- llvm::iterator_range<const_semantics_iterator> semantics() const {
- return llvm::make_range(semantics_begin(), semantics_end());
- }
-
- Expr *getSemanticExpr(unsigned index) {
- assert(index + 1 < getNumSubExprs());
- return getSubExprsBuffer()[index + 1];
- }
- const Expr *getSemanticExpr(unsigned index) const {
- return const_cast<PseudoObjectExpr*>(this)->getSemanticExpr(index);
- }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getSyntacticForm()->getExprLoc();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getSyntacticForm()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSyntacticForm()->getLocEnd();
- }
-
- child_range children() {
- Stmt **cs = reinterpret_cast<Stmt**>(getSubExprsBuffer());
- return child_range(cs, cs + getNumSubExprs());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PseudoObjectExprClass;
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-};
-
-/// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
-/// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the
-/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>.
-/// All of these instructions take one primary pointer and at least one memory
-/// order.
-class AtomicExpr : public Expr {
-public:
- enum AtomicOp {
-#define BUILTIN(ID, TYPE, ATTRS)
-#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) AO ## ID,
-#include "clang/Basic/Builtins.def"
- // Avoid trailing comma
- BI_First = 0
- };
-
- // The ABI values for various atomic memory orderings.
- enum AtomicOrderingKind {
- AO_ABI_memory_order_relaxed = 0,
- AO_ABI_memory_order_consume = 1,
- AO_ABI_memory_order_acquire = 2,
- AO_ABI_memory_order_release = 3,
- AO_ABI_memory_order_acq_rel = 4,
- AO_ABI_memory_order_seq_cst = 5
- };
-
-private:
- enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- unsigned NumSubExprs;
- SourceLocation BuiltinLoc, RParenLoc;
- AtomicOp Op;
-
- friend class ASTStmtReader;
-
-public:
- AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t,
- AtomicOp op, SourceLocation RP);
-
- /// \brief Determine the number of arguments the specified atomic builtin
- /// should have.
- static unsigned getNumSubExprs(AtomicOp Op);
-
- /// \brief Build an empty AtomicExpr.
- explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) { }
-
- Expr *getPtr() const {
- return cast<Expr>(SubExprs[PTR]);
- }
- Expr *getOrder() const {
- return cast<Expr>(SubExprs[ORDER]);
- }
- Expr *getVal1() const {
- if (Op == AO__c11_atomic_init)
- return cast<Expr>(SubExprs[ORDER]);
- assert(NumSubExprs > VAL1);
- return cast<Expr>(SubExprs[VAL1]);
- }
- Expr *getOrderFail() const {
- assert(NumSubExprs > ORDER_FAIL);
- return cast<Expr>(SubExprs[ORDER_FAIL]);
- }
- Expr *getVal2() const {
- if (Op == AO__atomic_exchange)
- return cast<Expr>(SubExprs[ORDER_FAIL]);
- assert(NumSubExprs > VAL2);
- return cast<Expr>(SubExprs[VAL2]);
- }
- Expr *getWeak() const {
- assert(NumSubExprs > WEAK);
- return cast<Expr>(SubExprs[WEAK]);
- }
-
- AtomicOp getOp() const { return Op; }
- unsigned getNumSubExprs() { return NumSubExprs; }
-
- Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
-
- bool isVolatile() const {
- return getPtr()->getType()->getPointeeType().isVolatileQualified();
- }
-
- bool isCmpXChg() const {
- return getOp() == AO__c11_atomic_compare_exchange_strong ||
- getOp() == AO__c11_atomic_compare_exchange_weak ||
- getOp() == AO__atomic_compare_exchange ||
- getOp() == AO__atomic_compare_exchange_n;
- }
-
- SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AtomicExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(SubExprs, SubExprs+NumSubExprs);
- }
-};
-
-/// TypoExpr - Internal placeholder for expressions where typo correction
-/// still needs to be performed and/or an error diagnostic emitted.
-class TypoExpr : public Expr {
-public:
- TypoExpr(QualType T)
- : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary,
- /*isTypeDependent*/ true,
- /*isValueDependent*/ true,
- /*isInstantiationDependent*/ true,
- /*containsUnexpandedParameterPack*/ false) {
- assert(T->isDependentType() && "TypoExpr given a non-dependent type");
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == TypoExprClass;
- }
-
-};
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_EXPR_H
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
deleted file mode 100644
index 0608aba..0000000
--- a/include/clang/AST/ExprCXX.h
+++ /dev/null
@@ -1,4179 +0,0 @@
-//===--- ExprCXX.h - Classes for representing expressions -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the clang::Expr interface and subclasses for C++ expressions.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPRCXX_H
-#define LLVM_CLANG_AST_EXPRCXX_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/LambdaCapture.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/TypeTraits.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-class CXXConstructorDecl;
-class CXXDestructorDecl;
-class CXXMethodDecl;
-class CXXTemporary;
-class MSPropertyDecl;
-class TemplateArgumentListInfo;
-class UuidAttr;
-
-//===--------------------------------------------------------------------===//
-// C++ Expressions.
-//===--------------------------------------------------------------------===//
-
-/// \brief A call to an overloaded operator written using operator
-/// syntax.
-///
-/// Represents a call to an overloaded operator written using operator
-/// syntax, e.g., "x + y" or "*p". While semantically equivalent to a
-/// normal call, this AST node provides better information about the
-/// syntactic representation of the call.
-///
-/// In a C++ template, this expression node kind will be used whenever
-/// any of the arguments are type-dependent. In this case, the
-/// function itself will be a (possibly empty) set of functions and
-/// function templates that were found by name lookup at template
-/// definition time.
-class CXXOperatorCallExpr : public CallExpr {
- /// \brief The overloaded operator.
- OverloadedOperatorKind Operator;
- SourceRange Range;
-
- // Record the FP_CONTRACT state that applies to this operator call. Only
- // meaningful for floating point types. For other types this value can be
- // set to false.
- unsigned FPContractable : 1;
-
- SourceRange getSourceRangeImpl() const LLVM_READONLY;
-public:
- CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation operatorloc, bool fpContractable)
- : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK,
- operatorloc),
- Operator(Op), FPContractable(fpContractable) {
- Range = getSourceRangeImpl();
- }
- explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
- CallExpr(C, CXXOperatorCallExprClass, Empty) { }
-
-
- /// \brief Returns the kind of overloaded operator that this
- /// expression refers to.
- OverloadedOperatorKind getOperator() const { return Operator; }
-
- /// \brief Returns the location of the operator symbol in the expression.
- ///
- /// When \c getOperator()==OO_Call, this is the location of the right
- /// parentheses; when \c getOperator()==OO_Subscript, this is the location
- /// of the right bracket.
- SourceLocation getOperatorLoc() const { return getRParenLoc(); }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return (Operator < OO_Plus || Operator >= OO_Arrow ||
- Operator == OO_PlusPlus || Operator == OO_MinusMinus)
- ? getLocStart()
- : getOperatorLoc();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const { return Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXOperatorCallExprClass;
- }
-
- // Set the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- void setFPContractable(bool FPC) { FPContractable = FPC; }
-
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
- bool isFPContractable() const { return FPContractable; }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// Represents a call to a member function that
-/// may be written either with member call syntax (e.g., "obj.func()"
-/// or "objptr->func()") or with normal function-call syntax
-/// ("func()") within a member function that ends up calling a member
-/// function. The callee in either case is a MemberExpr that contains
-/// both the object argument and the member function, while the
-/// arguments are the arguments within the parentheses (not including
-/// the object argument).
-class CXXMemberCallExpr : public CallExpr {
-public:
- CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args,
- QualType t, ExprValueKind VK, SourceLocation RP)
- : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {}
-
- CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CXXMemberCallExprClass, Empty) { }
-
- /// \brief Retrieves the implicit object argument for the member call.
- ///
- /// For example, in "x.f(5)", this returns the sub-expression "x".
- Expr *getImplicitObjectArgument() const;
-
- /// \brief Retrieves the declaration of the called method.
- CXXMethodDecl *getMethodDecl() const;
-
- /// \brief Retrieves 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
- /// context of the CXXMethodDecl which this function is calling.
- /// FIXME: Returns 0 for member pointer call exprs.
- CXXRecordDecl *getRecordDecl() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXMemberCallExprClass;
- }
-};
-
-/// \brief Represents a call to a CUDA kernel function.
-class CUDAKernelCallExpr : public CallExpr {
-private:
- enum { CONFIG, END_PREARG };
-
-public:
- CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
- ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
- SourceLocation RP)
- : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) {
- setConfig(Config);
- }
-
- CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty)
- : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { }
-
- const CallExpr *getConfig() const {
- return cast_or_null<CallExpr>(getPreArg(CONFIG));
- }
- CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); }
- void setConfig(CallExpr *E) { setPreArg(CONFIG, E); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CUDAKernelCallExprClass;
- }
-};
-
-/// \brief Abstract class common to all of the C++ "named"/"keyword" casts.
-///
-/// This abstract class is inherited by all of the classes
-/// representing "named" casts: CXXStaticCastExpr for \c static_cast,
-/// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for
-/// reinterpret_cast, and CXXConstCastExpr for \c const_cast.
-class CXXNamedCastExpr : public ExplicitCastExpr {
-private:
- SourceLocation Loc; // the location of the casting op
- SourceLocation RParenLoc; // the location of the right parenthesis
- SourceRange AngleBrackets; // range for '<' '>'
-
-protected:
- CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
- CastKind kind, Expr *op, unsigned PathSize,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
- RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
-
- explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(SC, Shell, PathSize) { }
-
- friend class ASTStmtReader;
-
-public:
- const char *getCastName() const;
-
- /// \brief Retrieve the location of the cast operator keyword, e.g.,
- /// \c static_cast.
- SourceLocation getOperatorLoc() const { return Loc; }
-
- /// \brief Retrieve the location of the closing parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
- SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; }
-
- static bool classof(const Stmt *T) {
- switch (T->getStmtClass()) {
- case CXXStaticCastExprClass:
- case CXXDynamicCastExprClass:
- case CXXReinterpretCastExprClass:
- case CXXConstCastExprClass:
- return true;
- default:
- return false;
- }
- }
-};
-
-/// \brief A C++ \c static_cast expression (C++ [expr.static.cast]).
-///
-/// This expression node represents a C++ static cast, e.g.,
-/// \c static_cast<int>(1.0).
-class CXXStaticCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> {
- CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
- unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
- writtenTy, l, RParenLoc, AngleBrackets) {}
-
- explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
- : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
-
-public:
- static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind K, Expr *Op,
- const CXXCastPath *Path,
- TypeSourceInfo *Written, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXStaticCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]).
-///
-/// This expression node represents a dynamic cast, e.g.,
-/// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time
-/// check to determine how to perform the type conversion.
-class CXXDynamicCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {
- CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
- Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
- writtenTy, l, RParenLoc, AngleBrackets) {}
-
- explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
-
-public:
- static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind Kind, Expr *Op,
- const CXXCastPath *Path,
- TypeSourceInfo *Written, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
-
- static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned pathSize);
-
- bool isAlwaysNull() const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDynamicCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]).
-///
-/// This expression node represents a reinterpret cast, e.g.,
-/// @c reinterpret_cast<int>(VoidPtr).
-///
-/// A reinterpret_cast provides a differently-typed view of a value but
-/// (in Clang, as in most C++ implementations) performs no actual work at
-/// run time.
-class CXXReinterpretCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXReinterpretCastExpr,
- CXXBaseSpecifier *> {
- CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
- Expr *op, unsigned pathSize,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
- pathSize, writtenTy, l, RParenLoc, AngleBrackets) {}
-
- CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
-
-public:
- static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind Kind,
- Expr *Op, const CXXCastPath *Path,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned pathSize);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXReinterpretCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A C++ \c const_cast expression (C++ [expr.const.cast]).
-///
-/// This expression node represents a const cast, e.g.,
-/// \c const_cast<char*>(PtrToConstChar).
-///
-/// A const_cast can remove type qualifiers but does not change the underlying
-/// value.
-class CXXConstCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> {
- CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc, SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
- 0, writtenTy, l, RParenLoc, AngleBrackets) {}
-
- explicit CXXConstCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
-
-public:
- static CXXConstCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, Expr *Op,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXConstCastExpr *CreateEmpty(const ASTContext &Context);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConstCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// \brief A call to a literal operator (C++11 [over.literal])
-/// written as a user-defined literal (C++11 [lit.ext]).
-///
-/// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this
-/// is semantically equivalent to a normal call, this AST node provides better
-/// information about the syntactic representation of the literal.
-///
-/// Since literal operators are never found by ADL and can only be declared at
-/// namespace scope, a user-defined literal is never dependent.
-class UserDefinedLiteral : public CallExpr {
- /// \brief The location of a ud-suffix within the literal.
- SourceLocation UDSuffixLoc;
-
-public:
- UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args,
- QualType T, ExprValueKind VK, SourceLocation LitEndLoc,
- SourceLocation SuffixLoc)
- : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc),
- UDSuffixLoc(SuffixLoc) {}
- explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty)
- : CallExpr(C, UserDefinedLiteralClass, Empty) {}
-
- /// The kind of literal operator which is invoked.
- enum LiteralOperatorKind {
- LOK_Raw, ///< Raw form: operator "" X (const char *)
- LOK_Template, ///< Raw form: operator "" X<cs...> ()
- LOK_Integer, ///< operator "" X (unsigned long long)
- LOK_Floating, ///< operator "" X (long double)
- LOK_String, ///< operator "" X (const CharT *, size_t)
- LOK_Character ///< operator "" X (CharT)
- };
-
- /// \brief Returns the kind of literal operator invocation
- /// which this expression represents.
- LiteralOperatorKind getLiteralOperatorKind() const;
-
- /// \brief If this is not a raw user-defined literal, get the
- /// underlying cooked literal (representing the literal with the suffix
- /// removed).
- Expr *getCookedLiteral();
- const Expr *getCookedLiteral() const {
- return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral();
- }
-
- SourceLocation getLocStart() const {
- if (getLiteralOperatorKind() == LOK_Template)
- return getRParenLoc();
- return getArg(0)->getLocStart();
- }
- SourceLocation getLocEnd() const { return getRParenLoc(); }
-
-
- /// \brief Returns the location of a ud-suffix in the expression.
- ///
- /// For a string literal, there may be multiple identical suffixes. This
- /// returns the first.
- SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; }
-
- /// \brief Returns the ud-suffix specified for this literal.
- const IdentifierInfo *getUDSuffix() const;
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == UserDefinedLiteralClass;
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief A boolean literal, per ([C++ lex.bool] Boolean literals).
-///
-class CXXBoolLiteralExpr : public Expr {
- bool Value;
- SourceLocation Loc;
-public:
- CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
- Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Value(val), Loc(l) {}
-
- explicit CXXBoolLiteralExpr(EmptyShell Empty)
- : Expr(CXXBoolLiteralExprClass, Empty) { }
-
- bool getValue() const { return Value; }
- void setValue(bool V) { Value = V; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBoolLiteralExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief The null pointer literal (C++11 [lex.nullptr])
-///
-/// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr.
-class CXXNullPtrLiteralExpr : public Expr {
- SourceLocation Loc;
-public:
- CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
- Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false),
- Loc(l) {}
-
- explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
- : Expr(CXXNullPtrLiteralExprClass, Empty) { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNullPtrLiteralExprClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Implicit construction of a std::initializer_list<T> object from an
-/// array temporary within list-initialization (C++11 [dcl.init.list]p5).
-class CXXStdInitializerListExpr : public Expr {
- Stmt *SubExpr;
-
- CXXStdInitializerListExpr(EmptyShell Empty)
- : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {}
-
-public:
- CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
- : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,
- Ty->isDependentType(), SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- SubExpr(SubExpr) {}
-
- Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
- const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExpr->getLocEnd();
- }
- SourceRange getSourceRange() const LLVM_READONLY {
- return SubExpr->getSourceRange();
- }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == CXXStdInitializerListExprClass;
- }
-
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-
- friend class ASTReader;
- friend class ASTStmtReader;
-};
-
-/// A C++ \c typeid expression (C++ [expr.typeid]), which gets
-/// the \c type_info that corresponds to the supplied type, or the (possibly
-/// dynamic) type of the supplied expression.
-///
-/// This represents code like \c typeid(int) or \c typeid(*objPtr)
-class CXXTypeidExpr : public Expr {
-private:
- llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- SourceRange Range;
-
-public:
- CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are dependent
- Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
- // typeid is never type-dependent (C++ [temp.dep.expr]p4)
- false,
- // typeid is value-dependent if the type or expression are dependent
- Operand->isTypeDependent() || Operand->isValueDependent(),
- Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXTypeidExpr(EmptyShell Empty, bool isExpr)
- : Expr(CXXTypeidExprClass, Empty) {
- if (isExpr)
- Operand = (Expr*)nullptr;
- else
- Operand = (TypeSourceInfo*)nullptr;
- }
-
- /// Determine whether this typeid has a type operand which is potentially
- /// evaluated, per C++11 [expr.typeid]p3.
- bool isPotentiallyEvaluated() const;
-
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
-
- /// \brief Retrieves the type operand of this typeid() expression after
- /// various required adjustments (removing reference types, cv-qualifiers).
- QualType getTypeOperand(ASTContext &Context) const;
-
- /// \brief Retrieve source information for the type operand.
- TypeSourceInfo *getTypeOperandSourceInfo() const {
- assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- return Operand.get<TypeSourceInfo *>();
- }
-
- void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
- assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- Operand = TSI;
- }
-
- Expr *getExprOperand() const {
- assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
- }
-
- void setExprOperand(Expr *E) {
- assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- Operand = E;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- void setSourceRange(SourceRange R) { Range = R; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTypeidExprClass;
- }
-
- // Iterators
- child_range children() {
- if (isTypeOperand())
- return child_range(child_iterator(), child_iterator());
- Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
- return child_range(begin, begin + 1);
- }
-};
-
-/// \brief A member reference to an MSPropertyDecl.
-///
-/// This expression always has pseudo-object type, and therefore it is
-/// typically not encountered in a fully-typechecked expression except
-/// within the syntactic form of a PseudoObjectExpr.
-class MSPropertyRefExpr : public Expr {
- Expr *BaseExpr;
- MSPropertyDecl *TheDecl;
- SourceLocation MemberLoc;
- bool IsArrow;
- NestedNameSpecifierLoc QualifierLoc;
-
-public:
- MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
- QualType ty, ExprValueKind VK,
- NestedNameSpecifierLoc qualifierLoc,
- SourceLocation nameLoc)
- : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
- /*type-dependent*/ false, baseExpr->isValueDependent(),
- baseExpr->isInstantiationDependent(),
- baseExpr->containsUnexpandedParameterPack()),
- BaseExpr(baseExpr), TheDecl(decl),
- MemberLoc(nameLoc), IsArrow(isArrow),
- QualifierLoc(qualifierLoc) {}
-
- MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getLocStart(), getLocEnd());
- }
- bool isImplicitAccess() const {
- return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
- }
- SourceLocation getLocStart() const {
- if (!isImplicitAccess())
- return BaseExpr->getLocStart();
- else if (QualifierLoc)
- return QualifierLoc.getBeginLoc();
- else
- return MemberLoc;
- }
- SourceLocation getLocEnd() const { return getMemberLoc(); }
-
- child_range children() {
- return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSPropertyRefExprClass;
- }
-
- Expr *getBaseExpr() const { return BaseExpr; }
- MSPropertyDecl *getPropertyDecl() const { return TheDecl; }
- bool isArrow() const { return IsArrow; }
- SourceLocation getMemberLoc() const { return MemberLoc; }
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- friend class ASTStmtReader;
-};
-
-/// MS property subscript expression.
-/// MSVC supports 'property' attribute and allows to apply it to the
-/// declaration of an empty array in a class or structure definition.
-/// For example:
-/// \code
-/// __declspec(property(get=GetX, put=PutX)) int x[];
-/// \endcode
-/// The above statement indicates that x[] can be used with one or more array
-/// indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and
-/// p->x[a][b] = i will be turned into p->PutX(a, b, i).
-/// This is a syntactic pseudo-object expression.
-class MSPropertySubscriptExpr : public Expr {
- friend class ASTStmtReader;
- enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 };
- Stmt *SubExprs[NUM_SUBEXPRS];
- SourceLocation RBracketLoc;
-
- void setBase(Expr *Base) { SubExprs[BASE_EXPR] = Base; }
- void setIdx(Expr *Idx) { SubExprs[IDX_EXPR] = Idx; }
-
-public:
- MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK,
- ExprObjectKind OK, SourceLocation RBracketLoc)
- : Expr(MSPropertySubscriptExprClass, Ty, VK, OK, Idx->isTypeDependent(),
- Idx->isValueDependent(), Idx->isInstantiationDependent(),
- Idx->containsUnexpandedParameterPack()),
- RBracketLoc(RBracketLoc) {
- SubExprs[BASE_EXPR] = Base;
- SubExprs[IDX_EXPR] = Idx;
- }
-
- /// \brief Create an empty array subscript expression.
- explicit MSPropertySubscriptExpr(EmptyShell Shell)
- : Expr(MSPropertySubscriptExprClass, Shell) {}
-
- Expr *getBase() { return cast<Expr>(SubExprs[BASE_EXPR]); }
- const Expr *getBase() const { return cast<Expr>(SubExprs[BASE_EXPR]); }
-
- Expr *getIdx() { return cast<Expr>(SubExprs[IDX_EXPR]); }
- const Expr *getIdx() const { return cast<Expr>(SubExprs[IDX_EXPR]); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
-
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getBase()->getExprLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSPropertySubscriptExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS);
- }
-};
-
-/// A Microsoft C++ @c __uuidof expression, which gets
-/// the _GUID that corresponds to the supplied type or expression.
-///
-/// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
-class CXXUuidofExpr : public Expr {
-private:
- llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- SourceRange Range;
-
-public:
- CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
- false, Operand->getType()->isDependentType(),
- Operand->getType()->isInstantiationDependentType(),
- Operand->getType()->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
- false, Operand->isTypeDependent(),
- Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Operand(Operand), Range(R) { }
-
- CXXUuidofExpr(EmptyShell Empty, bool isExpr)
- : Expr(CXXUuidofExprClass, Empty) {
- if (isExpr)
- Operand = (Expr*)nullptr;
- else
- Operand = (TypeSourceInfo*)nullptr;
- }
-
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
-
- /// \brief Retrieves the type operand of this __uuidof() expression after
- /// various required adjustments (removing reference types, cv-qualifiers).
- QualType getTypeOperand(ASTContext &Context) const;
-
- /// \brief Retrieve source information for the type operand.
- TypeSourceInfo *getTypeOperandSourceInfo() const {
- assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
- return Operand.get<TypeSourceInfo *>();
- }
-
- void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
- assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
- Operand = TSI;
- }
-
- Expr *getExprOperand() const {
- assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
- }
-
- void setExprOperand(Expr *E) {
- assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
- Operand = E;
- }
-
- StringRef getUuidAsStringRef(ASTContext &Context) const;
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- void setSourceRange(SourceRange R) { Range = R; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUuidofExprClass;
- }
-
- /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
- /// a single GUID.
- static const UuidAttr *GetUuidAttrOfType(QualType QT,
- bool *HasMultipleGUIDsPtr = nullptr);
-
- // Iterators
- child_range children() {
- if (isTypeOperand())
- return child_range(child_iterator(), child_iterator());
- Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
- return child_range(begin, begin + 1);
- }
-};
-
-/// \brief Represents the \c this expression in C++.
-///
-/// This is a pointer to the object on which the current member function is
-/// executing (C++ [expr.prim]p3). Example:
-///
-/// \code
-/// class Foo {
-/// public:
-/// void bar();
-/// void test() { this->bar(); }
-/// };
-/// \endcode
-class CXXThisExpr : public Expr {
- SourceLocation Loc;
- bool Implicit : 1;
-
-public:
- CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit)
- : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary,
- // 'this' is type-dependent if the class type of the enclosing
- // member function is dependent (C++ [temp.dep.expr]p2)
- Type->isDependentType(), Type->isDependentType(),
- Type->isInstantiationDependentType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Loc(L), Implicit(isImplicit) { }
-
- CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- bool isImplicit() const { return Implicit; }
- void setImplicit(bool I) { Implicit = I; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXThisExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief A C++ throw-expression (C++ [except.throw]).
-///
-/// This handles 'throw' (for re-throwing the current exception) and
-/// 'throw' assignment-expression. When assignment-expression isn't
-/// present, Op will be null.
-class CXXThrowExpr : public Expr {
- Stmt *Op;
- SourceLocation ThrowLoc;
- /// \brief Whether the thrown variable (if any) is in scope.
- unsigned IsThrownVariableInScope : 1;
-
- friend class ASTStmtReader;
-
-public:
- // \p Ty is the void type which is used as the result type of the
- // expression. The \p l is the location of the throw keyword. \p expr
- // can by null, if the optional expression to throw isn't present.
- CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l,
- bool IsThrownVariableInScope) :
- Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- expr && expr->isInstantiationDependent(),
- expr && expr->containsUnexpandedParameterPack()),
- Op(expr), ThrowLoc(l), IsThrownVariableInScope(IsThrownVariableInScope) {}
- CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
-
- const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
- Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
-
- SourceLocation getThrowLoc() const { return ThrowLoc; }
-
- /// \brief Determines whether the variable thrown by this expression (if any!)
- /// is within the innermost try block.
- ///
- /// This information is required to determine whether the NRVO can apply to
- /// this variable.
- bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (!getSubExpr())
- return ThrowLoc;
- return getSubExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXThrowExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Op, Op ? &Op+1 : &Op);
- }
-};
-
-/// \brief A default argument (C++ [dcl.fct.default]).
-///
-/// This wraps up a function call argument that was created from the
-/// corresponding parameter's default argument, when the call did not
-/// explicitly supply arguments for all of the parameters.
-class CXXDefaultArgExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
- /// \brief The parameter whose default is being used.
- ///
- /// When the bit is set, the subexpression is stored after the
- /// CXXDefaultArgExpr itself. When the bit is clear, the parameter's
- /// actual default expression is the subexpression.
- llvm::PointerIntPair<ParmVarDecl *, 1, bool> Param;
-
- /// \brief The location where the default argument expression was used.
- SourceLocation Loc;
-
- CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
- : Expr(SC,
- param->hasUnparsedDefaultArg()
- ? param->getType().getNonReferenceType()
- : param->getDefaultArg()->getType(),
- param->getDefaultArg()->getValueKind(),
- param->getDefaultArg()->getObjectKind(), false, false, false, false),
- Param(param, false), Loc(Loc) { }
-
- CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
- Expr *SubExpr)
- : Expr(SC, SubExpr->getType(),
- SubExpr->getValueKind(), SubExpr->getObjectKind(),
- false, false, false, false),
- Param(param, true), Loc(Loc) {
- *getTrailingObjects<Expr *>() = SubExpr;
- }
-
-public:
- CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
-
- // \p Param is the parameter whose default argument is used by this
- // expression.
- static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
- ParmVarDecl *Param) {
- return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param);
- }
-
- // \p Param is the parameter whose default argument is used by this
- // expression, and \p SubExpr is the expression that will actually be used.
- static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
- ParmVarDecl *Param, Expr *SubExpr);
-
- // Retrieve the parameter that the argument was created from.
- const ParmVarDecl *getParam() const { return Param.getPointer(); }
- ParmVarDecl *getParam() { return Param.getPointer(); }
-
- // Retrieve the actual argument to the function call.
- const Expr *getExpr() const {
- if (Param.getInt())
- return *getTrailingObjects<Expr *>();
- return getParam()->getDefaultArg();
- }
- Expr *getExpr() {
- if (Param.getInt())
- return *getTrailingObjects<Expr *>();
- return getParam()->getDefaultArg();
- }
-
- /// \brief Retrieve the location where this default argument was actually
- /// used.
- SourceLocation getUsedLocation() const { return Loc; }
-
- /// Default argument expressions have no representation in the
- /// source, so they have an empty source range.
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDefaultArgExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief A use of a default initializer in a constructor or in aggregate
-/// initialization.
-///
-/// This wraps a use of a C++ default initializer (technically,
-/// a brace-or-equal-initializer for a non-static data member) when it
-/// is implicitly used in a mem-initializer-list in a constructor
-/// (C++11 [class.base.init]p8) or in aggregate initialization
-/// (C++1y [dcl.init.aggr]p7).
-class CXXDefaultInitExpr : public Expr {
- /// \brief The field whose default is being used.
- FieldDecl *Field;
-
- /// \brief The location where the default initializer expression was used.
- SourceLocation Loc;
-
- CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field,
- QualType T);
-
- CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
-
-public:
- /// \p Field is the non-static data member whose default initializer is used
- /// by this expression.
- static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc,
- FieldDecl *Field) {
- return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType());
- }
-
- /// \brief Get the field whose initializer will be used.
- FieldDecl *getField() { return Field; }
- const FieldDecl *getField() const { return Field; }
-
- /// \brief Get the initialization expression that will be used.
- const Expr *getExpr() const {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
- }
- Expr *getExpr() {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDefaultInitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTReader;
- friend class ASTStmtReader;
-};
-
-/// \brief Represents a C++ temporary.
-class CXXTemporary {
- /// \brief The destructor that needs to be called.
- const CXXDestructorDecl *Destructor;
-
- explicit CXXTemporary(const CXXDestructorDecl *destructor)
- : Destructor(destructor) { }
-
-public:
- static CXXTemporary *Create(const ASTContext &C,
- const CXXDestructorDecl *Destructor);
-
- const CXXDestructorDecl *getDestructor() const { return Destructor; }
- void setDestructor(const CXXDestructorDecl *Dtor) {
- Destructor = Dtor;
- }
-};
-
-/// \brief Represents binding an expression to a temporary.
-///
-/// This ensures the destructor is called for the temporary. It should only be
-/// needed for non-POD, non-trivially destructable class types. For example:
-///
-/// \code
-/// struct S {
-/// S() { } // User defined constructor makes S non-POD.
-/// ~S() { } // User defined destructor makes it non-trivial.
-/// };
-/// void test() {
-/// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
-/// }
-/// \endcode
-class CXXBindTemporaryExpr : public Expr {
- CXXTemporary *Temp;
-
- Stmt *SubExpr;
-
- CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr)
- : Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
- VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
- SubExpr->isValueDependent(),
- SubExpr->isInstantiationDependent(),
- SubExpr->containsUnexpandedParameterPack()),
- Temp(temp), SubExpr(SubExpr) { }
-
-public:
- CXXBindTemporaryExpr(EmptyShell Empty)
- : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {}
-
- static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
- Expr* SubExpr);
-
- CXXTemporary *getTemporary() { return Temp; }
- const CXXTemporary *getTemporary() const { return Temp; }
- void setTemporary(CXXTemporary *T) { Temp = T; }
-
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- void setSubExpr(Expr *E) { SubExpr = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBindTemporaryExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-};
-
-/// \brief Represents a call to a C++ constructor.
-class CXXConstructExpr : public Expr {
-public:
- enum ConstructionKind {
- CK_Complete,
- CK_NonVirtualBase,
- CK_VirtualBase,
- CK_Delegating
- };
-
-private:
- CXXConstructorDecl *Constructor;
-
- SourceLocation Loc;
- SourceRange ParenOrBraceRange;
- unsigned NumArgs : 16;
- bool Elidable : 1;
- bool HadMultipleCandidates : 1;
- bool ListInitialization : 1;
- bool StdInitListInitialization : 1;
- bool ZeroInitialization : 1;
- unsigned ConstructKind : 2;
- Stmt **Args;
-
-protected:
- CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *d, bool elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
- SourceRange ParenOrBraceRange);
-
- /// \brief Construct an empty C++ construction expression.
- CXXConstructExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false),
- HadMultipleCandidates(false), ListInitialization(false),
- ZeroInitialization(false), ConstructKind(0), Args(nullptr)
- { }
-
-public:
- /// \brief Construct an empty C++ construction expression.
- explicit CXXConstructExpr(EmptyShell Empty)
- : Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
- NumArgs(0), Elidable(false), HadMultipleCandidates(false),
- ListInitialization(false), ZeroInitialization(false),
- ConstructKind(0), Args(nullptr)
- { }
-
- static CXXConstructExpr *Create(const ASTContext &C, QualType T,
- SourceLocation Loc,
- CXXConstructorDecl *D, bool Elidable,
- ArrayRef<Expr *> Args,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization,
- ConstructionKind ConstructKind,
- SourceRange ParenOrBraceRange);
-
- CXXConstructorDecl *getConstructor() const { return Constructor; }
- void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation Loc) { this->Loc = Loc; }
-
- /// \brief Whether this construction is elidable.
- bool isElidable() const { return Elidable; }
- void setElidable(bool E) { Elidable = E; }
-
- /// \brief Whether the referred constructor was resolved from
- /// an overloaded set having size greater than 1.
- bool hadMultipleCandidates() const { return HadMultipleCandidates; }
- void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
-
- /// \brief Whether this constructor call was written as list-initialization.
- bool isListInitialization() const { return ListInitialization; }
- void setListInitialization(bool V) { ListInitialization = V; }
-
- /// \brief Whether this constructor call was written as list-initialization,
- /// but was interpreted as forming a std::initializer_list<T> from the list
- /// and passing that as a single constructor argument.
- /// See C++11 [over.match.list]p1 bullet 1.
- bool isStdInitListInitialization() const { return StdInitListInitialization; }
- void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
-
- /// \brief Whether this construction first requires
- /// zero-initialization before the initializer is called.
- bool requiresZeroInitialization() const { return ZeroInitialization; }
- void setRequiresZeroInitialization(bool ZeroInit) {
- ZeroInitialization = ZeroInit;
- }
-
- /// \brief Determine whether this constructor is actually constructing
- /// a base class (rather than a complete object).
- ConstructionKind getConstructionKind() const {
- return (ConstructionKind)ConstructKind;
- }
- void setConstructionKind(ConstructionKind CK) {
- ConstructKind = CK;
- }
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
- typedef llvm::iterator_range<arg_iterator> arg_range;
- typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
-
- arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- arg_const_range arguments() const {
- return arg_const_range(arg_begin(), arg_end());
- }
-
- arg_iterator arg_begin() { return Args; }
- arg_iterator arg_end() { return Args + NumArgs; }
- const_arg_iterator arg_begin() const { return Args; }
- const_arg_iterator arg_end() const { return Args + NumArgs; }
-
- Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
- const Expr *const *getArgs() const {
- return const_cast<CXXConstructExpr *>(this)->getArgs();
- }
- unsigned getNumArgs() const { return NumArgs; }
-
- /// \brief Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(Args[Arg]);
- }
-
- /// \brief Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- Args[Arg] = ArgExpr;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
- SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; }
- void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConstructExprClass ||
- T->getStmtClass() == CXXTemporaryObjectExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Args[0], &Args[0]+NumArgs);
- }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Represents an explicit C++ type conversion that uses "functional"
-/// notation (C++ [expr.type.conv]).
-///
-/// Example:
-/// \code
-/// x = int(0.5);
-/// \endcode
-class CXXFunctionalCastExpr final
- : public ExplicitCastExpr,
- private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> {
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
-
- CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
- TypeSourceInfo *writtenTy,
- CastKind kind, Expr *castExpr, unsigned pathSize,
- SourceLocation lParenLoc, SourceLocation rParenLoc)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
- castExpr, pathSize, writtenTy),
- LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
-
- explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
-
-public:
- static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- TypeSourceInfo *Written,
- CastKind Kind, Expr *Op,
- const CXXCastPath *Path,
- SourceLocation LPLoc,
- SourceLocation RPLoc);
- static CXXFunctionalCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize);
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXFunctionalCastExprClass;
- }
-
- friend TrailingObjects;
- friend class CastExpr;
-};
-
-/// @brief Represents a C++ functional cast expression that builds a
-/// temporary object.
-///
-/// This expression type represents a C++ "functional" cast
-/// (C++[expr.type.conv]) with N != 1 arguments that invokes a
-/// constructor to build a temporary object. With N == 1 arguments the
-/// functional cast expression will be represented by CXXFunctionalCastExpr.
-/// Example:
-/// \code
-/// struct X { X(int, float); }
-///
-/// X create_X() {
-/// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
-/// };
-/// \endcode
-class CXXTemporaryObjectExpr : public CXXConstructExpr {
- TypeSourceInfo *Type;
-
-public:
- CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons,
- TypeSourceInfo *Type,
- ArrayRef<Expr *> Args,
- SourceRange ParenOrBraceRange,
- bool HadMultipleCandidates,
- bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization);
- explicit CXXTemporaryObjectExpr(EmptyShell Empty)
- : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
-
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTemporaryObjectExprClass;
- }
-
- friend class ASTStmtReader;
-};
-
-/// \brief A C++ lambda expression, which produces a function object
-/// (of unspecified type) that can be invoked later.
-///
-/// Example:
-/// \code
-/// void low_pass_filter(std::vector<double> &values, double cutoff) {
-/// values.erase(std::remove_if(values.begin(), values.end(),
-/// [=](double value) { return value > cutoff; });
-/// }
-/// \endcode
-///
-/// C++11 lambda expressions can capture local variables, either by copying
-/// the values of those local variables at the time the function
-/// object is constructed (not when it is called!) or by holding a
-/// reference to the local variable. These captures can occur either
-/// implicitly or can be written explicitly between the square
-/// brackets ([...]) that start the lambda expression.
-///
-/// C++1y introduces a new form of "capture" called an init-capture that
-/// includes an initializing expression (rather than capturing a variable),
-/// and which can never occur implicitly.
-class LambdaExpr final
- : public Expr,
- private llvm::TrailingObjects<LambdaExpr, Stmt *, unsigned, VarDecl *> {
- /// \brief The source range that covers the lambda introducer ([...]).
- SourceRange IntroducerRange;
-
- /// \brief The source location of this lambda's capture-default ('=' or '&').
- SourceLocation CaptureDefaultLoc;
-
- /// \brief The number of captures.
- unsigned NumCaptures : 16;
-
- /// \brief The default capture kind, which is a value of type
- /// LambdaCaptureDefault.
- unsigned CaptureDefault : 2;
-
- /// \brief Whether this lambda had an explicit parameter list vs. an
- /// implicit (and empty) parameter list.
- unsigned ExplicitParams : 1;
-
- /// \brief Whether this lambda had the result type explicitly specified.
- unsigned ExplicitResultType : 1;
-
- /// \brief Whether there are any array index variables stored at the end of
- /// this lambda expression.
- unsigned HasArrayIndexVars : 1;
-
- /// \brief The location of the closing brace ('}') that completes
- /// the lambda.
- ///
- /// The location of the brace is also available by looking up the
- /// function call operator in the lambda class. However, it is
- /// stored here to improve the performance of getSourceRange(), and
- /// to avoid having to deserialize the function call operator from a
- /// module file just to determine the source range.
- SourceLocation ClosingBrace;
-
- size_t numTrailingObjects(OverloadToken<Stmt *>) const {
- return NumCaptures + 1;
- }
-
- size_t numTrailingObjects(OverloadToken<unsigned>) const {
- return HasArrayIndexVars ? NumCaptures + 1 : 0;
- }
-
- /// \brief Construct a lambda expression.
- LambdaExpr(QualType T, SourceRange IntroducerRange,
- LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures,
- bool ExplicitParams, bool ExplicitResultType,
- ArrayRef<Expr *> CaptureInits, ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
-
- /// \brief Construct an empty lambda expression.
- LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool HasArrayIndexVars)
- : Expr(LambdaExprClass, Empty),
- NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
- ExplicitResultType(false), HasArrayIndexVars(true) {
- getStoredStmts()[NumCaptures] = nullptr;
- }
-
- Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
-
- Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
-
- /// \brief Retrieve the mapping from captures to the first array index
- /// variable.
- unsigned *getArrayIndexStarts() { return getTrailingObjects<unsigned>(); }
-
- const unsigned *getArrayIndexStarts() const {
- return getTrailingObjects<unsigned>();
- }
-
- /// \brief Retrieve the complete set of array-index variables.
- VarDecl **getArrayIndexVars() { return getTrailingObjects<VarDecl *>(); }
-
- VarDecl *const *getArrayIndexVars() const {
- return getTrailingObjects<VarDecl *>();
- }
-
-public:
- /// \brief Construct a new lambda expression.
- static LambdaExpr *
- Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
- LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
- ArrayRef<LambdaCapture> Captures, bool ExplicitParams,
- bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
- ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
-
- /// \brief Construct a new lambda expression that will be deserialized from
- /// an external source.
- static LambdaExpr *CreateDeserialized(const ASTContext &C,
- unsigned NumCaptures,
- unsigned NumArrayIndexVars);
-
- /// \brief Determine the default capture kind for this lambda.
- LambdaCaptureDefault getCaptureDefault() const {
- return static_cast<LambdaCaptureDefault>(CaptureDefault);
- }
-
- /// \brief Retrieve the location of this lambda's capture-default, if any.
- SourceLocation getCaptureDefaultLoc() const {
- return CaptureDefaultLoc;
- }
-
- /// \brief Determine whether one of this lambda's captures is an init-capture.
- bool isInitCapture(const LambdaCapture *Capture) const;
-
- /// \brief An iterator that walks over the captures of the lambda,
- /// both implicit and explicit.
- typedef const LambdaCapture *capture_iterator;
-
- /// \brief An iterator over a range of lambda captures.
- typedef llvm::iterator_range<capture_iterator> capture_range;
-
- /// \brief Retrieve this lambda's captures.
- capture_range captures() const;
-
- /// \brief Retrieve an iterator pointing to the first lambda capture.
- capture_iterator capture_begin() const;
-
- /// \brief Retrieve an iterator pointing past the end of the
- /// sequence of lambda captures.
- capture_iterator capture_end() const;
-
- /// \brief Determine the number of captures in this lambda.
- unsigned capture_size() const { return NumCaptures; }
-
- /// \brief Retrieve this lambda's explicit captures.
- capture_range explicit_captures() const;
-
- /// \brief Retrieve an iterator pointing to the first explicit
- /// lambda capture.
- capture_iterator explicit_capture_begin() const;
-
- /// \brief Retrieve an iterator pointing past the end of the sequence of
- /// explicit lambda captures.
- capture_iterator explicit_capture_end() const;
-
- /// \brief Retrieve this lambda's implicit captures.
- capture_range implicit_captures() const;
-
- /// \brief Retrieve an iterator pointing to the first implicit
- /// lambda capture.
- capture_iterator implicit_capture_begin() const;
-
- /// \brief Retrieve an iterator pointing past the end of the sequence of
- /// implicit lambda captures.
- capture_iterator implicit_capture_end() const;
-
- /// \brief Iterator that walks over the capture initialization
- /// arguments.
- typedef Expr **capture_init_iterator;
-
- /// \brief Const iterator that walks over the capture initialization
- /// arguments.
- typedef Expr *const *const_capture_init_iterator;
-
- /// \brief Retrieve the initialization expressions for this lambda's captures.
- llvm::iterator_range<capture_init_iterator> capture_inits() {
- return llvm::make_range(capture_init_begin(), capture_init_end());
- }
-
- /// \brief Retrieve the initialization expressions for this lambda's captures.
- llvm::iterator_range<const_capture_init_iterator> capture_inits() const {
- return llvm::make_range(capture_init_begin(), capture_init_end());
- }
-
- /// \brief Retrieve the first initialization argument for this
- /// lambda expression (which initializes the first capture field).
- capture_init_iterator capture_init_begin() {
- return reinterpret_cast<Expr **>(getStoredStmts());
- }
-
- /// \brief Retrieve the first initialization argument for this
- /// lambda expression (which initializes the first capture field).
- const_capture_init_iterator capture_init_begin() const {
- return reinterpret_cast<Expr *const *>(getStoredStmts());
- }
-
- /// \brief Retrieve the iterator pointing one past the last
- /// initialization argument for this lambda expression.
- capture_init_iterator capture_init_end() {
- return capture_init_begin() + NumCaptures;
- }
-
- /// \brief Retrieve the iterator pointing one past the last
- /// initialization argument for this lambda expression.
- const_capture_init_iterator capture_init_end() const {
- return capture_init_begin() + NumCaptures;
- }
-
- /// \brief Retrieve the set of index variables used in the capture
- /// initializer of an array captured by copy.
- ///
- /// \param Iter The iterator that points at the capture initializer for
- /// which we are extracting the corresponding index variables.
- ArrayRef<VarDecl *>
- getCaptureInitIndexVars(const_capture_init_iterator Iter) const;
-
- /// \brief Retrieve the source range covering the lambda introducer,
- /// which contains the explicit capture list surrounded by square
- /// brackets ([...]).
- SourceRange getIntroducerRange() const { return IntroducerRange; }
-
- /// \brief Retrieve the class that corresponds to the lambda.
- ///
- /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the
- /// captures in its fields and provides the various operations permitted
- /// on a lambda (copying, calling).
- CXXRecordDecl *getLambdaClass() const;
-
- /// \brief Retrieve the function call operator associated with this
- /// lambda expression.
- CXXMethodDecl *getCallOperator() const;
-
- /// \brief If this is a generic lambda expression, retrieve the template
- /// parameter list associated with it, or else return null.
- TemplateParameterList *getTemplateParameterList() const;
-
- /// \brief Whether this is a generic lambda.
- bool isGenericLambda() const { return getTemplateParameterList(); }
-
- /// \brief Retrieve the body of the lambda.
- CompoundStmt *getBody() const;
-
- /// \brief Determine whether the lambda is mutable, meaning that any
- /// captures values can be modified.
- bool isMutable() const;
-
- /// \brief Determine whether this lambda has an explicit parameter
- /// list vs. an implicit (empty) parameter list.
- bool hasExplicitParameters() const { return ExplicitParams; }
-
- /// \brief Whether this lambda had its result type explicitly specified.
- bool hasExplicitResultType() const { return ExplicitResultType; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == LambdaExprClass;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return IntroducerRange.getBegin();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; }
-
- child_range children() {
- // Includes initialization exprs plus body stmt
- return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// An expression "T()" which creates a value-initialized rvalue of type
-/// T, which is a non-class type. See (C++98 [5.2.3p2]).
-class CXXScalarValueInitExpr : public Expr {
- SourceLocation RParenLoc;
- TypeSourceInfo *TypeInfo;
-
- friend class ASTStmtReader;
-
-public:
- /// \brief Create an explicitly-written scalar-value initialization
- /// expression.
- CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
- SourceLocation rParenLoc)
- : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
- false, false, Type->isInstantiationDependentType(),
- Type->containsUnexpandedParameterPack()),
- RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
-
- explicit CXXScalarValueInitExpr(EmptyShell Shell)
- : Expr(CXXScalarValueInitExprClass, Shell) { }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return TypeInfo;
- }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXScalarValueInitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a new-expression for memory allocation and constructor
-/// calls, e.g: "new CXXNewExpr(foo)".
-class CXXNewExpr : public Expr {
- /// Contains an optional array size expression, an optional initialization
- /// expression, and any number of optional placement arguments, in that order.
- Stmt **SubExprs;
- /// \brief Points to the allocation function used.
- FunctionDecl *OperatorNew;
- /// \brief Points to the deallocation function used in case of error. May be
- /// null.
- FunctionDecl *OperatorDelete;
-
- /// \brief The allocated type-source information, as written in the source.
- TypeSourceInfo *AllocatedTypeInfo;
-
- /// \brief If the allocated type was expressed as a parenthesized type-id,
- /// the source range covering the parenthesized type-id.
- SourceRange TypeIdParens;
-
- /// \brief Range of the entire new expression.
- SourceRange Range;
-
- /// \brief Source-range of a paren-delimited initializer.
- SourceRange DirectInitRange;
-
- /// Was the usage ::new, i.e. is the global new to be used?
- bool GlobalNew : 1;
- /// Do we allocate an array? If so, the first SubExpr is the size expression.
- bool Array : 1;
- /// If this is an array allocation, does the usual deallocation
- /// function for the allocated type want to know the allocated size?
- bool UsualArrayDeleteWantsSize : 1;
- /// The number of placement new arguments.
- unsigned NumPlacementArgs : 13;
- /// What kind of initializer do we have? Could be none, parens, or braces.
- /// In storage, we distinguish between "none, and no initializer expr", and
- /// "none, but an implicit initializer expr".
- unsigned StoredInitializationStyle : 2;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-public:
- enum InitializationStyle {
- NoInit, ///< New-expression has no initializer as written.
- CallInit, ///< New-expression has a C++98 paren-delimited initializer.
- ListInit ///< New-expression has a C++11 list-initializer.
- };
-
- CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
- FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
- ArrayRef<Expr*> placementArgs,
- SourceRange typeIdParens, Expr *arraySize,
- InitializationStyle initializationStyle, Expr *initializer,
- QualType ty, TypeSourceInfo *AllocatedTypeInfo,
- SourceRange Range, SourceRange directInitRange);
- explicit CXXNewExpr(EmptyShell Shell)
- : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { }
-
- void AllocateArgsArray(const ASTContext &C, bool isArray,
- unsigned numPlaceArgs, bool hasInitializer);
-
- QualType getAllocatedType() const {
- assert(getType()->isPointerType());
- return getType()->getAs<PointerType>()->getPointeeType();
- }
-
- TypeSourceInfo *getAllocatedTypeSourceInfo() const {
- return AllocatedTypeInfo;
- }
-
- /// \brief True if the allocation result needs to be null-checked.
- ///
- /// C++11 [expr.new]p13:
- /// If the allocation function returns null, initialization shall
- /// not be done, the deallocation function shall not be called,
- /// and the value of the new-expression shall be null.
- ///
- /// C++ DR1748:
- /// If the allocation function is a reserved placement allocation
- /// function that returns null, the behavior is undefined.
- ///
- /// An allocation function is not allowed to return null unless it
- /// has a non-throwing exception-specification. The '03 rule is
- /// identical except that the definition of a non-throwing
- /// exception specification is just "is it throw()?".
- bool shouldNullCheckAllocation(const ASTContext &Ctx) const;
-
- FunctionDecl *getOperatorNew() const { return OperatorNew; }
- void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
- FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
- void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
-
- bool isArray() const { return Array; }
- Expr *getArraySize() {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
- }
- const Expr *getArraySize() const {
- return Array ? cast<Expr>(SubExprs[0]) : nullptr;
- }
-
- unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
- Expr **getPlacementArgs() {
- return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
- }
-
- Expr *getPlacementArg(unsigned i) {
- assert(i < NumPlacementArgs && "Index out of range");
- return getPlacementArgs()[i];
- }
- const Expr *getPlacementArg(unsigned i) const {
- assert(i < NumPlacementArgs && "Index out of range");
- return const_cast<CXXNewExpr*>(this)->getPlacementArg(i);
- }
-
- bool isParenTypeId() const { return TypeIdParens.isValid(); }
- SourceRange getTypeIdParens() const { return TypeIdParens; }
-
- bool isGlobalNew() const { return GlobalNew; }
-
- /// \brief Whether this new-expression has any initializer at all.
- bool hasInitializer() const { return StoredInitializationStyle > 0; }
-
- /// \brief The kind of initializer this new-expression has.
- InitializationStyle getInitializationStyle() const {
- if (StoredInitializationStyle == 0)
- return NoInit;
- return static_cast<InitializationStyle>(StoredInitializationStyle-1);
- }
-
- /// \brief The initializer of this new-expression.
- Expr *getInitializer() {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
- }
- const Expr *getInitializer() const {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
- }
-
- /// \brief Returns the CXXConstructExpr from this new-expression, or null.
- const CXXConstructExpr* getConstructExpr() const {
- return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
- }
-
- /// Answers whether the usual array deallocation function for the
- /// allocated type expects the size of the allocation as a
- /// parameter.
- bool doesUsualArrayDeleteWantSize() const {
- return UsualArrayDeleteWantsSize;
- }
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
-
- llvm::iterator_range<arg_iterator> placement_arguments() {
- return llvm::make_range(placement_arg_begin(), placement_arg_end());
- }
-
- llvm::iterator_range<const_arg_iterator> placement_arguments() const {
- return llvm::make_range(placement_arg_begin(), placement_arg_end());
- }
-
- arg_iterator placement_arg_begin() {
- return SubExprs + Array + hasInitializer();
- }
- arg_iterator placement_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
- const_arg_iterator placement_arg_begin() const {
- return SubExprs + Array + hasInitializer();
- }
- const_arg_iterator placement_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
-
- typedef Stmt **raw_arg_iterator;
- raw_arg_iterator raw_arg_begin() { return SubExprs; }
- raw_arg_iterator raw_arg_end() {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
- const_arg_iterator raw_arg_begin() const { return SubExprs; }
- const_arg_iterator raw_arg_end() const {
- return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
- }
-
- SourceLocation getStartLoc() const { return Range.getBegin(); }
- SourceLocation getEndLoc() const { return Range.getEnd(); }
-
- SourceRange getDirectInitRange() const { return DirectInitRange; }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return Range;
- }
- SourceLocation getLocStart() const LLVM_READONLY { return getStartLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNewExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(raw_arg_begin(), raw_arg_end());
- }
-};
-
-/// \brief Represents a \c delete expression for memory deallocation and
-/// destructor calls, e.g. "delete[] pArray".
-class CXXDeleteExpr : public Expr {
- /// Points to the operator delete overload that is used. Could be a member.
- FunctionDecl *OperatorDelete;
- /// The pointer expression to be deleted.
- Stmt *Argument;
- /// Location of the expression.
- SourceLocation Loc;
- /// Is this a forced global delete, i.e. "::delete"?
- bool GlobalDelete : 1;
- /// Is this the array form of delete, i.e. "delete[]"?
- bool ArrayForm : 1;
- /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied
- /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm
- /// will be true).
- bool ArrayFormAsWritten : 1;
- /// Does the usual deallocation function for the element type require
- /// a size_t argument?
- bool UsualArrayDeleteWantsSize : 1;
-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(),
- arg->containsUnexpandedParameterPack()),
- OperatorDelete(operatorDelete), Argument(arg), Loc(loc),
- GlobalDelete(globalDelete),
- ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
- UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { }
- explicit CXXDeleteExpr(EmptyShell Shell)
- : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr),
- Argument(nullptr) {}
-
- bool isGlobalDelete() const { return GlobalDelete; }
- bool isArrayForm() const { return ArrayForm; }
- bool isArrayFormAsWritten() const { return ArrayFormAsWritten; }
-
- /// Answers whether the usual array deallocation function for the
- /// allocated type expects the size of the allocation as a
- /// parameter. This can be true even if the actual deallocation
- /// function that we're using doesn't want a size.
- bool doesUsualArrayDeleteWantSize() const {
- return UsualArrayDeleteWantsSize;
- }
-
- FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
-
- Expr *getArgument() { return cast<Expr>(Argument); }
- const Expr *getArgument() const { return cast<Expr>(Argument); }
-
- /// \brief Retrieve the type being destroyed.
- ///
- /// If the type being destroyed is a dependent type which may or may not
- /// be a pointer, return an invalid type.
- QualType getDestroyedType() const;
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY {return Argument->getLocEnd();}
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDeleteExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Argument, &Argument+1); }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Stores the type being destroyed by a pseudo-destructor expression.
-class PseudoDestructorTypeStorage {
- /// \brief Either the type source information or the name of the type, if
- /// it couldn't be resolved due to type-dependence.
- llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
-
- /// \brief The starting source location of the pseudo-destructor type.
- SourceLocation Location;
-
-public:
- PseudoDestructorTypeStorage() { }
-
- PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
- : Type(II), Location(Loc) { }
-
- PseudoDestructorTypeStorage(TypeSourceInfo *Info);
-
- TypeSourceInfo *getTypeSourceInfo() const {
- return Type.dyn_cast<TypeSourceInfo *>();
- }
-
- IdentifierInfo *getIdentifier() const {
- return Type.dyn_cast<IdentifierInfo *>();
- }
-
- SourceLocation getLocation() const { return Location; }
-};
-
-/// \brief Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
-///
-/// A pseudo-destructor is an expression that looks like a member access to a
-/// destructor of a scalar type, except that scalar types don't have
-/// destructors. For example:
-///
-/// \code
-/// typedef int T;
-/// void f(int *p) {
-/// p->T::~T();
-/// }
-/// \endcode
-///
-/// Pseudo-destructors typically occur when instantiating templates such as:
-///
-/// \code
-/// template<typename T>
-/// void destroy(T* ptr) {
-/// ptr->T::~T();
-/// }
-/// \endcode
-///
-/// for scalar types. A pseudo-destructor expression has no run-time semantics
-/// beyond evaluating the base expression.
-class CXXPseudoDestructorExpr : public Expr {
- /// \brief The base expression (that is being destroyed).
- Stmt *Base;
-
- /// \brief Whether the operator was an arrow ('->'); otherwise, it was a
- /// period ('.').
- bool IsArrow : 1;
-
- /// \brief The location of the '.' or '->' operator.
- SourceLocation OperatorLoc;
-
- /// \brief The nested-name-specifier that follows the operator, if present.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The type that precedes the '::' in a qualified pseudo-destructor
- /// expression.
- TypeSourceInfo *ScopeType;
-
- /// \brief The location of the '::' in a qualified pseudo-destructor
- /// expression.
- SourceLocation ColonColonLoc;
-
- /// \brief The location of the '~'.
- SourceLocation TildeLoc;
-
- /// \brief The type being destroyed, or its name if we were unable to
- /// resolve the name.
- PseudoDestructorTypeStorage DestroyedType;
-
- friend class ASTStmtReader;
-
-public:
- CXXPseudoDestructorExpr(const ASTContext &Context,
- Expr *Base, bool isArrow, SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- TypeSourceInfo *ScopeType,
- SourceLocation ColonColonLoc,
- SourceLocation TildeLoc,
- PseudoDestructorTypeStorage DestroyedType);
-
- explicit CXXPseudoDestructorExpr(EmptyShell Shell)
- : Expr(CXXPseudoDestructorExprClass, Shell),
- Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { }
-
- Expr *getBase() const { return cast<Expr>(Base); }
-
- /// \brief Determines whether this member expression actually had
- /// a C++ nested-name-specifier prior to the name of the member, e.g.,
- /// x->Base::foo.
- bool hasQualifier() const { return QualifierLoc.hasQualifier(); }
-
- /// \brief Retrieves the nested-name-specifier that qualifies the type name,
- /// with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief If the member name was qualified, retrieves the
- /// nested-name-specifier that precedes the member name. Otherwise, returns
- /// null.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Determine whether this pseudo-destructor expression was written
- /// using an '->' (otherwise, it used a '.').
- bool isArrow() const { return IsArrow; }
-
- /// \brief Retrieve the location of the '.' or '->' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Retrieve the scope type in a qualified pseudo-destructor
- /// expression.
- ///
- /// Pseudo-destructor expressions can have extra qualification within them
- /// that is not part of the nested-name-specifier, e.g., \c p->T::~T().
- /// Here, if the object type of the expression is (or may be) a scalar type,
- /// \p T may also be a scalar type and, therefore, cannot be part of a
- /// nested-name-specifier. It is stored as the "scope type" of the pseudo-
- /// destructor expression.
- TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
-
- /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
- /// expression.
- SourceLocation getColonColonLoc() const { return ColonColonLoc; }
-
- /// \brief Retrieve the location of the '~'.
- SourceLocation getTildeLoc() const { return TildeLoc; }
-
- /// \brief Retrieve the source location information for the type
- /// being destroyed.
- ///
- /// This type-source information is available for non-dependent
- /// pseudo-destructor expressions and some dependent pseudo-destructor
- /// expressions. Returns null if we only have the identifier for a
- /// dependent pseudo-destructor expression.
- TypeSourceInfo *getDestroyedTypeInfo() const {
- return DestroyedType.getTypeSourceInfo();
- }
-
- /// \brief In a dependent pseudo-destructor expression for which we do not
- /// have full type information on the destroyed type, provides the name
- /// of the destroyed type.
- IdentifierInfo *getDestroyedTypeIdentifier() const {
- return DestroyedType.getIdentifier();
- }
-
- /// \brief Retrieve the type being destroyed.
- QualType getDestroyedType() const;
-
- /// \brief Retrieve the starting location of the type being destroyed.
- SourceLocation getDestroyedTypeLoc() const {
- return DestroyedType.getLocation();
- }
-
- /// \brief Set the name of destroyed type for a dependent pseudo-destructor
- /// expression.
- void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) {
- DestroyedType = PseudoDestructorTypeStorage(II, Loc);
- }
-
- /// \brief Set the destroyed type.
- void setDestroyedType(TypeSourceInfo *Info) {
- DestroyedType = PseudoDestructorTypeStorage(Info);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {return Base->getLocStart();}
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXPseudoDestructorExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base + 1); }
-};
-
-/// \brief A type trait used in the implementation of various C++11 and
-/// Library TR1 trait templates.
-///
-/// \code
-/// __is_pod(int) == true
-/// __is_enum(std::string) == false
-/// __is_trivially_constructible(vector<int>, int*, int*)
-/// \endcode
-class TypeTraitExpr final
- : public Expr,
- private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> {
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing parenthesis.
- SourceLocation RParenLoc;
-
- // Note: The TypeSourceInfos for the arguments are allocated after the
- // TypeTraitExpr.
-
- TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
- ArrayRef<TypeSourceInfo *> Args,
- SourceLocation RParenLoc,
- bool Value);
-
- TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) { }
-
- size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
- return getNumArgs();
- }
-
-public:
- /// \brief Create a new type trait expression.
- static TypeTraitExpr *Create(const ASTContext &C, QualType T,
- SourceLocation Loc, TypeTrait Kind,
- ArrayRef<TypeSourceInfo *> Args,
- SourceLocation RParenLoc,
- bool Value);
-
- static TypeTraitExpr *CreateDeserialized(const ASTContext &C,
- unsigned NumArgs);
-
- /// \brief Determine which type trait this expression uses.
- TypeTrait getTrait() const {
- return static_cast<TypeTrait>(TypeTraitExprBits.Kind);
- }
-
- bool getValue() const {
- assert(!isValueDependent());
- return TypeTraitExprBits.Value;
- }
-
- /// \brief Determine the number of arguments to this type trait.
- unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; }
-
- /// \brief Retrieve the Ith argument.
- TypeSourceInfo *getArg(unsigned I) const {
- assert(I < getNumArgs() && "Argument out-of-range");
- return getArgs()[I];
- }
-
- /// \brief Retrieve the argument types.
- ArrayRef<TypeSourceInfo *> getArgs() const {
- return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(),
- getNumArgs());
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == TypeTraitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief An Embarcadero array type trait, as used in the implementation of
-/// __array_rank and __array_extent.
-///
-/// Example:
-/// \code
-/// __array_rank(int[10][20]) == 2
-/// __array_extent(int, 1) == 20
-/// \endcode
-class ArrayTypeTraitExpr : public Expr {
- virtual void anchor();
-
- /// \brief The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
- unsigned ATT : 2;
-
- /// \brief The value of the type trait. Unspecified if dependent.
- uint64_t Value;
-
- /// \brief The array dimension being queried, or -1 if not used.
- Expr *Dimension;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The type being queried.
- TypeSourceInfo *QueriedType;
-
-public:
- ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
- TypeSourceInfo *queried, uint64_t value,
- Expr *dimension, SourceLocation rparen, QualType ty)
- : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
- false, queried->getType()->isDependentType(),
- (queried->getType()->isInstantiationDependentType() ||
- (dimension && dimension->isInstantiationDependent())),
- queried->getType()->containsUnexpandedParameterPack()),
- ATT(att), Value(value), Dimension(dimension),
- Loc(loc), RParen(rparen), QueriedType(queried) { }
-
-
- explicit ArrayTypeTraitExpr(EmptyShell Empty)
- : Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false),
- QueriedType() { }
-
- virtual ~ArrayTypeTraitExpr() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
-
- QualType getQueriedType() const { return QueriedType->getType(); }
-
- TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
-
- uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
-
- Expr *getDimensionExpression() const { return Dimension; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ArrayTypeTraitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
-};
-
-/// \brief An expression trait intrinsic.
-///
-/// Example:
-/// \code
-/// __is_lvalue_expr(std::cout) == true
-/// __is_lvalue_expr(1) == false
-/// \endcode
-class ExpressionTraitExpr : public Expr {
- /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned.
- unsigned ET : 31;
- /// \brief The value of the type trait. Unspecified if dependent.
- bool Value : 1;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The expression being queried.
- Expr* QueriedExpression;
-public:
- ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et,
- Expr *queried, bool value,
- SourceLocation rparen, QualType resultType)
- : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary,
- false, // Not type-dependent
- // Value-dependent if the argument is type-dependent.
- queried->isTypeDependent(),
- queried->isInstantiationDependent(),
- queried->containsUnexpandedParameterPack()),
- ET(et), Value(value), Loc(loc), RParen(rparen),
- QueriedExpression(queried) { }
-
- explicit ExpressionTraitExpr(EmptyShell Empty)
- : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false),
- QueriedExpression() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
-
- Expr *getQueriedExpression() const { return QueriedExpression; }
-
- bool getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExpressionTraitExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
-};
-
-
-/// \brief A reference to an overloaded function set, either an
-/// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
-class OverloadExpr : public Expr {
- /// \brief The common name of these declarations.
- DeclarationNameInfo NameInfo;
-
- /// \brief The nested-name-specifier that qualifies the name, if any.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// The results. These are undesugared, which is to say, they may
- /// include UsingShadowDecls. Access is relative to the naming
- /// class.
- // FIXME: Allocate this data after the OverloadExpr subclass.
- DeclAccessPair *Results;
- unsigned NumResults;
-
-protected:
- /// \brief Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo;
-
- /// \brief Return the optional template keyword and arguments info.
- ASTTemplateKWAndArgsInfo *
- getTrailingASTTemplateKWAndArgsInfo(); // defined far below.
-
- /// \brief Return the optional template keyword and arguments info.
- const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
- return const_cast<OverloadExpr *>(this)
- ->getTrailingASTTemplateKWAndArgsInfo();
- }
-
- /// Return the optional template arguments.
- TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below
-
- OverloadExpr(StmtClass K, const ASTContext &C,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End,
- bool KnownDependent,
- bool KnownInstantiationDependent,
- bool KnownContainsUnexpandedParameterPack);
-
- OverloadExpr(StmtClass K, EmptyShell Empty)
- : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0),
- HasTemplateKWAndArgsInfo(false) { }
-
- void initializeResults(const ASTContext &C,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
-
-public:
- struct FindResult {
- OverloadExpr *Expression;
- bool IsAddressOfOperand;
- bool HasFormOfMemberPointer;
- };
-
- /// \brief Finds the overloaded expression in the given expression \p E of
- /// OverloadTy.
- ///
- /// \return the expression (which must be there) and true if it has
- /// the particular form of a member pointer expression
- static FindResult find(Expr *E) {
- assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
-
- FindResult Result;
-
- E = E->IgnoreParens();
- if (isa<UnaryOperator>(E)) {
- assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
- E = cast<UnaryOperator>(E)->getSubExpr();
- OverloadExpr *Ovl = cast<OverloadExpr>(E->IgnoreParens());
-
- Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
- Result.IsAddressOfOperand = true;
- Result.Expression = Ovl;
- } else {
- Result.HasFormOfMemberPointer = false;
- Result.IsAddressOfOperand = false;
- Result.Expression = cast<OverloadExpr>(E);
- }
-
- return Result;
- }
-
- /// \brief Gets the naming class of this lookup, if any.
- CXXRecordDecl *getNamingClass() const;
-
- typedef UnresolvedSetImpl::iterator decls_iterator;
- decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
- decls_iterator decls_end() const {
- return UnresolvedSetIterator(Results + NumResults);
- }
- llvm::iterator_range<decls_iterator> decls() const {
- return llvm::make_range(decls_begin(), decls_end());
- }
-
- /// \brief Gets the number of declarations in the unresolved set.
- unsigned getNumDecls() const { return NumResults; }
-
- /// \brief Gets the full name info.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
-
- /// \brief Gets the name looked up.
- DeclarationName getName() const { return NameInfo.getName(); }
-
- /// \brief Gets the location of the name.
- SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
-
- /// \brief Fetches the nested-name qualifier, if one was given.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Fetches the nested-name qualifier with source-location
- /// information, if one was given.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the location of the template keyword preceding
- /// this name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
- }
-
- /// \brief Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the name, if any.
- SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
- }
-
- /// \brief Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
- }
-
- /// \brief Determines whether the name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// \brief Determines whether this expression had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- TemplateArgumentLoc const *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
- return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
- }
-
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs;
- }
-
- /// \brief Copies the template arguments into the given structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedLookupExprClass ||
- T->getStmtClass() == UnresolvedMemberExprClass;
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief A reference to a name which we were able to look up during
-/// parsing but could not resolve to a specific declaration.
-///
-/// This arises in several ways:
-/// * we might be waiting for argument-dependent lookup;
-/// * the name might resolve to an overloaded function;
-/// and eventually:
-/// * the lookup might have included a function template.
-///
-/// These never include UnresolvedUsingValueDecls, which are always class
-/// members and therefore appear only in UnresolvedMemberLookupExprs.
-class UnresolvedLookupExpr final
- : public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
- /// True if these lookup results should be extended by
- /// argument-dependent lookup if this is the operand of a function
- /// call.
- bool RequiresADL;
-
- /// True if these lookup results are overloaded. This is pretty
- /// trivially rederivable if we urgently need to kill this field.
- bool Overloaded;
-
- /// The naming class (C++ [class.access.base]p5) of the lookup, if
- /// any. This can generally be recalculated from the context chain,
- /// but that can be fairly expensive for unqualified lookups. If we
- /// want to improve memory use here, this could go in a union
- /// against the qualified-lookup bits.
- CXXRecordDecl *NamingClass;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- UnresolvedLookupExpr(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool RequiresADL, bool Overloaded,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End)
- : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
- NameInfo, TemplateArgs, Begin, End, false, false, false),
- RequiresADL(RequiresADL),
- Overloaded(Overloaded), NamingClass(NamingClass)
- {}
-
- UnresolvedLookupExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedLookupExprClass, Empty),
- RequiresADL(false), Overloaded(false), NamingClass(nullptr)
- {}
-
- friend TrailingObjects;
- friend class OverloadExpr;
- friend class ASTStmtReader;
-
-public:
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL, bool Overloaded,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
- return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
- SourceLocation(), NameInfo,
- ADL, Overloaded, nullptr, Begin, End);
- }
-
- static UnresolvedLookupExpr *Create(const ASTContext &C,
- CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- bool ADL,
- const TemplateArgumentListInfo *Args,
- UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
-
- static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// True if this declaration should be extended by
- /// argument-dependent lookup.
- bool requiresADL() const { return RequiresADL; }
-
- /// True if this lookup is overloaded.
- bool isOverloaded() const { return Overloaded; }
-
- /// Gets the 'naming class' (in the sense of C++0x
- /// [class.access.base]p5) of the lookup. This is the scope
- /// that was looked in to find these results.
- CXXRecordDecl *getNamingClass() const { return NamingClass; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (NestedNameSpecifierLoc l = getQualifierLoc())
- return l.getBeginLoc();
- return getNameInfo().getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getNameInfo().getLocEnd();
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedLookupExprClass;
- }
-};
-
-/// \brief A qualified reference to a name whose declaration cannot
-/// yet be resolved.
-///
-/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
-/// it expresses a reference to a declaration such as
-/// X<T>::value. The difference, however, is that an
-/// DependentScopeDeclRefExpr node is used only within C++ templates when
-/// the qualification (e.g., X<T>::) refers to a dependent type. In
-/// this case, X<T>::value cannot resolve to a declaration because the
-/// declaration will differ from one instantiation of X<T> to the
-/// next. Therefore, DependentScopeDeclRefExpr keeps track of the
-/// qualifier (X<T>::) and the name of the entity being referenced
-/// ("value"). Such expressions will instantiate to a DeclRefExpr once the
-/// declaration can be found.
-class DependentScopeDeclRefExpr final
- : public Expr,
- private llvm::TrailingObjects<DependentScopeDeclRefExpr,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// \brief The nested-name-specifier that qualifies this unresolved
- /// declaration name.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief The name of the entity we will be referencing.
- DeclarationNameInfo NameInfo;
-
- /// \brief Whether the name includes info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- DependentScopeDeclRefExpr(QualType T,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *Args);
-
-public:
- static DependentScopeDeclRefExpr *Create(const ASTContext &C,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
- static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// \brief Retrieve the name that this expression refers to.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
-
- /// \brief Retrieve the name that this expression refers to.
- DeclarationName getDeclName() const { return NameInfo.getName(); }
-
- /// \brief Retrieve the location of the name within the expression.
- ///
- /// For example, in "X<T>::value" this is the location of "value".
- SourceLocation getLocation() const { return NameInfo.getLoc(); }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the
- /// name, with source location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies this
- /// declaration.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Retrieve the location of the template keyword preceding
- /// this name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
- }
-
- /// \brief Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the name, if any.
- SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
- }
-
- /// \brief Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
-
- /// Determines whether the name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// Determines whether this lookup had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- /// \brief Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- TemplateArgumentLoc const *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr,
- /// and differs from getLocation().getStart().
- SourceLocation getLocStart() const LLVM_READONLY {
- return QualifierLoc.getBeginLoc();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getLocation();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DependentScopeDeclRefExprClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// Represents an expression -- generally a full-expression -- that
-/// introduces cleanups to be run at the end of the sub-expression's
-/// evaluation. The most common source of expression-introduced
-/// cleanups is temporary objects in C++, but several other kinds of
-/// expressions can create cleanups, including basically every
-/// call in ARC that returns an Objective-C pointer.
-///
-/// This expression also tracks whether the sub-expression contains a
-/// potentially-evaluated block literal. The lifetime of a block
-/// literal is the extent of the enclosing scope.
-class ExprWithCleanups final
- : public Expr,
- private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
-public:
- /// The type of objects that are kept in the cleanup.
- /// It's useful to remember the set of blocks; we could also
- /// remember the set of temporaries, but there's currently
- /// no need.
- typedef BlockDecl *CleanupObject;
-
-private:
- Stmt *SubExpr;
-
- ExprWithCleanups(EmptyShell, unsigned NumObjects);
- ExprWithCleanups(Expr *SubExpr, ArrayRef<CleanupObject> Objects);
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-
-public:
- static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty,
- unsigned numObjects);
-
- static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
- ArrayRef<CleanupObject> objects);
-
- ArrayRef<CleanupObject> getObjects() const {
- return llvm::makeArrayRef(getTrailingObjects<CleanupObject>(),
- getNumObjects());
- }
-
- unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
-
- CleanupObject getObject(unsigned i) const {
- assert(i < getNumObjects() && "Index out of range");
- return getObjects()[i];
- }
-
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
-
- /// As with any mutator of the AST, be very careful
- /// when modifying an existing AST to preserve its invariants.
- void setSubExpr(Expr *E) { SubExpr = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExpr->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExprWithCleanupsClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
-};
-
-/// \brief Describes an explicit type conversion that uses functional
-/// notion but could not be resolved because one or more arguments are
-/// type-dependent.
-///
-/// The explicit type conversions expressed by
-/// CXXUnresolvedConstructExpr have the form <tt>T(a1, a2, ..., aN)</tt>,
-/// where \c T is some type and \c a1, \c a2, ..., \c aN are values, and
-/// either \c T is a dependent type or one or more of the <tt>a</tt>'s is
-/// type-dependent. For example, this would occur in a template such
-/// as:
-///
-/// \code
-/// template<typename T, typename A1>
-/// inline T make_a(const A1& a1) {
-/// return T(a1);
-/// }
-/// \endcode
-///
-/// When the returned expression is instantiated, it may resolve to a
-/// constructor call, conversion function call, or some kind of type
-/// conversion.
-class CXXUnresolvedConstructExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> {
- /// \brief The type being constructed.
- TypeSourceInfo *Type;
-
- /// \brief The location of the left parentheses ('(').
- SourceLocation LParenLoc;
-
- /// \brief The location of the right parentheses (')').
- SourceLocation RParenLoc;
-
- /// \brief The number of arguments used to construct the type.
- unsigned NumArgs;
-
- CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
- SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
- SourceLocation RParenLoc);
-
- CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty), Type(), NumArgs(NumArgs) { }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-
-public:
- static CXXUnresolvedConstructExpr *Create(const ASTContext &C,
- TypeSourceInfo *Type,
- SourceLocation LParenLoc,
- ArrayRef<Expr*> Args,
- SourceLocation RParenLoc);
-
- static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C,
- unsigned NumArgs);
-
- /// \brief Retrieve the type that is being constructed, as specified
- /// in the source code.
- QualType getTypeAsWritten() const { return Type->getType(); }
-
- /// \brief Retrieve the type source information for the type being
- /// constructed.
- TypeSourceInfo *getTypeSourceInfo() const { return Type; }
-
- /// \brief Retrieve the location of the left parentheses ('(') that
- /// precedes the argument list.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
-
- /// \brief Retrieve the location of the right parentheses (')') that
- /// follows the argument list.
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- /// \brief Retrieve the number of arguments.
- unsigned arg_size() const { return NumArgs; }
-
- typedef Expr** arg_iterator;
- arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
- arg_iterator arg_end() { return arg_begin() + NumArgs; }
-
- typedef const Expr* const * const_arg_iterator;
- const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
- const_arg_iterator arg_end() const {
- return arg_begin() + NumArgs;
- }
-
- Expr *getArg(unsigned I) {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
- }
-
- const Expr *getArg(unsigned I) const {
- assert(I < NumArgs && "Argument index out-of-range");
- return *(arg_begin() + I);
- }
-
- void setArg(unsigned I, Expr *E) {
- assert(I < NumArgs && "Argument index out-of-range");
- *(arg_begin() + I) = E;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (!RParenLoc.isValid() && NumArgs > 0)
- return getArg(NumArgs - 1)->getLocEnd();
- return RParenLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUnresolvedConstructExprClass;
- }
-
- // Iterators
- child_range children() {
- Stmt **begin = reinterpret_cast<Stmt **>(arg_begin());
- return child_range(begin, begin + NumArgs);
- }
-};
-
-/// \brief Represents a C++ member access expression where the actual
-/// member referenced could not be resolved because the base
-/// expression or the member name was dependent.
-///
-/// Like UnresolvedMemberExprs, these can be either implicit or
-/// explicit accesses. It is only possible to get one of these with
-/// an implicit access if a qualifier is provided.
-class CXXDependentScopeMemberExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- /// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f. Can be null in implicit accesses.
- Stmt *Base;
-
- /// \brief The type of the base expression. Never null, even for
- /// implicit accesses.
- QualType BaseType;
-
- /// \brief Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// \brief Whether this member expression has info for explicit template
- /// keyword and arguments.
- bool HasTemplateKWAndArgsInfo : 1;
-
- /// \brief The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
-
- /// \brief The nested-name-specifier that precedes the member name, if any.
- NestedNameSpecifierLoc QualifierLoc;
-
- /// \brief In a qualified member access expression such as t->Base::f, this
- /// member stores the resolves of name lookup in the context of the member
- /// access expression, to be used at instantiation time.
- ///
- /// FIXME: This member, along with the QualifierLoc, could
- /// be stuck into a structure that is optionally allocated at the end of
- /// the CXXDependentScopeMemberExpr, to save space in the common case.
- NamedDecl *FirstQualifierFoundInScope;
-
- /// \brief The member to which this member expression refers, which
- /// can be name, overloaded operator, or destructor.
- ///
- /// FIXME: could also be a template-id
- DeclarationNameInfo MemberNameInfo;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
- QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
-public:
- CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
- QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo);
-
- static CXXDependentScopeMemberExpr *
- Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
-
- static CXXDependentScopeMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// \brief True if this is an implicit access, i.e. one in which the
- /// member being accessed was not written in the source. The source
- /// location of the operator is invalid in this case.
- bool isImplicitAccess() const;
-
- /// \brief Retrieve the base object of this member expressions,
- /// e.g., the \c x in \c x.m.
- Expr *getBase() const {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
-
- QualType getBaseType() const { return BaseType; }
-
- /// \brief Determine whether this member expression used the '->'
- /// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return IsArrow; }
-
- /// \brief Retrieve the location of the '->' or '.' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the member
- /// name.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
-
- /// \brief Retrieve the nested-name-specifier that qualifies the member
- /// name, with source location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
-
- /// \brief Retrieve the first part of the nested-name-specifier that was
- /// found in the scope of the member access expression when the member access
- /// was initially parsed.
- ///
- /// This function only returns a useful result when member access expression
- /// uses a qualified member name, e.g., "x.Base::f". Here, the declaration
- /// returned by this function describes what was found by unqualified name
- /// lookup for the identifier "Base" within the scope of the member access
- /// expression itself. At template instantiation time, this information is
- /// combined with the results of name lookup into the type of the object
- /// expression itself (the class type of x).
- NamedDecl *getFirstQualifierFoundInScope() const {
- return FirstQualifierFoundInScope;
- }
-
- /// \brief Retrieve the name of the member that this expression
- /// refers to.
- const DeclarationNameInfo &getMemberNameInfo() const {
- return MemberNameInfo;
- }
-
- /// \brief Retrieve the name of the member that this expression
- /// refers to.
- DeclarationName getMember() const { return MemberNameInfo.getName(); }
-
- // \brief Retrieve the location of the name of the member that this
- // expression refers to.
- SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); }
-
- /// \brief Retrieve the location of the template keyword preceding the
- /// member name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
- }
-
- /// \brief Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the member name, if any.
- SourceLocation getLAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
- }
-
- /// \brief Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the member name, if any.
- SourceLocation getRAngleLoc() const {
- if (!HasTemplateKWAndArgsInfo) return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
-
- /// Determines whether the member name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
-
- /// \brief Determines whether this member expression actually had a C++
- /// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
-
- /// \brief Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
-
- /// \brief Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
-
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
-
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (!isImplicitAccess())
- return Base->getLocStart();
- if (getQualifier())
- return getQualifierLoc().getBeginLoc();
- return MemberNameInfo.getBeginLoc();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return MemberNameInfo.getEndLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDependentScopeMemberExprClass;
- }
-
- // Iterators
- child_range children() {
- if (isImplicitAccess())
- return child_range(child_iterator(), child_iterator());
- return child_range(&Base, &Base + 1);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// \brief Represents a C++ member access expression for which lookup
-/// produced a set of overloaded functions.
-///
-/// The member access may be explicit or implicit:
-/// \code
-/// struct A {
-/// int a, b;
-/// int explicitAccess() { return this->a + this->A::b; }
-/// int implicitAccess() { return a + A::b; }
-/// };
-/// \endcode
-///
-/// In the final AST, an explicit access always becomes a MemberExpr.
-/// An implicit access may become either a MemberExpr or a
-/// DeclRefExpr, depending on whether the member is static.
-class UnresolvedMemberExpr final
- : public OverloadExpr,
- private llvm::TrailingObjects<
- UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> {
- /// \brief Whether this member expression used the '->' operator or
- /// the '.' operator.
- bool IsArrow : 1;
-
- /// \brief Whether the lookup results contain an unresolved using
- /// declaration.
- bool HasUnresolvedUsing : 1;
-
- /// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f.
- ///
- /// This can be null if this is an 'unbased' member expression.
- Stmt *Base;
-
- /// \brief The type of the base expression; never null.
- QualType BaseType;
-
- /// \brief The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
-
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return HasTemplateKWAndArgsInfo ? 1 : 0;
- }
-
- UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
-
- UnresolvedMemberExpr(EmptyShell Empty)
- : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
- HasUnresolvedUsing(false), Base(nullptr) { }
-
- friend TrailingObjects;
- friend class OverloadExpr;
- friend class ASTStmtReader;
-
-public:
- static UnresolvedMemberExpr *
- Create(const ASTContext &C, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
-
- static UnresolvedMemberExpr *
- CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
-
- /// \brief True if this is an implicit access, i.e., one in which the
- /// member being accessed was not written in the source.
- ///
- /// The source location of the operator is invalid in this case.
- bool isImplicitAccess() const;
-
- /// \brief Retrieve the base object of this member expressions,
- /// e.g., the \c x in \c x.m.
- Expr *getBase() {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
- const Expr *getBase() const {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
-
- QualType getBaseType() const { return BaseType; }
-
- /// \brief Determine whether the lookup results contain an unresolved using
- /// declaration.
- bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
-
- /// \brief Determine whether this member expression used the '->'
- /// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return IsArrow; }
-
- /// \brief Retrieve the location of the '->' or '.' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Retrieve the naming class of this lookup.
- CXXRecordDecl *getNamingClass() const;
-
- /// \brief Retrieve the full name info for the member that this expression
- /// refers to.
- const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
-
- /// \brief Retrieve the name of the member that this expression
- /// refers to.
- DeclarationName getMemberName() const { return getName(); }
-
- // \brief Retrieve the location of the name of the member that this
- // expression refers to.
- SourceLocation getMemberLoc() const { return getNameLoc(); }
-
- // \brief Return the preferred location (the member name) for the arrow when
- // diagnosing a problem with this expression.
- SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- if (!isImplicitAccess())
- return Base->getLocStart();
- if (NestedNameSpecifierLoc l = getQualifierLoc())
- return l.getBeginLoc();
- return getMemberNameInfo().getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getMemberNameInfo().getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedMemberExprClass;
- }
-
- // Iterators
- child_range children() {
- if (isImplicitAccess())
- return child_range(child_iterator(), child_iterator());
- return child_range(&Base, &Base + 1);
- }
-};
-
-inline ASTTemplateKWAndArgsInfo *
-OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo)
- return nullptr;
-
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
-}
-
-inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
- if (isa<UnresolvedLookupExpr>(this))
- return cast<UnresolvedLookupExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
- else
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
-}
-
-/// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
-///
-/// The noexcept expression tests whether a given expression might throw. Its
-/// result is a boolean constant.
-class CXXNoexceptExpr : public Expr {
- bool Value : 1;
- Stmt *Operand;
- SourceRange Range;
-
- friend class ASTStmtReader;
-
-public:
- CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
- SourceLocation Keyword, SourceLocation RParen)
- : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
- /*TypeDependent*/false,
- /*ValueDependent*/Val == CT_Dependent,
- Val == CT_Dependent || Operand->isInstantiationDependent(),
- Operand->containsUnexpandedParameterPack()),
- Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen)
- { }
-
- CXXNoexceptExpr(EmptyShell Empty)
- : Expr(CXXNoexceptExprClass, Empty)
- { }
-
- Expr *getOperand() const { return static_cast<Expr*>(Operand); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- bool getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNoexceptExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Operand, &Operand + 1); }
-};
-
-/// \brief Represents a C++11 pack expansion that produces a sequence of
-/// expressions.
-///
-/// A pack expansion expression contains a pattern (which itself is an
-/// expression) followed by an ellipsis. For example:
-///
-/// \code
-/// template<typename F, typename ...Types>
-/// void forward(F f, Types &&...args) {
-/// f(static_cast<Types&&>(args)...);
-/// }
-/// \endcode
-///
-/// Here, the argument to the function object \c f is a pack expansion whose
-/// pattern is \c static_cast<Types&&>(args). When the \c forward function
-/// template is instantiated, the pack expansion will instantiate to zero or
-/// or more function arguments to the function object \c f.
-class PackExpansionExpr : public Expr {
- SourceLocation EllipsisLoc;
-
- /// \brief The number of expansions that will be produced by this pack
- /// expansion expression, if known.
- ///
- /// When zero, the number of expansions is not known. Otherwise, this value
- /// is the number of expansions + 1.
- unsigned NumExpansions;
-
- Stmt *Pattern;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
-public:
- PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions)
- : Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
- Pattern->getObjectKind(), /*TypeDependent=*/true,
- /*ValueDependent=*/true, /*InstantiationDependent=*/true,
- /*ContainsUnexpandedParameterPack=*/false),
- EllipsisLoc(EllipsisLoc),
- NumExpansions(NumExpansions? *NumExpansions + 1 : 0),
- Pattern(Pattern) { }
-
- PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) { }
-
- /// \brief Retrieve the pattern of the pack expansion.
- Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); }
-
- /// \brief Retrieve the pattern of the pack expansion.
- const Expr *getPattern() const { return reinterpret_cast<Expr *>(Pattern); }
-
- /// \brief Retrieve the location of the ellipsis that describes this pack
- /// expansion.
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
-
- /// \brief Determine the number of expansions that will be produced when
- /// this pack expansion is instantiated, if already known.
- Optional<unsigned> getNumExpansions() const {
- if (NumExpansions)
- return NumExpansions - 1;
-
- return None;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return Pattern->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return EllipsisLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PackExpansionExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&Pattern, &Pattern + 1);
- }
-};
-
-
-/// \brief Represents an expression that computes the length of a parameter
-/// pack.
-///
-/// \code
-/// template<typename ...Types>
-/// struct count {
-/// static const unsigned value = sizeof...(Types);
-/// };
-/// \endcode
-class SizeOfPackExpr final
- : public Expr,
- private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> {
- /// \brief The location of the \c sizeof keyword.
- SourceLocation OperatorLoc;
-
- /// \brief The location of the name of the parameter pack.
- SourceLocation PackLoc;
-
- /// \brief The location of the closing parenthesis.
- SourceLocation RParenLoc;
-
- /// \brief The length of the parameter pack, if known.
- ///
- /// When this expression is not value-dependent, this is the length of
- /// the pack. When the expression was parsed rather than instantiated
- /// (and thus is value-dependent), this is zero.
- ///
- /// After partial substitution into a sizeof...(X) expression (for instance,
- /// within an alias template or during function template argument deduction),
- /// we store a trailing array of partially-substituted TemplateArguments,
- /// and this is the length of that array.
- unsigned Length;
-
- /// \brief The parameter pack.
- NamedDecl *Pack;
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- /// \brief Create an expression that computes the length of
- /// the given parameter pack.
- SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
- SourceLocation PackLoc, SourceLocation RParenLoc,
- Optional<unsigned> Length, ArrayRef<TemplateArgument> PartialArgs)
- : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
- /*TypeDependent=*/false, /*ValueDependent=*/!Length,
- /*InstantiationDependent=*/!Length,
- /*ContainsUnexpandedParameterPack=*/false),
- OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
- Length(Length ? *Length : PartialArgs.size()), Pack(Pack) {
- assert((!Length || PartialArgs.empty()) &&
- "have partial args for non-dependent sizeof... expression");
- TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
- std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args);
- }
-
- /// \brief Create an empty expression.
- SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs)
- : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs), Pack() {}
-
-public:
- static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc,
- NamedDecl *Pack, SourceLocation PackLoc,
- SourceLocation RParenLoc,
- Optional<unsigned> Length = None,
- ArrayRef<TemplateArgument> PartialArgs = None);
- static SizeOfPackExpr *CreateDeserialized(ASTContext &Context,
- unsigned NumPartialArgs);
-
- /// \brief Determine the location of the 'sizeof' keyword.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
-
- /// \brief Determine the location of the parameter pack.
- SourceLocation getPackLoc() const { return PackLoc; }
-
- /// \brief Determine the location of the right parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- /// \brief Retrieve the parameter pack.
- NamedDecl *getPack() const { return Pack; }
-
- /// \brief Retrieve the length of the parameter pack.
- ///
- /// This routine may only be invoked when the expression is not
- /// value-dependent.
- unsigned getPackLength() const {
- assert(!isValueDependent() &&
- "Cannot get the length of a value-dependent pack size expression");
- return Length;
- }
-
- /// \brief Determine whether this represents a partially-substituted sizeof...
- /// expression, such as is produced for:
- ///
- /// template<typename ...Ts> using X = int[sizeof...(Ts)];
- /// template<typename ...Us> void f(X<Us..., 1, 2, 3, Us...>);
- bool isPartiallySubstituted() const {
- return isValueDependent() && Length;
- }
-
- /// \brief Get
- ArrayRef<TemplateArgument> getPartialArguments() const {
- assert(isPartiallySubstituted());
- const TemplateArgument *Args = getTrailingObjects<TemplateArgument>();
- return llvm::makeArrayRef(Args, Args + Length);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SizeOfPackExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a reference to a non-type template parameter
-/// that has been substituted with a template argument.
-class SubstNonTypeTemplateParmExpr : public Expr {
- /// \brief The replaced parameter.
- NonTypeTemplateParmDecl *Param;
-
- /// \brief The replacement expression.
- Stmt *Replacement;
-
- /// \brief The location of the non-type template parameter reference.
- SourceLocation NameLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmExprClass, Empty) { }
-
-public:
- SubstNonTypeTemplateParmExpr(QualType type,
- ExprValueKind valueKind,
- SourceLocation loc,
- NonTypeTemplateParmDecl *param,
- Expr *replacement)
- : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary,
- replacement->isTypeDependent(), replacement->isValueDependent(),
- replacement->isInstantiationDependent(),
- replacement->containsUnexpandedParameterPack()),
- Param(param), Replacement(replacement), NameLoc(loc) {}
-
- SourceLocation getNameLoc() const { return NameLoc; }
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
-
- Expr *getReplacement() const { return cast<Expr>(Replacement); }
-
- NonTypeTemplateParmDecl *getParameter() const { return Param; }
-
- static bool classof(const Stmt *s) {
- return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Replacement, &Replacement+1); }
-};
-
-/// \brief Represents a reference to a non-type template parameter pack that
-/// has been substituted with a non-template argument pack.
-///
-/// When a pack expansion in the source code contains multiple parameter packs
-/// and those parameter packs correspond to different levels of template
-/// parameter lists, this node is used to represent a non-type template
-/// parameter pack from an outer level, which has already had its argument pack
-/// substituted but that still lives within a pack expansion that itself
-/// could not be instantiated. When actually performing a substitution into
-/// that pack expansion (e.g., when all template parameters have corresponding
-/// arguments), this type will be replaced with the appropriate underlying
-/// expression at the current pack substitution index.
-class SubstNonTypeTemplateParmPackExpr : public Expr {
- /// \brief The non-type template parameter pack itself.
- NonTypeTemplateParmDecl *Param;
-
- /// \brief A pointer to the set of template arguments that this
- /// parameter pack is instantiated with.
- const TemplateArgument *Arguments;
-
- /// \brief The number of template arguments in \c Arguments.
- unsigned NumArguments;
-
- /// \brief The location of the non-type template parameter pack reference.
- SourceLocation NameLoc;
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { }
-
-public:
- SubstNonTypeTemplateParmPackExpr(QualType T,
- NonTypeTemplateParmDecl *Param,
- SourceLocation NameLoc,
- const TemplateArgument &ArgPack);
-
- /// \brief Retrieve the non-type template parameter pack being substituted.
- NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
-
- /// \brief Retrieve the location of the parameter pack name.
- SourceLocation getParameterPackLocation() const { return NameLoc; }
-
- /// \brief Retrieve the template argument pack containing the substituted
- /// template arguments.
- TemplateArgument getArgumentPack() const;
-
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a reference to a function parameter pack that has been
-/// substituted but not yet expanded.
-///
-/// When a pack expansion contains multiple parameter packs at different levels,
-/// this node is used to represent a function parameter pack at an outer level
-/// which we have already substituted to refer to expanded parameters, but where
-/// the containing pack expansion cannot yet be expanded.
-///
-/// \code
-/// template<typename...Ts> struct S {
-/// template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...));
-/// };
-/// template struct S<int, int>;
-/// \endcode
-class FunctionParmPackExpr final
- : public Expr,
- private llvm::TrailingObjects<FunctionParmPackExpr, ParmVarDecl *> {
- /// \brief The function parameter pack which was referenced.
- ParmVarDecl *ParamPack;
-
- /// \brief The location of the function parameter pack reference.
- SourceLocation NameLoc;
-
- /// \brief The number of expansions of this pack.
- unsigned NumParameters;
-
- FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack,
- SourceLocation NameLoc, unsigned NumParams,
- ParmVarDecl *const *Params);
-
- friend TrailingObjects;
- friend class ASTReader;
- friend class ASTStmtReader;
-
-public:
- static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T,
- ParmVarDecl *ParamPack,
- SourceLocation NameLoc,
- ArrayRef<ParmVarDecl *> Params);
- static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context,
- unsigned NumParams);
-
- /// \brief Get the parameter pack which this expression refers to.
- ParmVarDecl *getParameterPack() const { return ParamPack; }
-
- /// \brief Get the location of the parameter pack.
- SourceLocation getParameterPackLocation() const { return NameLoc; }
-
- /// \brief Iterators over the parameters which the parameter pack expanded
- /// into.
- typedef ParmVarDecl * const *iterator;
- iterator begin() const { return getTrailingObjects<ParmVarDecl *>(); }
- iterator end() const { return begin() + NumParameters; }
-
- /// \brief Get the number of parameters in this parameter pack.
- unsigned getNumExpansions() const { return NumParameters; }
-
- /// \brief Get an expansion of the parameter pack by index.
- ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == FunctionParmPackExprClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief Represents a prvalue temporary that is written into memory so that
-/// a reference can bind to it.
-///
-/// Prvalue expressions are materialized when they need to have an address
-/// in memory for a reference to bind to. This happens when binding a
-/// reference to the result of a conversion, e.g.,
-///
-/// \code
-/// const int &r = 1.0;
-/// \endcode
-///
-/// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is
-/// then materialized via a \c MaterializeTemporaryExpr, and the reference
-/// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues
-/// (either an lvalue or an xvalue, depending on the kind of reference binding
-/// to it), maintaining the invariant that references always bind to glvalues.
-///
-/// Reference binding and copy-elision can both extend the lifetime of a
-/// temporary. When either happens, the expression will also track the
-/// declaration which is responsible for the lifetime extension.
-class MaterializeTemporaryExpr : public Expr {
-private:
- struct ExtraState {
- /// \brief The temporary-generating expression whose value will be
- /// materialized.
- Stmt *Temporary;
-
- /// \brief The declaration which lifetime-extended this reference, if any.
- /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
- const ValueDecl *ExtendingDecl;
-
- unsigned ManglingNumber;
- };
- llvm::PointerUnion<Stmt *, ExtraState *> State;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- void initializeExtraState(const ValueDecl *ExtendedBy,
- unsigned ManglingNumber);
-
-public:
- MaterializeTemporaryExpr(QualType T, Expr *Temporary,
- bool BoundToLvalueReference)
- : Expr(MaterializeTemporaryExprClass, T,
- BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
- Temporary->isTypeDependent(), Temporary->isValueDependent(),
- Temporary->isInstantiationDependent(),
- Temporary->containsUnexpandedParameterPack()),
- State(Temporary) {}
-
- MaterializeTemporaryExpr(EmptyShell Empty)
- : Expr(MaterializeTemporaryExprClass, Empty) { }
-
- Stmt *getTemporary() const {
- return State.is<Stmt *>() ? State.get<Stmt *>()
- : State.get<ExtraState *>()->Temporary;
- }
-
- /// \brief Retrieve the temporary-generating subexpression whose value will
- /// be materialized into a glvalue.
- Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
-
- /// \brief Retrieve the storage duration for the materialized temporary.
- StorageDuration getStorageDuration() const {
- const ValueDecl *ExtendingDecl = getExtendingDecl();
- if (!ExtendingDecl)
- return SD_FullExpression;
- // FIXME: This is not necessarily correct for a temporary materialized
- // within a default initializer.
- if (isa<FieldDecl>(ExtendingDecl))
- return SD_Automatic;
- return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
- }
-
- /// \brief Get the declaration which triggered the lifetime-extension of this
- /// temporary, if any.
- const ValueDecl *getExtendingDecl() const {
- return State.is<Stmt *>() ? nullptr
- : State.get<ExtraState *>()->ExtendingDecl;
- }
-
- void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
-
- unsigned getManglingNumber() const {
- return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
- }
-
- /// \brief Determine whether this materialized temporary is bound to an
- /// lvalue reference; otherwise, it's bound to an rvalue reference.
- bool isBoundToLvalueReference() const {
- return getValueKind() == VK_LValue;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getTemporary()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getTemporary()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MaterializeTemporaryExprClass;
- }
-
- // Iterators
- child_range children() {
- if (State.is<Stmt *>())
- return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
-
- auto ES = State.get<ExtraState *>();
- return child_range(&ES->Temporary, &ES->Temporary + 1);
- }
-};
-
-/// \brief Represents a folding of a pack over an operator.
-///
-/// This expression is always dependent and represents a pack expansion of the
-/// forms:
-///
-/// ( expr op ... )
-/// ( ... op expr )
-/// ( expr op ... op expr )
-class CXXFoldExpr : public Expr {
- SourceLocation LParenLoc;
- SourceLocation EllipsisLoc;
- SourceLocation RParenLoc;
- Stmt *SubExprs[2];
- BinaryOperatorKind Opcode;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-public:
- CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
- BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
- SourceLocation RParenLoc)
- : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary,
- /*Dependent*/ true, true, true,
- /*ContainsUnexpandedParameterPack*/ false),
- LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
- Opcode(Opcode) {
- SubExprs[0] = LHS;
- SubExprs[1] = RHS;
- }
- CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
-
- Expr *getLHS() const { return static_cast<Expr*>(SubExprs[0]); }
- Expr *getRHS() const { return static_cast<Expr*>(SubExprs[1]); }
-
- /// Does this produce a right-associated sequence of operators?
- bool isRightFold() const {
- return getLHS() && getLHS()->containsUnexpandedParameterPack();
- }
- /// Does this produce a left-associated sequence of operators?
- bool isLeftFold() const { return !isRightFold(); }
- /// Get the pattern, that is, the operand that contains an unexpanded pack.
- Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); }
- /// Get the operand that doesn't contain a pack, for a binary fold.
- Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); }
-
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- BinaryOperatorKind getOperator() const { return Opcode; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return LParenLoc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return RParenLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXFoldExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(SubExprs, SubExprs + 2); }
-};
-
-/// \brief Represents an expression that might suspend coroutine execution;
-/// either a co_await or co_yield expression.
-///
-/// Evaluation of this expression first evaluates its 'ready' expression. If
-/// that returns 'false':
-/// -- execution of the coroutine is suspended
-/// -- the 'suspend' expression is evaluated
-/// -- if the 'suspend' expression returns 'false', the coroutine is
-/// resumed
-/// -- otherwise, control passes back to the resumer.
-/// If the coroutine is not suspended, or when it is resumed, the 'resume'
-/// expression is evaluated, and its result is the result of the overall
-/// expression.
-class CoroutineSuspendExpr : public Expr {
- SourceLocation KeywordLoc;
-
- enum SubExpr { Common, Ready, Suspend, Resume, Count };
- Stmt *SubExprs[SubExpr::Count];
-
- friend class ASTStmtReader;
-public:
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
- Expr *Ready, Expr *Suspend, Expr *Resume)
- : Expr(SC, Resume->getType(), Resume->getValueKind(),
- Resume->getObjectKind(), Resume->isTypeDependent(),
- Resume->isValueDependent(), Common->isInstantiationDependent(),
- Common->containsUnexpandedParameterPack()),
- KeywordLoc(KeywordLoc) {
- SubExprs[SubExpr::Common] = Common;
- SubExprs[SubExpr::Ready] = Ready;
- SubExprs[SubExpr::Suspend] = Suspend;
- SubExprs[SubExpr::Resume] = Resume;
- }
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
- Expr *Common)
- : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true,
- Common->containsUnexpandedParameterPack()),
- KeywordLoc(KeywordLoc) {
- assert(Common->isTypeDependent() && Ty->isDependentType() &&
- "wrong constructor for non-dependent co_await/co_yield expression");
- SubExprs[SubExpr::Common] = Common;
- SubExprs[SubExpr::Ready] = nullptr;
- SubExprs[SubExpr::Suspend] = nullptr;
- SubExprs[SubExpr::Resume] = nullptr;
- }
- CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
- SubExprs[SubExpr::Common] = nullptr;
- SubExprs[SubExpr::Ready] = nullptr;
- SubExprs[SubExpr::Suspend] = nullptr;
- SubExprs[SubExpr::Resume] = nullptr;
- }
-
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
- Expr *getCommonExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Common]);
- }
-
- Expr *getReadyExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Ready]);
- }
- Expr *getSuspendExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Suspend]);
- }
- Expr *getResumeExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Resume]);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return KeywordLoc;
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getCommonExpr()->getLocEnd();
- }
-
- child_range children() {
- return child_range(SubExprs, SubExprs + SubExpr::Count);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoawaitExprClass ||
- T->getStmtClass() == CoyieldExprClass;
- }
-};
-
-/// \brief Represents a 'co_await' expression.
-class CoawaitExpr : public CoroutineSuspendExpr {
- friend class ASTStmtReader;
-public:
- CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready,
- Suspend, Resume) {}
- CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {}
- CoawaitExpr(EmptyShell Empty)
- : CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
-
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoawaitExprClass;
- }
-};
-
-/// \brief Represents a 'co_yield' expression.
-class CoyieldExpr : public CoroutineSuspendExpr {
- friend class ASTStmtReader;
-public:
- CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready,
- Suspend, Resume) {}
- CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {}
- CoyieldExpr(EmptyShell Empty)
- : CoroutineSuspendExpr(CoyieldExprClass, Empty) {}
-
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoyieldExprClass;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
deleted file mode 100644
index 61e6383..0000000
--- a/include/clang/AST/ExprObjC.h
+++ /dev/null
@@ -1,1568 +0,0 @@
-//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ExprObjC interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPROBJC_H
-#define LLVM_CLANG_AST_EXPROBJC_H
-
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/SelectorLocationsKind.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
- class IdentifierInfo;
- class ASTContext;
-
-/// ObjCStringLiteral, used for Objective-C string literals
-/// i.e. @"foo".
-class ObjCStringLiteral : public Expr {
- Stmt *String;
- SourceLocation AtLoc;
-public:
- ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
- : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- String(SL), AtLoc(L) {}
- explicit ObjCStringLiteral(EmptyShell Empty)
- : Expr(ObjCStringLiteralClass, Empty) {}
-
- StringLiteral *getString() { return cast<StringLiteral>(String); }
- const StringLiteral *getString() const { return cast<StringLiteral>(String); }
- void setString(StringLiteral *S) { String = S; }
-
- SourceLocation getAtLoc() const { return AtLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCStringLiteralClass;
- }
-
- // Iterators
- child_range children() { return child_range(&String, &String+1); }
-};
-
-/// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
-///
-class ObjCBoolLiteralExpr : public Expr {
- bool Value;
- SourceLocation Loc;
-public:
- ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
- Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
- false, false), Value(val), Loc(l) {}
-
- explicit ObjCBoolLiteralExpr(EmptyShell Empty)
- : Expr(ObjCBoolLiteralExprClass, Empty) { }
-
- bool getValue() const { return Value; }
- void setValue(bool V) { Value = V; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCBoolLiteralExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ObjCBoxedExpr - used for generalized expression boxing.
-/// as in: @(strdup("hello world")), @(random()) or @(view.frame)
-/// Also used for boxing non-parenthesized numeric literals;
-/// as in: @42 or \@true (c++/objc++) or \@__yes (c/objc).
-class ObjCBoxedExpr : public Expr {
- Stmt *SubExpr;
- ObjCMethodDecl *BoxingMethod;
- SourceRange Range;
-public:
- ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
- SourceRange R)
- : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
- E->isTypeDependent(), E->isValueDependent(),
- E->isInstantiationDependent(), E->containsUnexpandedParameterPack()),
- SubExpr(E), BoxingMethod(method), Range(R) {}
- explicit ObjCBoxedExpr(EmptyShell Empty)
- : Expr(ObjCBoxedExprClass, Empty) {}
-
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
-
- ObjCMethodDecl *getBoxingMethod() const {
- return BoxingMethod;
- }
-
- SourceLocation getAtLoc() const { return Range.getBegin(); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY {
- return Range;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCBoxedExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr+1); }
-
- typedef ConstExprIterator const_arg_iterator;
-
- const_arg_iterator arg_begin() const {
- return reinterpret_cast<Stmt const * const*>(&SubExpr);
- }
- const_arg_iterator arg_end() const {
- return reinterpret_cast<Stmt const * const*>(&SubExpr + 1);
- }
-
- friend class ASTStmtReader;
-};
-
-/// ObjCArrayLiteral - used for objective-c array containers; as in:
-/// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
-class ObjCArrayLiteral final
- : public Expr,
- private llvm::TrailingObjects<ObjCArrayLiteral, Expr *> {
- unsigned NumElements;
- SourceRange Range;
- ObjCMethodDecl *ArrayWithObjectsMethod;
-
- ObjCArrayLiteral(ArrayRef<Expr *> Elements,
- QualType T, ObjCMethodDecl * Method,
- SourceRange SR);
-
- explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
- : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
-
-public:
- static ObjCArrayLiteral *Create(const ASTContext &C,
- ArrayRef<Expr *> Elements,
- QualType T, ObjCMethodDecl * Method,
- SourceRange SR);
-
- static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
- unsigned NumElements);
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCArrayLiteralClass;
- }
-
- /// \brief Retrieve elements of array of literals.
- Expr **getElements() { return getTrailingObjects<Expr *>(); }
-
- /// \brief Retrieve elements of array of literals.
- const Expr * const *getElements() const {
- return getTrailingObjects<Expr *>();
- }
-
- /// getNumElements - Return number of elements of objective-c array literal.
- unsigned getNumElements() const { return NumElements; }
-
- /// getExpr - Return the Expr at the specified index.
- Expr *getElement(unsigned Index) {
- assert((Index < NumElements) && "Arg access out of range!");
- return cast<Expr>(getElements()[Index]);
- }
- const Expr *getElement(unsigned Index) const {
- assert((Index < NumElements) && "Arg access out of range!");
- return cast<Expr>(getElements()[Index]);
- }
-
- ObjCMethodDecl *getArrayWithObjectsMethod() const {
- return ArrayWithObjectsMethod;
- }
-
- // Iterators
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(getElements()),
- reinterpret_cast<Stmt **>(getElements()) + NumElements);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
-};
-
-/// \brief An element in an Objective-C dictionary literal.
-///
-struct ObjCDictionaryElement {
- /// \brief The key for the dictionary element.
- Expr *Key;
-
- /// \brief The value of the dictionary element.
- Expr *Value;
-
- /// \brief The location of the ellipsis, if this is a pack expansion.
- SourceLocation EllipsisLoc;
-
- /// \brief The number of elements this pack expansion will expand to, if
- /// this is a pack expansion and is known.
- Optional<unsigned> NumExpansions;
-
- /// \brief Determines whether this dictionary element is a pack expansion.
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-};
-} // end namespace clang
-
-namespace llvm {
-template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
-}
-
-namespace clang {
-/// \brief Internal struct for storing Key/value pair.
-struct ObjCDictionaryLiteral_KeyValuePair {
- Expr *Key;
- Expr *Value;
-};
-
-/// \brief Internal struct to describes an element that is a pack
-/// expansion, used if any of the elements in the dictionary literal
-/// are pack expansions.
-struct ObjCDictionaryLiteral_ExpansionData {
- /// \brief The location of the ellipsis, if this element is a pack
- /// expansion.
- SourceLocation EllipsisLoc;
-
- /// \brief If non-zero, the number of elements that this pack
- /// expansion will expand to (+1).
- unsigned NumExpansionsPlusOne;
-};
-
-/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary
-/// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] };
-class ObjCDictionaryLiteral final
- : public Expr,
- private llvm::TrailingObjects<ObjCDictionaryLiteral,
- ObjCDictionaryLiteral_KeyValuePair,
- ObjCDictionaryLiteral_ExpansionData> {
- /// \brief The number of elements in this dictionary literal.
- unsigned NumElements : 31;
-
- /// \brief Determine whether this dictionary literal has any pack expansions.
- ///
- /// If the dictionary literal has pack expansions, then there will
- /// be an array of pack expansion data following the array of
- /// key/value pairs, which provide the locations of the ellipses (if
- /// any) and number of elements in the expansion (if known). If
- /// there are no pack expansions, we optimize away this storage.
- unsigned HasPackExpansions : 1;
-
- SourceRange Range;
- ObjCMethodDecl *DictWithObjectsMethod;
-
- typedef ObjCDictionaryLiteral_KeyValuePair KeyValuePair;
- typedef ObjCDictionaryLiteral_ExpansionData ExpansionData;
-
- size_t numTrailingObjects(OverloadToken<KeyValuePair>) const {
- return NumElements;
- }
-
- ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK,
- bool HasPackExpansions,
- QualType T, ObjCMethodDecl *method,
- SourceRange SR);
-
- explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
- bool HasPackExpansions)
- : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
- HasPackExpansions(HasPackExpansions) {}
-
-public:
- static ObjCDictionaryLiteral *Create(const ASTContext &C,
- ArrayRef<ObjCDictionaryElement> VK,
- bool HasPackExpansions,
- QualType T, ObjCMethodDecl *method,
- SourceRange SR);
-
- static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C,
- unsigned NumElements,
- bool HasPackExpansions);
-
- /// getNumElements - Return number of elements of objective-c dictionary
- /// literal.
- unsigned getNumElements() const { return NumElements; }
-
- ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
- assert((Index < NumElements) && "Arg access out of range!");
- const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index];
- ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
- if (HasPackExpansions) {
- const ExpansionData &Expansion =
- getTrailingObjects<ExpansionData>()[Index];
- Result.EllipsisLoc = Expansion.EllipsisLoc;
- if (Expansion.NumExpansionsPlusOne > 0)
- Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
- }
- return Result;
- }
-
- ObjCMethodDecl *getDictWithObjectsMethod() const
- { return DictWithObjectsMethod; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCDictionaryLiteralClass;
- }
-
- // Iterators
- child_range children() {
- // Note: we're taking advantage of the layout of the KeyValuePair struct
- // here. If that struct changes, this code will need to change as well.
- static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2,
- "KeyValuePair is expected size");
- return child_range(
- reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()),
- reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) +
- NumElements * 2);
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
-};
-
-
-/// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same
-/// type and behavior as StringLiteral except that the string initializer is
-/// obtained from ASTContext with the encoding type as an argument.
-class ObjCEncodeExpr : public Expr {
- TypeSourceInfo *EncodedType;
- SourceLocation AtLoc, RParenLoc;
-public:
- ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
- SourceLocation at, SourceLocation rp)
- : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
- EncodedType->getType()->isDependentType(),
- EncodedType->getType()->isDependentType(),
- EncodedType->getType()->isInstantiationDependentType(),
- EncodedType->getType()->containsUnexpandedParameterPack()),
- EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
-
- explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
-
-
- SourceLocation getAtLoc() const { return AtLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- QualType getEncodedType() const { return EncodedType->getType(); }
-
- TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
- void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
- EncodedType = EncType;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCEncodeExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ObjCSelectorExpr used for \@selector in Objective-C.
-class ObjCSelectorExpr : public Expr {
- Selector SelName;
- SourceLocation AtLoc, RParenLoc;
-public:
- ObjCSelectorExpr(QualType T, Selector selInfo,
- SourceLocation at, SourceLocation rp)
- : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- SelName(selInfo), AtLoc(at), RParenLoc(rp){}
- explicit ObjCSelectorExpr(EmptyShell Empty)
- : Expr(ObjCSelectorExprClass, Empty) {}
-
- Selector getSelector() const { return SelName; }
- void setSelector(Selector S) { SelName = S; }
-
- SourceLocation getAtLoc() const { return AtLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- /// getNumArgs - Return the number of actual arguments to this call.
- unsigned getNumArgs() const { return SelName.getNumArgs(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCSelectorExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// ObjCProtocolExpr used for protocol expression in Objective-C.
-///
-/// This is used as: \@protocol(foo), as in:
-/// \code
-/// [obj conformsToProtocol:@protocol(foo)]
-/// \endcode
-///
-/// The return type is "Protocol*".
-class ObjCProtocolExpr : public Expr {
- ObjCProtocolDecl *TheProtocol;
- SourceLocation AtLoc, ProtoLoc, RParenLoc;
-public:
- ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
- SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
- : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
- false, false),
- TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
- explicit ObjCProtocolExpr(EmptyShell Empty)
- : Expr(ObjCProtocolExprClass, Empty) {}
-
- ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
- void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
-
- SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
- SourceLocation getAtLoc() const { return AtLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setAtLoc(SourceLocation L) { AtLoc = L; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCProtocolExprClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
-class ObjCIvarRefExpr : public Expr {
- ObjCIvarDecl *D;
- Stmt *Base;
- SourceLocation Loc;
- /// OpLoc - This is the location of '.' or '->'
- SourceLocation OpLoc;
-
- bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
- bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
-
-public:
- ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
- SourceLocation l, SourceLocation oploc,
- Expr *base,
- bool arrow = false, bool freeIvar = false) :
- Expr(ObjCIvarRefExprClass, t, VK_LValue,
- d->isBitField() ? OK_BitField : OK_Ordinary,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- D(d), Base(base), Loc(l), OpLoc(oploc),
- IsArrow(arrow), IsFreeIvar(freeIvar) {}
-
- explicit ObjCIvarRefExpr(EmptyShell Empty)
- : Expr(ObjCIvarRefExprClass, Empty) {}
-
- ObjCIvarDecl *getDecl() { return D; }
- const ObjCIvarDecl *getDecl() const { return D; }
- void setDecl(ObjCIvarDecl *d) { D = d; }
-
- const Expr *getBase() const { return cast<Expr>(Base); }
- Expr *getBase() { return cast<Expr>(Base); }
- void setBase(Expr * base) { Base = base; }
-
- bool isArrow() const { return IsArrow; }
- bool isFreeIvar() const { return IsFreeIvar; }
- void setIsArrow(bool A) { IsArrow = A; }
- void setIsFreeIvar(bool A) { IsFreeIvar = A; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return isFreeIvar() ? Loc : getBase()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
-
- SourceLocation getOpLoc() const { return OpLoc; }
- void setOpLoc(SourceLocation L) { OpLoc = L; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCIvarRefExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
-};
-
-/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
-/// property.
-class ObjCPropertyRefExpr : public Expr {
-private:
- /// If the bool is true, this is an implicit property reference; the
- /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
- /// if the bool is false, this is an explicit property reference;
- /// the pointer is an ObjCPropertyDecl and Setter is always null.
- llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
-
- /// \brief Indicates whether the property reference will result in a message
- /// to the getter, the setter, or both.
- /// This applies to both implicit and explicit property references.
- enum MethodRefFlags {
- MethodRef_None = 0,
- MethodRef_Getter = 0x1,
- MethodRef_Setter = 0x2
- };
-
- /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
- llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
-
- // FIXME: Maybe we should store the property identifier here,
- // because it's not rederivable from the other data when there's an
- // implicit property with no getter (because the 'foo' -> 'setFoo:'
- // transformation is lossy on the first character).
-
- SourceLocation IdLoc;
-
- /// \brief When the receiver in property access is 'super', this is
- /// the location of the 'super' keyword. When it's an interface,
- /// this is that interface.
- SourceLocation ReceiverLoc;
- llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
-
-public:
- ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation l, Expr *base)
- : Expr(ObjCPropertyRefExprClass, t, VK, OK,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- base->containsUnexpandedParameterPack()),
- PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
- IdLoc(l), ReceiverLoc(), Receiver(base) {
- assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation l, SourceLocation sl, QualType st)
- : Expr(ObjCPropertyRefExprClass, t, VK, OK,
- /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
- st->containsUnexpandedParameterPack()),
- PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
- IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
- assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
- QualType T, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation IdLoc, Expr *Base)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
- Base->isValueDependent(), Base->isInstantiationDependent(),
- Base->containsUnexpandedParameterPack()),
- PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
- IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
- assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
- QualType T, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation IdLoc,
- SourceLocation SuperLoc, QualType SuperTy)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
- PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
- IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
- assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
- QualType T, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation IdLoc,
- SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
- : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
- PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
- IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
- assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
- }
-
- explicit ObjCPropertyRefExpr(EmptyShell Empty)
- : Expr(ObjCPropertyRefExprClass, Empty) {}
-
- bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
- bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
-
- ObjCPropertyDecl *getExplicitProperty() const {
- assert(!isImplicitProperty());
- return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
- }
-
- ObjCMethodDecl *getImplicitPropertyGetter() const {
- assert(isImplicitProperty());
- return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
- }
-
- ObjCMethodDecl *getImplicitPropertySetter() const {
- assert(isImplicitProperty());
- return SetterAndMethodRefFlags.getPointer();
- }
-
- Selector getGetterSelector() const {
- if (isImplicitProperty())
- return getImplicitPropertyGetter()->getSelector();
- return getExplicitProperty()->getGetterName();
- }
-
- Selector getSetterSelector() const {
- if (isImplicitProperty())
- return getImplicitPropertySetter()->getSelector();
- return getExplicitProperty()->getSetterName();
- }
-
- /// \brief True if the property reference will result in a message to the
- /// getter.
- /// This applies to both implicit and explicit property references.
- bool isMessagingGetter() const {
- return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
- }
-
- /// \brief True if the property reference will result in a message to the
- /// setter.
- /// This applies to both implicit and explicit property references.
- bool isMessagingSetter() const {
- return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
- }
-
- void setIsMessagingGetter(bool val = true) {
- setMethodRefFlag(MethodRef_Getter, val);
- }
-
- void setIsMessagingSetter(bool val = true) {
- setMethodRefFlag(MethodRef_Setter, val);
- }
-
- const Expr *getBase() const {
- return cast<Expr>(Receiver.get<Stmt*>());
- }
- Expr *getBase() {
- return cast<Expr>(Receiver.get<Stmt*>());
- }
-
- SourceLocation getLocation() const { return IdLoc; }
-
- SourceLocation getReceiverLocation() const { return ReceiverLoc; }
- QualType getSuperReceiverType() const {
- return QualType(Receiver.get<const Type*>(), 0);
- }
-
- ObjCInterfaceDecl *getClassReceiver() const {
- return Receiver.get<ObjCInterfaceDecl*>();
- }
- bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
- bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
- bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
-
- /// Determine the type of the base, regardless of the kind of receiver.
- QualType getReceiverType(const ASTContext &ctx) const;
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCPropertyRefExprClass;
- }
-
- // Iterators
- child_range children() {
- if (Receiver.is<Stmt*>()) {
- Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
- return child_range(begin, begin+1);
- }
- return child_range(child_iterator(), child_iterator());
- }
-
-private:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
- PropertyOrGetter.setPointer(D);
- PropertyOrGetter.setInt(false);
- SetterAndMethodRefFlags.setPointer(nullptr);
- SetterAndMethodRefFlags.setInt(methRefFlags);
- }
- void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
- unsigned methRefFlags) {
- PropertyOrGetter.setPointer(Getter);
- PropertyOrGetter.setInt(true);
- SetterAndMethodRefFlags.setPointer(Setter);
- SetterAndMethodRefFlags.setInt(methRefFlags);
- }
- void setBase(Expr *Base) { Receiver = Base; }
- void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
- void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
-
- void setLocation(SourceLocation L) { IdLoc = L; }
- void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
-
- void setMethodRefFlag(MethodRefFlags flag, bool val) {
- unsigned f = SetterAndMethodRefFlags.getInt();
- if (val)
- f |= flag;
- else
- f &= ~flag;
- SetterAndMethodRefFlags.setInt(f);
- }
-};
-
-/// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
-/// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
-///
-class ObjCSubscriptRefExpr : public Expr {
- // Location of ']' in an indexing expression.
- SourceLocation RBracket;
- // array/dictionary base expression.
- // for arrays, this is a numeric expression. For dictionaries, this is
- // an objective-c object pointer expression.
- enum { BASE, KEY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
-
- ObjCMethodDecl *GetAtIndexMethodDecl;
-
- // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
- // an indexed object this is null too.
- ObjCMethodDecl *SetAtIndexMethodDecl;
-
-public:
-
- ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
- ExprValueKind VK, ExprObjectKind OK,
- ObjCMethodDecl *getMethod,
- ObjCMethodDecl *setMethod, SourceLocation RB)
- : Expr(ObjCSubscriptRefExprClass, T, VK, OK,
- base->isTypeDependent() || key->isTypeDependent(),
- base->isValueDependent() || key->isValueDependent(),
- base->isInstantiationDependent() || key->isInstantiationDependent(),
- (base->containsUnexpandedParameterPack() ||
- key->containsUnexpandedParameterPack())),
- RBracket(RB),
- GetAtIndexMethodDecl(getMethod),
- SetAtIndexMethodDecl(setMethod)
- {SubExprs[BASE] = base; SubExprs[KEY] = key;}
-
- explicit ObjCSubscriptRefExpr(EmptyShell Empty)
- : Expr(ObjCSubscriptRefExprClass, Empty) {}
-
- SourceLocation getRBracket() const { return RBracket; }
- void setRBracket(SourceLocation RB) { RBracket = RB; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return SubExprs[BASE]->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCSubscriptRefExprClass;
- }
-
- Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
- void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
-
- Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
- void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
-
- ObjCMethodDecl *getAtIndexMethodDecl() const {
- return GetAtIndexMethodDecl;
- }
-
- ObjCMethodDecl *setAtIndexMethodDecl() const {
- return SetAtIndexMethodDecl;
- }
-
- bool isArraySubscriptRefExpr() const {
- return getKeyExpr()->getType()->isIntegralOrEnumerationType();
- }
-
- child_range children() {
- return child_range(SubExprs, SubExprs+END_EXPR);
- }
-private:
- friend class ASTStmtReader;
-};
-
-
-/// \brief An expression that sends a message to the given Objective-C
-/// object or class.
-///
-/// The following contains two message send expressions:
-///
-/// \code
-/// [[NSString alloc] initWithString:@"Hello"]
-/// \endcode
-///
-/// The innermost message send invokes the "alloc" class method on the
-/// NSString class, while the outermost message send invokes the
-/// "initWithString" instance method on the object returned from
-/// NSString's "alloc". In all, an Objective-C message send can take
-/// on four different (although related) forms:
-///
-/// 1. Send to an object instance.
-/// 2. Send to a class.
-/// 3. Send to the superclass instance of the current class.
-/// 4. Send to the superclass of the current class.
-///
-/// All four kinds of message sends are modeled by the ObjCMessageExpr
-/// class, and can be distinguished via \c getReceiverKind(). Example:
-///
-/// The "void *" trailing objects are actually ONE void * (the
-/// receiver pointer), and NumArgs Expr *. But due to the
-/// implementation of children(), these must be together contiguously.
-
-class ObjCMessageExpr final
- : public Expr,
- private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
- /// \brief Stores either the selector that this message is sending
- /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
- /// referring to the method that we type-checked against.
- uintptr_t SelectorOrMethod;
-
- enum { NumArgsBitWidth = 16 };
-
- /// \brief The number of arguments in the message send, not
- /// including the receiver.
- unsigned NumArgs : NumArgsBitWidth;
-
- /// \brief The kind of message send this is, which is one of the
- /// ReceiverKind values.
- ///
- /// We pad this out to a byte to avoid excessive masking and shifting.
- unsigned Kind : 8;
-
- /// \brief Whether we have an actual method prototype in \c
- /// SelectorOrMethod.
- ///
- /// When non-zero, we have a method declaration; otherwise, we just
- /// have a selector.
- unsigned HasMethod : 1;
-
- /// \brief Whether this message send is a "delegate init call",
- /// i.e. a call of an init method on self from within an init method.
- unsigned IsDelegateInitCall : 1;
-
- /// \brief Whether this message send was implicitly generated by
- /// the implementation rather than explicitly written by the user.
- unsigned IsImplicit : 1;
-
- /// \brief Whether the locations of the selector identifiers are in a
- /// "standard" position, a enum SelectorLocationsKind.
- unsigned SelLocsKind : 2;
-
- /// \brief When the message expression is a send to 'super', this is
- /// the location of the 'super' keyword.
- SourceLocation SuperLoc;
-
- /// \brief The source locations of the open and close square
- /// brackets ('[' and ']', respectively).
- SourceLocation LBracLoc, RBracLoc;
-
- size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; }
-
- void setNumArgs(unsigned Num) {
- assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
- NumArgs = Num;
- }
-
- ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0),
- HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
- setNumArgs(NumArgs);
- }
-
- ObjCMessageExpr(QualType T, ExprValueKind VK,
- SourceLocation LBracLoc,
- SourceLocation SuperLoc,
- bool IsInstanceSuper,
- QualType SuperType,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
- ObjCMessageExpr(QualType T, ExprValueKind VK,
- SourceLocation LBracLoc,
- TypeSourceInfo *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
- ObjCMessageExpr(QualType T, ExprValueKind VK,
- SourceLocation LBracLoc,
- Expr *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
-
- void initArgsAndSelLocs(ArrayRef<Expr *> Args,
- ArrayRef<SourceLocation> SelLocs,
- SelectorLocationsKind SelLocsK);
-
- /// \brief Retrieve the pointer value of the message receiver.
- void *getReceiverPointer() const { return *getTrailingObjects<void *>(); }
-
- /// \brief Set the pointer value of the message receiver.
- void setReceiverPointer(void *Value) {
- *getTrailingObjects<void *>() = Value;
- }
-
- SelectorLocationsKind getSelLocsKind() const {
- return (SelectorLocationsKind)SelLocsKind;
- }
- bool hasStandardSelLocs() const {
- return getSelLocsKind() != SelLoc_NonStandard;
- }
-
- /// \brief Get a pointer to the stored selector identifiers locations array.
- /// No locations will be stored if HasStandardSelLocs is true.
- SourceLocation *getStoredSelLocs() {
- return getTrailingObjects<SourceLocation>();
- }
- const SourceLocation *getStoredSelLocs() const {
- return getTrailingObjects<SourceLocation>();
- }
-
- /// \brief Get the number of stored selector identifiers locations.
- /// No locations will be stored if HasStandardSelLocs is true.
- unsigned getNumStoredSelLocs() const {
- if (hasStandardSelLocs())
- return 0;
- return getNumSelectorLocs();
- }
-
- static ObjCMessageExpr *alloc(const ASTContext &C,
- ArrayRef<Expr *> Args,
- SourceLocation RBraceLoc,
- ArrayRef<SourceLocation> SelLocs,
- Selector Sel,
- SelectorLocationsKind &SelLocsK);
- static ObjCMessageExpr *alloc(const ASTContext &C,
- unsigned NumArgs,
- unsigned NumStoredSelLocs);
-
-public:
- /// \brief The kind of receiver this message is sending to.
- enum ReceiverKind {
- /// \brief The receiver is a class.
- Class = 0,
- /// \brief The receiver is an object instance.
- Instance,
- /// \brief The receiver is a superclass.
- SuperClass,
- /// \brief The receiver is the instance of the superclass object.
- SuperInstance
- };
-
- /// \brief Create a message send to super.
- ///
- /// \param Context The ASTContext in which this expression will be created.
- ///
- /// \param T The result type of this message.
- ///
- /// \param VK The value kind of this message. A message returning
- /// a l-value or r-value reference will be an l-value or x-value,
- /// respectively.
- ///
- /// \param LBracLoc The location of the open square bracket '['.
- ///
- /// \param SuperLoc The location of the "super" keyword.
- ///
- /// \param IsInstanceSuper Whether this is an instance "super"
- /// message (otherwise, it's a class "super" message).
- ///
- /// \param Sel The selector used to determine which method gets called.
- ///
- /// \param Method The Objective-C method against which this message
- /// send was type-checked. May be NULL.
- ///
- /// \param Args The message send arguments.
- ///
- /// \param RBracLoc The location of the closing square bracket ']'.
- static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- SourceLocation SuperLoc,
- bool IsInstanceSuper,
- QualType SuperType,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
-
- /// \brief Create a class message send.
- ///
- /// \param Context The ASTContext in which this expression will be created.
- ///
- /// \param T The result type of this message.
- ///
- /// \param VK The value kind of this message. A message returning
- /// a l-value or r-value reference will be an l-value or x-value,
- /// respectively.
- ///
- /// \param LBracLoc The location of the open square bracket '['.
- ///
- /// \param Receiver The type of the receiver, including
- /// source-location information.
- ///
- /// \param Sel The selector used to determine which method gets called.
- ///
- /// \param Method The Objective-C method against which this message
- /// send was type-checked. May be NULL.
- ///
- /// \param Args The message send arguments.
- ///
- /// \param RBracLoc The location of the closing square bracket ']'.
- static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- TypeSourceInfo *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
-
- /// \brief Create an instance message send.
- ///
- /// \param Context The ASTContext in which this expression will be created.
- ///
- /// \param T The result type of this message.
- ///
- /// \param VK The value kind of this message. A message returning
- /// a l-value or r-value reference will be an l-value or x-value,
- /// respectively.
- ///
- /// \param LBracLoc The location of the open square bracket '['.
- ///
- /// \param Receiver The expression used to produce the object that
- /// will receive this message.
- ///
- /// \param Sel The selector used to determine which method gets called.
- ///
- /// \param Method The Objective-C method against which this message
- /// send was type-checked. May be NULL.
- ///
- /// \param Args The message send arguments.
- ///
- /// \param RBracLoc The location of the closing square bracket ']'.
- static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK,
- SourceLocation LBracLoc,
- Expr *Receiver,
- Selector Sel,
- ArrayRef<SourceLocation> SeLocs,
- ObjCMethodDecl *Method,
- ArrayRef<Expr *> Args,
- SourceLocation RBracLoc,
- bool isImplicit);
-
- /// \brief Create an empty Objective-C message expression, to be
- /// filled in by subsequent calls.
- ///
- /// \param Context The context in which the message send will be created.
- ///
- /// \param NumArgs The number of message arguments, not including
- /// the receiver.
- static ObjCMessageExpr *CreateEmpty(const ASTContext &Context,
- unsigned NumArgs,
- unsigned NumStoredSelLocs);
-
- /// \brief Indicates whether the message send was implicitly
- /// generated by the implementation. If false, it was written explicitly
- /// in the source code.
- bool isImplicit() const { return IsImplicit; }
-
- /// \brief Determine the kind of receiver that this message is being
- /// sent to.
- ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
-
- /// \brief Source range of the receiver.
- SourceRange getReceiverRange() const;
-
- /// \brief Determine whether this is an instance message to either a
- /// computed object or to super.
- bool isInstanceMessage() const {
- return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
- }
-
- /// \brief Determine whether this is an class message to either a
- /// specified class or to super.
- bool isClassMessage() const {
- return getReceiverKind() == Class || getReceiverKind() == SuperClass;
- }
-
- /// \brief Returns the object expression (receiver) for an instance message,
- /// or null for a message that is not an instance message.
- Expr *getInstanceReceiver() {
- if (getReceiverKind() == Instance)
- return static_cast<Expr *>(getReceiverPointer());
-
- return nullptr;
- }
- const Expr *getInstanceReceiver() const {
- return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
- }
-
- /// \brief Turn this message send into an instance message that
- /// computes the receiver object with the given expression.
- void setInstanceReceiver(Expr *rec) {
- Kind = Instance;
- setReceiverPointer(rec);
- }
-
- /// \brief Returns the type of a class message send, or NULL if the
- /// message is not a class message.
- QualType getClassReceiver() const {
- if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
- return TSInfo->getType();
-
- return QualType();
- }
-
- /// \brief Returns a type-source information of a class message
- /// send, or NULL if the message is not a class message.
- TypeSourceInfo *getClassReceiverTypeInfo() const {
- if (getReceiverKind() == Class)
- return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
- return nullptr;
- }
-
- void setClassReceiver(TypeSourceInfo *TSInfo) {
- Kind = Class;
- setReceiverPointer(TSInfo);
- }
-
- /// \brief Retrieve the location of the 'super' keyword for a class
- /// or instance message to 'super', otherwise an invalid source location.
- SourceLocation getSuperLoc() const {
- if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
- return SuperLoc;
-
- return SourceLocation();
- }
-
- /// \brief Retrieve the receiver type to which this message is being directed.
- ///
- /// This routine cross-cuts all of the different kinds of message
- /// sends to determine what the underlying (statically known) type
- /// of the receiver will be; use \c getReceiverKind() to determine
- /// whether the message is a class or an instance method, whether it
- /// is a send to super or not, etc.
- ///
- /// \returns The type of the receiver.
- QualType getReceiverType() const;
-
- /// \brief Retrieve the Objective-C interface to which this message
- /// is being directed, if known.
- ///
- /// This routine cross-cuts all of the different kinds of message
- /// sends to determine what the underlying (statically known) type
- /// of the receiver will be; use \c getReceiverKind() to determine
- /// whether the message is a class or an instance method, whether it
- /// is a send to super or not, etc.
- ///
- /// \returns The Objective-C interface if known, otherwise NULL.
- ObjCInterfaceDecl *getReceiverInterface() const;
-
- /// \brief Retrieve the type referred to by 'super'.
- ///
- /// The returned type will either be an ObjCInterfaceType (for an
- /// class message to super) or an ObjCObjectPointerType that refers
- /// to a class (for an instance message to super);
- QualType getSuperType() const {
- if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
- return QualType::getFromOpaquePtr(getReceiverPointer());
-
- return QualType();
- }
-
- void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
- Kind = IsInstanceSuper? SuperInstance : SuperClass;
- SuperLoc = Loc;
- setReceiverPointer(T.getAsOpaquePtr());
- }
-
- Selector getSelector() const;
-
- void setSelector(Selector S) {
- HasMethod = false;
- SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
- }
-
- const ObjCMethodDecl *getMethodDecl() const {
- if (HasMethod)
- return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
-
- return nullptr;
- }
-
- ObjCMethodDecl *getMethodDecl() {
- if (HasMethod)
- return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
-
- return nullptr;
- }
-
- void setMethodDecl(ObjCMethodDecl *MD) {
- HasMethod = true;
- SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
- }
-
- ObjCMethodFamily getMethodFamily() const {
- if (HasMethod) return getMethodDecl()->getMethodFamily();
- return getSelector().getMethodFamily();
- }
-
- /// \brief Return the number of actual arguments in this message,
- /// not counting the receiver.
- unsigned getNumArgs() const { return NumArgs; }
-
- /// \brief Retrieve the arguments to this message, not including the
- /// receiver.
- Expr **getArgs() {
- return reinterpret_cast<Expr **>(getTrailingObjects<void *>() + 1);
- }
- const Expr * const *getArgs() const {
- return reinterpret_cast<const Expr *const *>(getTrailingObjects<void *>() +
- 1);
- }
-
- /// getArg - Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < NumArgs && "Arg access out of range!");
- return getArgs()[Arg];
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return getArgs()[Arg];
- }
- /// setArg - Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < NumArgs && "Arg access out of range!");
- getArgs()[Arg] = ArgExpr;
- }
-
- /// isDelegateInitCall - Answers whether this message send has been
- /// tagged as a "delegate init call", i.e. a call to a method in the
- /// -init family on self from within an -init method implementation.
- bool isDelegateInitCall() const { return IsDelegateInitCall; }
- void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
-
- SourceLocation getLeftLoc() const { return LBracLoc; }
- SourceLocation getRightLoc() const { return RBracLoc; }
-
- SourceLocation getSelectorStartLoc() const {
- if (isImplicit())
- return getLocStart();
- return getSelectorLoc(0);
- }
- SourceLocation getSelectorLoc(unsigned Index) const {
- assert(Index < getNumSelectorLocs() && "Index out of range!");
- if (hasStandardSelLocs())
- return getStandardSelectorLoc(Index, getSelector(),
- getSelLocsKind() == SelLoc_StandardWithSpace,
- llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
- getNumArgs()),
- RBracLoc);
- return getStoredSelLocs()[Index];
- }
-
- void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
-
- unsigned getNumSelectorLocs() const {
- if (isImplicit())
- return 0;
- Selector Sel = getSelector();
- if (Sel.isUnarySelector())
- return 1;
- return Sel.getNumArgs();
- }
-
- void setSourceRange(SourceRange R) {
- LBracLoc = R.getBegin();
- RBracLoc = R.getEnd();
- }
- SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCMessageExprClass;
- }
-
- // Iterators
- child_range children();
-
- typedef ExprIterator arg_iterator;
- typedef ConstExprIterator const_arg_iterator;
-
- llvm::iterator_range<arg_iterator> arguments() {
- return llvm::make_range(arg_begin(), arg_end());
- }
-
- llvm::iterator_range<const_arg_iterator> arguments() const {
- return llvm::make_range(arg_begin(), arg_end());
- }
-
- arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
- arg_iterator arg_end() {
- return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
- }
- const_arg_iterator arg_begin() const {
- return reinterpret_cast<Stmt const * const*>(getArgs());
- }
- const_arg_iterator arg_end() const {
- return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
- }
-
- friend TrailingObjects;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
-/// (similar in spirit to MemberExpr).
-class ObjCIsaExpr : public Expr {
- /// Base - the expression for the base object pointer.
- Stmt *Base;
-
- /// IsaMemberLoc - This is the location of the 'isa'.
- SourceLocation IsaMemberLoc;
-
- /// OpLoc - This is the location of '.' or '->'
- SourceLocation OpLoc;
-
- /// IsArrow - True if this is "X->F", false if this is "X.F".
- bool IsArrow;
-public:
- ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
- QualType ty)
- : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
- /*TypeDependent=*/false, base->isValueDependent(),
- base->isInstantiationDependent(),
- /*ContainsUnexpandedParameterPack=*/false),
- Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
-
- /// \brief Build an empty expression.
- explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
-
- void setBase(Expr *E) { Base = E; }
- Expr *getBase() const { return cast<Expr>(Base); }
-
- bool isArrow() const { return IsArrow; }
- void setArrow(bool A) { IsArrow = A; }
-
- /// getMemberLoc - Return the location of the "member", in X->F, it is the
- /// location of 'F'.
- SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
- void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
-
- SourceLocation getOpLoc() const { return OpLoc; }
- void setOpLoc(SourceLocation L) { OpLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
- }
-
- SourceLocation getBaseLocEnd() const LLVM_READONLY {
- return getBase()->getLocEnd();
- }
-
- SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; }
-
- SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCIsaExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Base, &Base+1); }
-};
-
-
-/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
-/// argument by indirect copy-restore in ARC. This is used to support
-/// passing indirect arguments with the wrong lifetime, e.g. when
-/// passing the address of a __strong local variable to an 'out'
-/// parameter. This expression kind is only valid in an "argument"
-/// position to some sort of call expression.
-///
-/// The parameter must have type 'pointer to T', and the argument must
-/// have type 'pointer to U', where T and U agree except possibly in
-/// qualification. If the argument value is null, then a null pointer
-/// is passed; otherwise it points to an object A, and:
-/// 1. A temporary object B of type T is initialized, either by
-/// zero-initialization (used when initializing an 'out' parameter)
-/// or copy-initialization (used when initializing an 'inout'
-/// parameter).
-/// 2. The address of the temporary is passed to the function.
-/// 3. If the call completes normally, A is move-assigned from B.
-/// 4. Finally, A is destroyed immediately.
-///
-/// Currently 'T' must be a retainable object lifetime and must be
-/// __autoreleasing; this qualifier is ignored when initializing
-/// the value.
-class ObjCIndirectCopyRestoreExpr : public Expr {
- Stmt *Operand;
-
- // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
-
- friend class ASTReader;
- friend class ASTStmtReader;
-
- void setShouldCopy(bool shouldCopy) {
- ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
- }
-
- explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
- : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
-
-public:
- ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
- : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
- operand->isTypeDependent(), operand->isValueDependent(),
- operand->isInstantiationDependent(),
- operand->containsUnexpandedParameterPack()),
- Operand(operand) {
- setShouldCopy(shouldCopy);
- }
-
- Expr *getSubExpr() { return cast<Expr>(Operand); }
- const Expr *getSubExpr() const { return cast<Expr>(Operand); }
-
- /// shouldCopy - True if we should do the 'copy' part of the
- /// copy-restore. If false, the temporary will be zero-initialized.
- bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
-
- child_range children() { return child_range(&Operand, &Operand+1); }
-
- // Source locations are determined by the subexpression.
- SourceLocation getLocStart() const LLVM_READONLY {
- return Operand->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();}
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getSubExpr()->getExprLoc();
- }
-
- static bool classof(const Stmt *s) {
- return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
- }
-};
-
-/// \brief An Objective-C "bridged" cast expression, which casts between
-/// Objective-C pointers and C pointers, transferring ownership in the process.
-///
-/// \code
-/// NSString *str = (__bridge_transfer NSString *)CFCreateString();
-/// \endcode
-class ObjCBridgedCastExpr final
- : public ExplicitCastExpr,
- private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> {
- SourceLocation LParenLoc;
- SourceLocation BridgeKeywordLoc;
- unsigned Kind : 2;
-
- friend TrailingObjects;
- friend class CastExpr;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
-public:
- ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
- CastKind CK, SourceLocation BridgeKeywordLoc,
- TypeSourceInfo *TSInfo, Expr *Operand)
- : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
- CK, Operand, 0, TSInfo),
- LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
-
- /// \brief Construct an empty Objective-C bridged cast.
- explicit ObjCBridgedCastExpr(EmptyShell Shell)
- : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
-
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Determine which kind of bridge is being performed via this cast.
- ObjCBridgeCastKind getBridgeKind() const {
- return static_cast<ObjCBridgeCastKind>(Kind);
- }
-
- /// \brief Retrieve the kind of bridge being performed as a string.
- StringRef getBridgeKindName() const;
-
- /// \brief The location of the bridge keyword.
- SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSubExpr()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCBridgedCastExprClass;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ExprOpenMP.h b/include/clang/AST/ExprOpenMP.h
deleted file mode 100644
index 2d71a3a..0000000
--- a/include/clang/AST/ExprOpenMP.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===--- ExprOpenMP.h - Classes for representing expressions ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Expr interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_EXPROPENMP_H
-#define LLVM_CLANG_AST_EXPROPENMP_H
-
-#include "clang/AST/Expr.h"
-
-namespace clang {
-/// \brief OpenMP 4.0 [2.4, Array Sections].
-/// To specify an array section in an OpenMP construct, array subscript
-/// expressions are extended with the following syntax:
-/// \code
-/// [ lower-bound : length ]
-/// [ lower-bound : ]
-/// [ : length ]
-/// [ : ]
-/// \endcode
-/// The array section must be a subset of the original array.
-/// Array sections are allowed on multidimensional arrays. Base language array
-/// subscript expressions can be used to specify length-one dimensions of
-/// multidimensional array sections.
-/// The lower-bound and length are integral type expressions. When evaluated
-/// they represent a set of integer values as follows:
-/// \code
-/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length -
-/// 1 }
-/// \endcode
-/// The lower-bound and length must evaluate to non-negative integers.
-/// When the size of the array dimension is not known, the length must be
-/// specified explicitly.
-/// When the length is absent, it defaults to the size of the array dimension
-/// minus the lower-bound.
-/// When the lower-bound is absent it defaults to 0.
-class OMPArraySectionExpr : public Expr {
- enum { BASE, LOWER_BOUND, LENGTH, END_EXPR };
- Stmt *SubExprs[END_EXPR];
- SourceLocation ColonLoc;
- SourceLocation RBracketLoc;
-
-public:
- OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type,
- ExprValueKind VK, ExprObjectKind OK,
- SourceLocation ColonLoc, SourceLocation RBracketLoc)
- : Expr(
- OMPArraySectionExprClass, Type, VK, OK,
- Base->isTypeDependent() ||
- (LowerBound && LowerBound->isTypeDependent()) ||
- (Length && Length->isTypeDependent()),
- Base->isValueDependent() ||
- (LowerBound && LowerBound->isValueDependent()) ||
- (Length && Length->isValueDependent()),
- Base->isInstantiationDependent() ||
- (LowerBound && LowerBound->isInstantiationDependent()) ||
- (Length && Length->isInstantiationDependent()),
- Base->containsUnexpandedParameterPack() ||
- (LowerBound && LowerBound->containsUnexpandedParameterPack()) ||
- (Length && Length->containsUnexpandedParameterPack())),
- ColonLoc(ColonLoc), RBracketLoc(RBracketLoc) {
- SubExprs[BASE] = Base;
- SubExprs[LOWER_BOUND] = LowerBound;
- SubExprs[LENGTH] = Length;
- }
-
- /// \brief Create an empty array section expression.
- explicit OMPArraySectionExpr(EmptyShell Shell)
- : Expr(OMPArraySectionExprClass, Shell) {}
-
- /// An array section can be written only as Base[LowerBound:Length].
-
- /// \brief Get base of the array section.
- Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
- const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
- /// \brief Set base of the array section.
- void setBase(Expr *E) { SubExprs[BASE] = E; }
-
- /// \brief Return original type of the base expression for array section.
- static QualType getBaseOriginalType(Expr *Base);
-
- /// \brief Get lower bound of array section.
- Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
- const Expr *getLowerBound() const {
- return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
- }
- /// \brief Set lower bound of the array section.
- void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
-
- /// \brief Get length of array section.
- Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
- const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
- /// \brief Set length of the array section.
- void setLength(Expr *E) { SubExprs[LENGTH] = E; }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBase()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
-
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
-
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
-
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getBase()->getExprLoc();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPArraySectionExprClass;
- }
-
- child_range children() {
- return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
- }
-};
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
deleted file mode 100644
index 81cf631..0000000
--- a/include/clang/AST/ExternalASTSource.h
+++ /dev/null
@@ -1,578 +0,0 @@
-//===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ExternalASTSource interface, which enables
-// construction of AST nodes from some external source.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
-#define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
-
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/DeclBase.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
-
-class ASTConsumer;
-class CXXBaseSpecifier;
-class CXXCtorInitializer;
-class DeclarationName;
-class ExternalSemaSource; // layering violation required for downcasting
-class FieldDecl;
-class Module;
-class NamedDecl;
-class RecordDecl;
-class Selector;
-class Stmt;
-class TagDecl;
-
-/// \brief Abstract interface for external sources of AST nodes.
-///
-/// External AST sources provide AST nodes constructed from some
-/// external source, such as a precompiled header. External AST
-/// sources can resolve types and declarations from abstract IDs into
-/// actual type and declaration nodes, and read parts of declaration
-/// contexts.
-class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
- /// Generation number for this external AST source. Must be increased
- /// whenever we might have added new redeclarations for existing decls.
- uint32_t CurrentGeneration;
-
- /// \brief Whether this AST source also provides information for
- /// semantic analysis.
- bool SemaSource;
-
- friend class ExternalSemaSource;
-
-public:
- ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
-
- virtual ~ExternalASTSource();
-
- /// \brief RAII class for safely pairing a StartedDeserializing call
- /// with FinishedDeserializing.
- class Deserializing {
- ExternalASTSource *Source;
- public:
- explicit Deserializing(ExternalASTSource *source) : Source(source) {
- assert(Source);
- Source->StartedDeserializing();
- }
- ~Deserializing() {
- Source->FinishedDeserializing();
- }
- };
-
- /// \brief Get the current generation of this AST source. This number
- /// is incremented each time the AST source lazily extends an existing
- /// entity.
- uint32_t getGeneration() const { return CurrentGeneration; }
-
- /// \brief Resolve a declaration ID into a declaration, potentially
- /// building a new declaration.
- ///
- /// This method only needs to be implemented if the AST source ever
- /// passes back decl sets as VisibleDeclaration objects.
- ///
- /// The default implementation of this method is a no-op.
- virtual Decl *GetExternalDecl(uint32_t ID);
-
- /// \brief Resolve a selector ID into a selector.
- ///
- /// This operation only needs to be implemented if the AST source
- /// returns non-zero for GetNumKnownSelectors().
- ///
- /// The default implementation of this method is a no-op.
- virtual Selector GetExternalSelector(uint32_t ID);
-
- /// \brief Returns the number of selectors known to the external AST
- /// source.
- ///
- /// The default implementation of this method is a no-op.
- virtual uint32_t GetNumExternalSelectors();
-
- /// \brief Resolve the offset of a statement in the decl stream into
- /// a statement.
- ///
- /// This operation is meant to be used via a LazyOffsetPtr. It only
- /// needs to be implemented if the AST source uses methods like
- /// FunctionDecl::setLazyBody when building decls.
- ///
- /// The default implementation of this method is a no-op.
- virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
-
- /// \brief Resolve the offset of a set of C++ constructor initializers in
- /// the decl stream into an array of initializers.
- ///
- /// The default implementation of this method is a no-op.
- virtual CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset);
-
- /// \brief Resolve the offset of a set of C++ base specifiers in the decl
- /// stream into an array of specifiers.
- ///
- /// The default implementation of this method is a no-op.
- virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
-
- /// \brief Update an out-of-date identifier.
- virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { }
-
- /// \brief Find all declarations with the given name in the given context,
- /// and add them to the context by calling SetExternalVisibleDeclsForName
- /// or SetNoExternalVisibleDeclsForName.
- /// \return \c true if any declarations might have been found, \c false if
- /// we definitely have no declarations with tbis name.
- ///
- /// The default implementation of this method is a no-op returning \c false.
- virtual bool
- FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
-
- /// \brief Ensures that the table of all visible declarations inside this
- /// context is up to date.
- ///
- /// The default implementation of this function is a no-op.
- virtual void completeVisibleDeclsMap(const DeclContext *DC);
-
- /// \brief Retrieve the module that corresponds to the given module ID.
- virtual Module *getModule(unsigned ID) { return nullptr; }
-
- /// Abstracts clang modules and precompiled header files and holds
- /// everything needed to generate debug info for an imported module
- /// or PCH.
- class ASTSourceDescriptor {
- StringRef PCHModuleName;
- StringRef Path;
- StringRef ASTFile;
- uint64_t Signature = 0;
- const Module *ClangModule = nullptr;
-
- public:
- ASTSourceDescriptor(){};
- ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
- uint64_t Signature)
- : PCHModuleName(std::move(Name)), Path(std::move(Path)),
- ASTFile(std::move(ASTFile)), Signature(Signature){};
- ASTSourceDescriptor(const Module &M);
- std::string getModuleName() const;
- StringRef getPath() const { return Path; }
- StringRef getASTFile() const { return ASTFile; }
- uint64_t getSignature() const { return Signature; }
- const Module *getModuleOrNull() const { return ClangModule; }
- };
-
- /// Return a descriptor for the corresponding module, if one exists.
- virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
-
- /// \brief Finds all declarations lexically contained within the given
- /// DeclContext, after applying an optional filter predicate.
- ///
- /// \param IsKindWeWant a predicate function that returns true if the passed
- /// declaration kind is one we are looking for.
- ///
- /// The default implementation of this method is a no-op.
- virtual void
- FindExternalLexicalDecls(const DeclContext *DC,
- llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
- SmallVectorImpl<Decl *> &Result);
-
- /// \brief Finds all declarations lexically contained within the given
- /// DeclContext.
- void FindExternalLexicalDecls(const DeclContext *DC,
- SmallVectorImpl<Decl *> &Result) {
- FindExternalLexicalDecls(DC, [](Decl::Kind) { return true; }, Result);
- }
-
- /// \brief Get the decls that are contained in a file in the Offset/Length
- /// range. \p Length can be 0 to indicate a point at \p Offset instead of
- /// a range.
- virtual void FindFileRegionDecls(FileID File, unsigned Offset,
- unsigned Length,
- SmallVectorImpl<Decl *> &Decls);
-
- /// \brief Gives the external AST source an opportunity to complete
- /// the redeclaration chain for a declaration. Called each time we
- /// need the most recent declaration of a declaration after the
- /// generation count is incremented.
- virtual void CompleteRedeclChain(const Decl *D);
-
- /// \brief Gives the external AST source an opportunity to complete
- /// an incomplete type.
- virtual void CompleteType(TagDecl *Tag);
-
- /// \brief Gives the external AST source an opportunity to complete an
- /// incomplete Objective-C class.
- ///
- /// This routine will only be invoked if the "externally completed" bit is
- /// set on the ObjCInterfaceDecl via the function
- /// \c ObjCInterfaceDecl::setExternallyCompleted().
- virtual void CompleteType(ObjCInterfaceDecl *Class);
-
- /// \brief Loads comment ranges.
- virtual void ReadComments();
-
- /// \brief Notify ExternalASTSource that we started deserialization of
- /// a decl or type so until FinishedDeserializing is called there may be
- /// decls that are initializing. Must be paired with FinishedDeserializing.
- ///
- /// The default implementation of this method is a no-op.
- virtual void StartedDeserializing();
-
- /// \brief Notify ExternalASTSource that we finished the deserialization of
- /// a decl or type. Must be paired with StartedDeserializing.
- ///
- /// The default implementation of this method is a no-op.
- virtual void FinishedDeserializing();
-
- /// \brief Function that will be invoked when we begin parsing a new
- /// translation unit involving this external AST source.
- ///
- /// The default implementation of this method is a no-op.
- virtual void StartTranslationUnit(ASTConsumer *Consumer);
-
- /// \brief Print any statistics that have been gathered regarding
- /// the external AST source.
- ///
- /// The default implementation of this method is a no-op.
- virtual void PrintStats();
-
-
- /// \brief Perform layout on the given record.
- ///
- /// This routine allows the external AST source to provide an specific
- /// layout for a record, overriding the layout that would normally be
- /// constructed. It is intended for clients who receive specific layout
- /// details rather than source code (such as LLDB). The client is expected
- /// to fill in the field offsets, base offsets, virtual base offsets, and
- /// complete object size.
- ///
- /// \param Record The record whose layout is being requested.
- ///
- /// \param Size The final size of the record, in bits.
- ///
- /// \param Alignment The final alignment of the record, in bits.
- ///
- /// \param FieldOffsets The offset of each of the fields within the record,
- /// expressed in bits. All of the fields must be provided with offsets.
- ///
- /// \param BaseOffsets The offset of each of the direct, non-virtual base
- /// classes. If any bases are not given offsets, the bases will be laid
- /// out according to the ABI.
- ///
- /// \param VirtualBaseOffsets The offset of each of the virtual base classes
- /// (either direct or not). If any bases are not given offsets, the bases will be laid
- /// out according to the ABI.
- ///
- /// \returns true if the record layout was provided, false otherwise.
- virtual bool layoutRecordType(
- const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
-
- //===--------------------------------------------------------------------===//
- // Queries for performance analysis.
- //===--------------------------------------------------------------------===//
-
- struct MemoryBufferSizes {
- size_t malloc_bytes;
- size_t mmap_bytes;
-
- MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
- : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
- };
-
- /// Return the amount of memory used by memory buffers, breaking down
- /// by heap-backed versus mmap'ed memory.
- MemoryBufferSizes getMemoryBufferSizes() const {
- MemoryBufferSizes sizes(0, 0);
- getMemoryBufferSizes(sizes);
- return sizes;
- }
-
- virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
-
-protected:
- static DeclContextLookupResult
- SetExternalVisibleDeclsForName(const DeclContext *DC,
- DeclarationName Name,
- ArrayRef<NamedDecl*> Decls);
-
- static DeclContextLookupResult
- SetNoExternalVisibleDeclsForName(const DeclContext *DC,
- DeclarationName Name);
-
- /// \brief Increment the current generation.
- uint32_t incrementGeneration(ASTContext &C);
-};
-
-/// \brief A lazy pointer to an AST node (of base type T) that resides
-/// within an external AST source.
-///
-/// The AST node is identified within the external AST source by a
-/// 63-bit offset, and can be retrieved via an operation on the
-/// external AST source itself.
-template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
-struct LazyOffsetPtr {
- /// \brief Either a pointer to an AST node or the offset within the
- /// external AST source where the AST node can be found.
- ///
- /// If the low bit is clear, a pointer to the AST node. If the low
- /// bit is set, the upper 63 bits are the offset.
- mutable uint64_t Ptr;
-
-public:
- LazyOffsetPtr() : Ptr(0) { }
-
- explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
- explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
- assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
- if (Offset == 0)
- Ptr = 0;
- }
-
- LazyOffsetPtr &operator=(T *Ptr) {
- this->Ptr = reinterpret_cast<uint64_t>(Ptr);
- return *this;
- }
-
- LazyOffsetPtr &operator=(uint64_t Offset) {
- assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
- if (Offset == 0)
- Ptr = 0;
- else
- Ptr = (Offset << 1) | 0x01;
-
- return *this;
- }
-
- /// \brief Whether this pointer is non-NULL.
- ///
- /// This operation does not require the AST node to be deserialized.
- explicit operator bool() const { return Ptr != 0; }
-
- /// \brief Whether this pointer is non-NULL.
- ///
- /// This operation does not require the AST node to be deserialized.
- bool isValid() const { return Ptr != 0; }
-
- /// \brief Whether this pointer is currently stored as an offset.
- bool isOffset() const { return Ptr & 0x01; }
-
- /// \brief Retrieve the pointer to the AST node that this lazy pointer
- ///
- /// \param Source the external AST source.
- ///
- /// \returns a pointer to the AST node.
- T* get(ExternalASTSource *Source) const {
- if (isOffset()) {
- assert(Source &&
- "Cannot deserialize a lazy pointer without an AST source");
- Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
- }
- return reinterpret_cast<T*>(Ptr);
- }
-};
-
-/// \brief A lazy value (of type T) that is within an AST node of type Owner,
-/// where the value might change in later generations of the external AST
-/// source.
-template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)>
-struct LazyGenerationalUpdatePtr {
- /// A cache of the value of this pointer, in the most recent generation in
- /// which we queried it.
- struct LazyData {
- LazyData(ExternalASTSource *Source, T Value)
- : ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
- ExternalASTSource *ExternalSource;
- uint32_t LastGeneration;
- T LastValue;
- };
-
- // Our value is represented as simply T if there is no external AST source.
- typedef llvm::PointerUnion<T, LazyData*> ValueType;
- ValueType Value;
-
- LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
-
- // Defined in ASTContext.h
- static ValueType makeValue(const ASTContext &Ctx, T Value);
-
-public:
- explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
- : Value(makeValue(Ctx, Value)) {}
-
- /// Create a pointer that is not potentially updated by later generations of
- /// the external AST source.
- enum NotUpdatedTag { NotUpdated };
- LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T())
- : Value(Value) {}
-
- /// Forcibly set this pointer (which must be lazy) as needing updates.
- void markIncomplete() {
- Value.template get<LazyData *>()->LastGeneration = 0;
- }
-
- /// Set the value of this pointer, in the current generation.
- void set(T NewValue) {
- if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
- LazyVal->LastValue = NewValue;
- return;
- }
- Value = NewValue;
- }
-
- /// Set the value of this pointer, for this and all future generations.
- void setNotUpdated(T NewValue) { Value = NewValue; }
-
- /// Get the value of this pointer, updating its owner if necessary.
- T get(Owner O) {
- if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
- if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
- LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
- (LazyVal->ExternalSource->*Update)(O);
- }
- return LazyVal->LastValue;
- }
- return Value.template get<T>();
- }
-
- /// Get the most recently computed value of this pointer without updating it.
- T getNotUpdated() const {
- if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>())
- return LazyVal->LastValue;
- return Value.template get<T>();
- }
-
- void *getOpaqueValue() { return Value.getOpaqueValue(); }
- static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
- return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
- }
-};
-} // end namespace clang
-
-/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
-/// placed into a PointerUnion.
-namespace llvm {
-template<typename Owner, typename T,
- void (clang::ExternalASTSource::*Update)(Owner)>
-struct PointerLikeTypeTraits<
- clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
- typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
- static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
- static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
- enum {
- NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
- };
-};
-}
-
-namespace clang {
-/// \brief Represents a lazily-loaded vector of data.
-///
-/// The lazily-loaded vector of data contains data that is partially loaded
-/// from an external source and partially added by local translation. The
-/// items loaded from the external source are loaded lazily, when needed for
-/// iteration over the complete vector.
-template<typename T, typename Source,
- void (Source::*Loader)(SmallVectorImpl<T>&),
- unsigned LoadedStorage = 2, unsigned LocalStorage = 4>
-class LazyVector {
- SmallVector<T, LoadedStorage> Loaded;
- SmallVector<T, LocalStorage> Local;
-
-public:
- /// Iteration over the elements in the vector.
- ///
- /// In a complete iteration, the iterator walks the range [-M, N),
- /// where negative values are used to indicate elements
- /// loaded from the external source while non-negative values are used to
- /// indicate elements added via \c push_back().
- /// However, to provide iteration in source order (for, e.g., chained
- /// precompiled headers), dereferencing the iterator flips the negative
- /// values (corresponding to loaded entities), so that position -M
- /// corresponds to element 0 in the loaded entities vector, position -M+1
- /// corresponds to element 1 in the loaded entities vector, etc. This
- /// gives us a reasonably efficient, source-order walk.
- ///
- /// We define this as a wrapping iterator around an int. The
- /// iterator_adaptor_base class forwards the iterator methods to basic integer
- /// arithmetic.
- class iterator : public llvm::iterator_adaptor_base<
- iterator, int, std::random_access_iterator_tag, T, int> {
- LazyVector *Self;
-
- iterator(LazyVector *Self, int Position)
- : iterator::iterator_adaptor_base(Position), Self(Self) {}
-
- bool isLoaded() const { return this->I < 0; }
- friend class LazyVector;
-
- public:
- iterator() : iterator(nullptr, 0) {}
-
- typename iterator::reference operator*() const {
- if (isLoaded())
- return Self->Loaded.end()[this->I];
- return Self->Local.begin()[this->I];
- }
- };
-
- iterator begin(Source *source, bool LocalOnly = false) {
- if (LocalOnly)
- return iterator(this, 0);
-
- if (source)
- (source->*Loader)(Loaded);
- return iterator(this, -(int)Loaded.size());
- }
-
- iterator end() {
- return iterator(this, Local.size());
- }
-
- void push_back(const T& LocalValue) {
- Local.push_back(LocalValue);
- }
-
- void erase(iterator From, iterator To) {
- if (From.isLoaded() && To.isLoaded()) {
- Loaded.erase(&*From, &*To);
- return;
- }
-
- if (From.isLoaded()) {
- Loaded.erase(&*From, Loaded.end());
- From = begin(nullptr, true);
- }
-
- Local.erase(&*From, &*To);
- }
-};
-
-/// \brief A lazy pointer to a statement.
-typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
- LazyDeclStmtPtr;
-
-/// \brief A lazy pointer to a declaration.
-typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
- LazyDeclPtr;
-
-/// \brief A lazy pointer to a set of CXXCtorInitializers.
-typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t,
- &ExternalASTSource::GetExternalCXXCtorInitializers>
- LazyCXXCtorInitializersPtr;
-
-/// \brief A lazy pointer to a set of CXXBaseSpecifiers.
-typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
- &ExternalASTSource::GetExternalCXXBaseSpecifiers>
- LazyCXXBaseSpecifiersPtr;
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h
deleted file mode 100644
index 54c9d88..0000000
--- a/include/clang/AST/GlobalDecl.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
-// together with its type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_GLOBALDECL_H
-#define LLVM_CLANG_AST_GLOBALDECL_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/ABI.h"
-
-namespace clang {
-
-/// GlobalDecl - represents a global declaration. This can either be a
-/// CXXConstructorDecl and the constructor type (Base, Complete).
-/// a CXXDestructorDecl and the destructor type (Base, Complete) or
-/// a VarDecl, a FunctionDecl or a BlockDecl.
-class GlobalDecl {
- llvm::PointerIntPair<const Decl*, 2> Value;
-
- void Init(const Decl *D) {
- assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
- assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
-
- Value.setPointer(D);
- }
-
-public:
- GlobalDecl() {}
-
- GlobalDecl(const VarDecl *D) { Init(D);}
- GlobalDecl(const FunctionDecl *D) { Init(D); }
- GlobalDecl(const BlockDecl *D) { Init(D); }
- GlobalDecl(const CapturedDecl *D) { Init(D); }
- GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
-
- GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
- : Value(D, Type) {}
- GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
- : Value(D, Type) {}
-
- GlobalDecl getCanonicalDecl() const {
- GlobalDecl CanonGD;
- CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
- CanonGD.Value.setInt(Value.getInt());
-
- return CanonGD;
- }
-
- const Decl *getDecl() const { return Value.getPointer(); }
-
- CXXCtorType getCtorType() const {
- assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
- return static_cast<CXXCtorType>(Value.getInt());
- }
-
- CXXDtorType getDtorType() const {
- assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
- return static_cast<CXXDtorType>(Value.getInt());
- }
-
- friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
- return LHS.Value == RHS.Value;
- }
-
- void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
-
- static GlobalDecl getFromOpaquePtr(void *P) {
- GlobalDecl GD;
- GD.Value.setFromOpaqueValue(P);
- return GD;
- }
-
- GlobalDecl getWithDecl(const Decl *D) {
- GlobalDecl Result(*this);
- Result.Value.setPointer(D);
- return Result;
- }
-};
-
-} // end namespace clang
-
-namespace llvm {
- template<class> struct DenseMapInfo;
-
- template<> struct DenseMapInfo<clang::GlobalDecl> {
- static inline clang::GlobalDecl getEmptyKey() {
- return clang::GlobalDecl();
- }
-
- static inline clang::GlobalDecl getTombstoneKey() {
- return clang::GlobalDecl::
- getFromOpaquePtr(reinterpret_cast<void*>(-1));
- }
-
- static unsigned getHashValue(clang::GlobalDecl GD) {
- return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
- }
-
- static bool isEqual(clang::GlobalDecl LHS,
- clang::GlobalDecl RHS) {
- return LHS == RHS;
- }
-
- };
-
- // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
- // copy assignment operator, and destructor are all trivial.
- template <>
- struct isPodLike<clang::GlobalDecl> {
- static const bool value = true;
- };
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
deleted file mode 100644
index ddefa88..0000000
--- a/include/clang/AST/LambdaCapture.h
+++ /dev/null
@@ -1,128 +0,0 @@
-//===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the LambdaCapture class.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_LAMBDACAPTURE_H
-#define LLVM_CLANG_AST_LAMBDACAPTURE_H
-
-#include "clang/AST/Decl.h"
-#include "clang/Basic/Lambda.h"
-#include "llvm/ADT/PointerIntPair.h"
-
-namespace clang {
-
-/// \brief Describes the capture of a variable or of \c this, or of a
-/// C++1y init-capture.
-class LambdaCapture {
- enum {
- /// \brief Flag used by the Capture class to indicate that the given
- /// capture was implicit.
- Capture_Implicit = 0x01,
-
- /// \brief Flag used by the Capture class to indicate that the
- /// given capture was by-copy.
- ///
- /// This includes the case of a non-reference init-capture.
- Capture_ByCopy = 0x02
- };
-
- llvm::PointerIntPair<Decl *, 2> DeclAndBits;
- SourceLocation Loc;
- SourceLocation EllipsisLoc;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
-public:
- /// \brief Create a new capture of a variable or of \c this.
- ///
- /// \param Loc The source location associated with this capture.
- ///
- /// \param Kind The kind of capture (this, byref, bycopy), which must
- /// not be init-capture.
- ///
- /// \param Implicit Whether the capture was implicit or explicit.
- ///
- /// \param Var The local variable being captured, or null if capturing
- /// \c this.
- ///
- /// \param EllipsisLoc The location of the ellipsis (...) for a
- /// capture that is a pack expansion, or an invalid source
- /// location to indicate that this is not a pack expansion.
- LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
- VarDecl *Var = nullptr,
- SourceLocation EllipsisLoc = SourceLocation());
-
- /// \brief Determine the kind of capture.
- LambdaCaptureKind getCaptureKind() const;
-
- /// \brief Determine whether this capture handles the C++ \c this
- /// pointer.
- bool capturesThis() const {
- return (DeclAndBits.getPointer() == nullptr) &&
- !(DeclAndBits.getInt() & Capture_ByCopy);
- }
-
- /// \brief Determine whether this capture handles a variable.
- bool capturesVariable() const {
- return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
- }
-
- /// \brief Determine whether this captures a variable length array bound
- /// expression.
- bool capturesVLAType() const {
- return (DeclAndBits.getPointer() == nullptr) &&
- (DeclAndBits.getInt() & Capture_ByCopy);
- }
-
- /// \brief Retrieve the declaration of the local variable being
- /// captured.
- ///
- /// This operation is only valid if this capture is a variable capture
- /// (other than a capture of \c this).
- VarDecl *getCapturedVar() const {
- assert(capturesVariable() && "No variable available for 'this' capture");
- return cast<VarDecl>(DeclAndBits.getPointer());
- }
-
- /// \brief Determine whether this was an implicit capture (not
- /// written between the square brackets introducing the lambda).
- bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
-
- /// \brief Determine whether this was an explicit capture (written
- /// between the square brackets introducing the lambda).
- bool isExplicit() const { return !isImplicit(); }
-
- /// \brief Retrieve the source location of the capture.
- ///
- /// For an explicit capture, this returns the location of the
- /// explicit capture in the source. For an implicit capture, this
- /// returns the location at which the variable or \c this was first
- /// used.
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Determine whether this capture is a pack expansion,
- /// which captures a function parameter pack.
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-
- /// \brief Retrieve the location of the ellipsis for a capture
- /// that is a pack expansion.
- SourceLocation getEllipsisLoc() const {
- assert(isPackExpansion() && "No ellipsis location for a non-expansion");
- return EllipsisLoc;
- }
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
deleted file mode 100644
index 85e6449..0000000
--- a/include/clang/AST/Makefile
+++ /dev/null
@@ -1,79 +0,0 @@
-CLANG_LEVEL := ../../..
-TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc AttrVisitor.inc \
- StmtNodes.inc DeclNodes.inc \
- CommentNodes.inc CommentHTMLTags.inc \
- CommentHTMLTagsProperties.inc \
- CommentHTMLNamedCharacterReferences.inc \
- CommentCommandInfo.inc \
- CommentCommandList.inc
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-$(ObjDir)/Attrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute classes with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute implementations with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrDump.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute dumper with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrVisitor.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang attribute AST visitor with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-attr-ast-visitor -o $(call SYSPATH, $@) \
- -I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang statement node tables with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/DeclNodes.inc.tmp : $(TD_SRC_DIR)/DeclNodes.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang declaration node tables with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-decl-nodes -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentNodes.inc.tmp : $(TD_SRC_DIR)/CommentNodes.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang comment node tables with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-nodes -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentHTMLTags.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td $(CLANG_TBLGEN) \
- $(ObjDir)/.dir
- $(Echo) "Building Clang comment HTML tag matchers with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang comment HTML tag properties with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentHTMLNamedCharacterReferences.inc.tmp : \
- $(PROJ_SRC_DIR)/CommentHTMLNamedCharacterReferences.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang named character reference translation function with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-html-named-character-references -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentCommandInfo.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang comment command info with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-command-info -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CommentCommandList.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \
- $(CLANG_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building Clang list of comment commands with tblgen"
- $(Verb) $(ClangTableGen) -gen-clang-comment-command-list -o $(call SYSPATH, $@) $<
-
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
deleted file mode 100644
index 4872738..0000000
--- a/include/clang/AST/Mangle.h
+++ /dev/null
@@ -1,243 +0,0 @@
-//===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines the C++ name mangling interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_MANGLE_H
-#define LLVM_CLANG_AST_MANGLE_H
-
-#include "clang/AST/Type.h"
-#include "clang/Basic/ABI.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
- class ASTContext;
- class BlockDecl;
- class CXXConstructorDecl;
- class CXXDestructorDecl;
- class CXXMethodDecl;
- class FunctionDecl;
- class NamedDecl;
- class ObjCMethodDecl;
- class StringLiteral;
- struct ThisAdjustment;
- struct ThunkInfo;
- class VarDecl;
-
-/// MangleContext - Context for tracking state which persists across multiple
-/// calls to the C++ name mangler.
-class MangleContext {
-public:
- enum ManglerKind {
- MK_Itanium,
- MK_Microsoft
- };
-
-private:
- virtual void anchor();
-
- ASTContext &Context;
- DiagnosticsEngine &Diags;
- const ManglerKind Kind;
-
- llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
- llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
- llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
-
-public:
- ManglerKind getKind() const { return Kind; }
-
- explicit MangleContext(ASTContext &Context,
- DiagnosticsEngine &Diags,
- ManglerKind Kind)
- : Context(Context), Diags(Diags), Kind(Kind) {}
-
- virtual ~MangleContext() { }
-
- ASTContext &getASTContext() const { return Context; }
-
- DiagnosticsEngine &getDiags() const { return Diags; }
-
- virtual void startNewFunction() { LocalBlockIds.clear(); }
-
- unsigned getBlockId(const BlockDecl *BD, bool Local) {
- llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
- = Local? LocalBlockIds : GlobalBlockIds;
- std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
- Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
- 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()));
- return Result.first->second;
- }
-
- /// @name Mangler Entry Points
- /// @{
-
- bool shouldMangleDeclName(const NamedDecl *D);
- virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
- virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
-
- // FIXME: consider replacing raw_ostream & with something like SmallString &.
- void mangleName(const NamedDecl *D, raw_ostream &);
- virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
- virtual void mangleThunk(const CXXMethodDecl *MD,
- const ThunkInfo &Thunk,
- raw_ostream &) = 0;
- virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
- const ThisAdjustment &ThisAdjustment,
- raw_ostream &) = 0;
- virtual void mangleReferenceTemporary(const VarDecl *D,
- unsigned ManglingNumber,
- raw_ostream &) = 0;
- virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
- virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
- virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
- raw_ostream &) = 0;
- virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
- raw_ostream &) = 0;
- virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
-
- void mangleGlobalBlock(const BlockDecl *BD,
- const NamedDecl *ID,
- raw_ostream &Out);
- void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
- const BlockDecl *BD, raw_ostream &Out);
- void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
- const BlockDecl *BD, raw_ostream &Out);
- void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
- raw_ostream &Out);
-
- void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
-
- virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
-
- virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
-
- virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
- raw_ostream &) = 0;
-
- virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
- raw_ostream &Out) = 0;
-
- virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
- raw_ostream &Out) = 0;
-
- /// Generates a unique string for an externally visible type for use with TBAA
- /// or type uniquing.
- /// TODO: Extend this to internal types by generating names that are unique
- /// across translation units so it can be used with LTO.
- virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
-
- /// @}
-};
-
-class ItaniumMangleContext : public MangleContext {
-public:
- explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
- : MangleContext(C, D, MK_Itanium) {}
-
- virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
- virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
- virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
- const CXXRecordDecl *Type,
- raw_ostream &) = 0;
- virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
- raw_ostream &) = 0;
- virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
- raw_ostream &) = 0;
-
- virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
- raw_ostream &) = 0;
- virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
- raw_ostream &) = 0;
-
- static bool classof(const MangleContext *C) {
- return C->getKind() == MK_Itanium;
- }
-
- static ItaniumMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
-};
-
-class MicrosoftMangleContext : public MangleContext {
-public:
- explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
- : MangleContext(C, D, MK_Microsoft) {}
-
- /// \brief Mangle vftable symbols. Only a subset of the bases along the path
- /// to the vftable are included in the name. It's up to the caller to pick
- /// them correctly.
- virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out) = 0;
-
- /// \brief Mangle vbtable symbols. Only a subset of the bases along the path
- /// to the vbtable are included in the name. It's up to the caller to pick
- /// them correctly.
- virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out) = 0;
-
- virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
- unsigned GuardNum,
- raw_ostream &Out) = 0;
-
- virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
- raw_ostream &) = 0;
-
- virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
- const CXXRecordDecl *DstRD,
- raw_ostream &Out) = 0;
-
- virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
- uint32_t NumEntries, raw_ostream &Out) = 0;
-
- virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
- raw_ostream &Out) = 0;
-
- virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
- CXXCtorType CT, uint32_t Size,
- uint32_t NVOffset, int32_t VBPtrOffset,
- uint32_t VBIndex, raw_ostream &Out) = 0;
-
- virtual void mangleCXXRTTIBaseClassDescriptor(
- const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
- uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
-
- virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
- raw_ostream &Out) = 0;
- virtual void
- mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
- raw_ostream &Out) = 0;
-
- virtual void
- mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out) = 0;
-
- static bool classof(const MangleContext *C) {
- return C->getKind() == MK_Microsoft;
- }
-
- static MicrosoftMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
-};
-}
-
-#endif
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
deleted file mode 100644
index 7a81855..0000000
--- a/include/clang/AST/MangleNumberingContext.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//=== MangleNumberingContext.h - Context for mangling numbers ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the LambdaBlockMangleContext interface, which keeps track
-// of the Itanium C++ ABI mangling numbers for lambda expressions and block
-// literals.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
-#define LLVM_CLANG_AST_MANGLENUMBERINGCONTEXT_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-
-namespace clang {
-
-class BlockDecl;
-class CXXMethodDecl;
-class IdentifierInfo;
-class TagDecl;
-class Type;
-class VarDecl;
-
-/// \brief Keeps track of the mangled names of lambda expressions and block
-/// literals within a particular context.
-class MangleNumberingContext : public RefCountedBase<MangleNumberingContext> {
-public:
- virtual ~MangleNumberingContext() {}
-
- /// \brief Retrieve the mangling number of a new lambda expression with the
- /// given call operator within this context.
- virtual unsigned getManglingNumber(const CXXMethodDecl *CallOperator) = 0;
-
- /// \brief Retrieve the mangling number of a new block literal within this
- /// context.
- virtual unsigned getManglingNumber(const BlockDecl *BD) = 0;
-
- /// Static locals are numbered by source order.
- virtual unsigned getStaticLocalNumber(const VarDecl *VD) = 0;
-
- /// \brief Retrieve the mangling number of a static local variable within
- /// this context.
- virtual unsigned getManglingNumber(const VarDecl *VD,
- unsigned MSLocalManglingNumber) = 0;
-
- /// \brief Retrieve the mangling number of a static local variable within
- /// this context.
- virtual unsigned getManglingNumber(const TagDecl *TD,
- unsigned MSLocalManglingNumber) = 0;
-};
-
-} // end namespace clang
-#endif
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
deleted file mode 100644
index 583f9d9..0000000
--- a/include/clang/AST/NSAPI.h
+++ /dev/null
@@ -1,262 +0,0 @@
-//===--- NSAPI.h - NSFoundation APIs ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_NSAPI_H
-#define LLVM_CLANG_AST_NSAPI_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-
-namespace clang {
- class ASTContext;
- class ObjCInterfaceDecl;
- class QualType;
- class Expr;
-
-// \brief Provides info and caches identifiers/selectors for NSFoundation API.
-class NSAPI {
-public:
- explicit NSAPI(ASTContext &Ctx);
-
- ASTContext &getASTContext() const { return Ctx; }
-
- enum NSClassIdKindKind {
- ClassId_NSObject,
- ClassId_NSString,
- ClassId_NSArray,
- ClassId_NSMutableArray,
- ClassId_NSDictionary,
- ClassId_NSMutableDictionary,
- ClassId_NSNumber,
- ClassId_NSMutableSet,
- ClassId_NSMutableOrderedSet,
- ClassId_NSValue
- };
- static const unsigned NumClassIds = 10;
-
- enum NSStringMethodKind {
- NSStr_stringWithString,
- NSStr_stringWithUTF8String,
- NSStr_stringWithCStringEncoding,
- NSStr_stringWithCString,
- NSStr_initWithString,
- NSStr_initWithUTF8String
- };
- static const unsigned NumNSStringMethods = 5;
-
- IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
-
- /// \brief The Objective-C NSString selectors.
- Selector getNSStringSelector(NSStringMethodKind MK) const;
-
- /// \brief Return NSStringMethodKind if \param Sel is such a selector.
- Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const;
-
- /// \brief Returns true if the expression \param E is a reference of
- /// "NSUTF8StringEncoding" enum constant.
- bool isNSUTF8StringEncodingConstant(const Expr *E) const {
- return isObjCEnumerator(E, "NSUTF8StringEncoding", NSUTF8StringEncodingId);
- }
-
- /// \brief Returns true if the expression \param E is a reference of
- /// "NSASCIIStringEncoding" enum constant.
- bool isNSASCIIStringEncodingConstant(const Expr *E) const {
- return isObjCEnumerator(E, "NSASCIIStringEncoding",NSASCIIStringEncodingId);
- }
-
- /// \brief Enumerates the NSArray/NSMutableArray methods used to generate
- /// literals and to apply some checks.
- enum NSArrayMethodKind {
- NSArr_array,
- NSArr_arrayWithArray,
- NSArr_arrayWithObject,
- NSArr_arrayWithObjects,
- NSArr_arrayWithObjectsCount,
- NSArr_initWithArray,
- NSArr_initWithObjects,
- NSArr_objectAtIndex,
- NSMutableArr_replaceObjectAtIndex,
- NSMutableArr_addObject,
- NSMutableArr_insertObjectAtIndex,
- NSMutableArr_setObjectAtIndexedSubscript
- };
- static const unsigned NumNSArrayMethods = 12;
-
- /// \brief The Objective-C NSArray selectors.
- Selector getNSArraySelector(NSArrayMethodKind MK) const;
-
- /// \brief Return NSArrayMethodKind if \p Sel is such a selector.
- Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
-
- /// \brief Enumerates the NSDictionary/NSMutableDictionary methods used
- /// to generate literals and to apply some checks.
- enum NSDictionaryMethodKind {
- NSDict_dictionary,
- NSDict_dictionaryWithDictionary,
- NSDict_dictionaryWithObjectForKey,
- NSDict_dictionaryWithObjectsForKeys,
- NSDict_dictionaryWithObjectsForKeysCount,
- NSDict_dictionaryWithObjectsAndKeys,
- NSDict_initWithDictionary,
- NSDict_initWithObjectsAndKeys,
- NSDict_initWithObjectsForKeys,
- NSDict_objectForKey,
- NSMutableDict_setObjectForKey,
- NSMutableDict_setObjectForKeyedSubscript,
- NSMutableDict_setValueForKey
- };
- static const unsigned NumNSDictionaryMethods = 14;
-
- /// \brief The Objective-C NSDictionary selectors.
- Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
-
- /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector.
- Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
-
- /// \brief Enumerates the NSMutableSet/NSOrderedSet methods used
- /// to apply some checks.
- enum NSSetMethodKind {
- NSMutableSet_addObject,
- NSOrderedSet_insertObjectAtIndex,
- NSOrderedSet_setObjectAtIndex,
- NSOrderedSet_setObjectAtIndexedSubscript,
- NSOrderedSet_replaceObjectAtIndexWithObject
- };
- static const unsigned NumNSSetMethods = 5;
-
- /// \brief The Objective-C NSSet selectors.
- Selector getNSSetSelector(NSSetMethodKind MK) const;
-
- /// \brief Return NSSetMethodKind if \p Sel is such a selector.
- Optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
-
- /// \brief Returns selector for "objectForKeyedSubscript:".
- Selector getObjectForKeyedSubscriptSelector() const {
- return getOrInitSelector(StringRef("objectForKeyedSubscript"),
- objectForKeyedSubscriptSel);
- }
-
- /// \brief Returns selector for "objectAtIndexedSubscript:".
- Selector getObjectAtIndexedSubscriptSelector() const {
- return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
- objectAtIndexedSubscriptSel);
- }
-
- /// \brief Returns selector for "setObject:forKeyedSubscript".
- Selector getSetObjectForKeyedSubscriptSelector() const {
- StringRef Ids[] = { "setObject", "forKeyedSubscript" };
- return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
- }
-
- /// \brief Returns selector for "setObject:atIndexedSubscript".
- Selector getSetObjectAtIndexedSubscriptSelector() const {
- StringRef Ids[] = { "setObject", "atIndexedSubscript" };
- return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
- }
-
- /// \brief Returns selector for "isEqual:".
- Selector getIsEqualSelector() const {
- return getOrInitSelector(StringRef("isEqual"), isEqualSel);
- }
-
- /// \brief Enumerates the NSNumber methods used to generate literals.
- enum NSNumberLiteralMethodKind {
- NSNumberWithChar,
- NSNumberWithUnsignedChar,
- NSNumberWithShort,
- NSNumberWithUnsignedShort,
- NSNumberWithInt,
- NSNumberWithUnsignedInt,
- NSNumberWithLong,
- NSNumberWithUnsignedLong,
- NSNumberWithLongLong,
- NSNumberWithUnsignedLongLong,
- NSNumberWithFloat,
- NSNumberWithDouble,
- NSNumberWithBool,
- NSNumberWithInteger,
- NSNumberWithUnsignedInteger
- };
- static const unsigned NumNSNumberLiteralMethods = 15;
-
- /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
- /// \param Instance if true it will return the selector for the init* method
- /// otherwise it will return the selector for the number* method.
- Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
- bool Instance) const;
-
- bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
- Selector Sel) const {
- return Sel == getNSNumberLiteralSelector(MK, false) ||
- Sel == getNSNumberLiteralSelector(MK, true);
- }
-
- /// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector.
- Optional<NSNumberLiteralMethodKind>
- getNSNumberLiteralMethodKind(Selector Sel) const;
-
- /// \brief Determine the appropriate NSNumber factory method kind for a
- /// literal of the given type.
- Optional<NSNumberLiteralMethodKind>
- getNSNumberFactoryMethodKind(QualType T) const;
-
- /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
- bool isObjCBOOLType(QualType T) const;
- /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
- bool isObjCNSIntegerType(QualType T) const;
- /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
- bool isObjCNSUIntegerType(QualType T) const;
- /// \brief Returns one of NSIntegral typedef names if \param T is a typedef
- /// of that name in objective-c.
- StringRef GetNSIntegralKind(QualType T) const;
-
- /// \brief Returns \c true if \p Id is currently defined as a macro.
- bool isMacroDefined(StringRef Id) const;
-
- /// \brief Returns \c true if \p InterfaceDecl is subclass of \p NSClassKind
- bool isSubclassOfNSClass(ObjCInterfaceDecl *InterfaceDecl,
- NSClassIdKindKind NSClassKind) const;
-
-private:
- bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
- bool isObjCEnumerator(const Expr *E,
- StringRef name, IdentifierInfo *&II) const;
- Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const;
-
- ASTContext &Ctx;
-
- mutable IdentifierInfo *ClassIds[NumClassIds];
-
- mutable Selector NSStringSelectors[NumNSStringMethods];
-
- /// \brief The selectors for Objective-C NSArray methods.
- mutable Selector NSArraySelectors[NumNSArrayMethods];
-
- /// \brief The selectors for Objective-C NSDictionary methods.
- mutable Selector NSDictionarySelectors[NumNSDictionaryMethods];
-
- /// \brief The selectors for Objective-C NSSet methods.
- mutable Selector NSSetSelectors[NumNSSetMethods];
-
- /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
- mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
- mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
-
- mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
- setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
- isEqualSel;
-
- mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
- mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_NSAPI_H
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
deleted file mode 100644
index b1ff9bd..0000000
--- a/include/clang/AST/NestedNameSpecifier.h
+++ /dev/null
@@ -1,516 +0,0 @@
-//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the NestedNameSpecifier class, which represents
-// a C++ nested-name-specifier.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
-#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-class ASTContext;
-class CXXRecordDecl;
-class NamespaceAliasDecl;
-class NamespaceDecl;
-class IdentifierInfo;
-struct PrintingPolicy;
-class Type;
-class TypeLoc;
-class LangOptions;
-
-/// \brief Represents a C++ nested name specifier, such as
-/// "\::std::vector<int>::".
-///
-/// C++ nested name specifiers are the prefixes to qualified
-/// namespaces. For example, "foo::" in "foo::x" is a nested name
-/// specifier. Nested name specifiers are made up of a sequence of
-/// specifiers, each of which can be a namespace, type, identifier
-/// (for dependent names), decltype specifier, or the global specifier ('::').
-/// The last two specifiers can only appear at the start of a
-/// nested-namespace-specifier.
-class NestedNameSpecifier : public llvm::FoldingSetNode {
-
- /// \brief Enumeration describing
- enum StoredSpecifierKind {
- StoredIdentifier = 0,
- StoredDecl = 1,
- StoredTypeSpec = 2,
- StoredTypeSpecWithTemplate = 3
- };
-
- /// \brief The nested name specifier that precedes this nested name
- /// specifier.
- ///
- /// The pointer is the nested-name-specifier that precedes this
- /// one. The integer stores one of the first four values of type
- /// SpecifierKind.
- llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
-
- /// \brief The last component in the nested name specifier, which
- /// can be an identifier, a declaration, or a type.
- ///
- /// When the pointer is NULL, this specifier represents the global
- /// specifier '::'. Otherwise, the pointer is one of
- /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
- /// specifier as encoded within the prefix.
- void* Specifier;
-
-public:
- /// \brief The kind of specifier that completes this nested name
- /// specifier.
- enum SpecifierKind {
- /// \brief An identifier, stored as an IdentifierInfo*.
- Identifier,
- /// \brief A namespace, stored as a NamespaceDecl*.
- Namespace,
- /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
- NamespaceAlias,
- /// \brief A type, stored as a Type*.
- TypeSpec,
- /// \brief A type that was preceded by the 'template' keyword,
- /// stored as a Type*.
- TypeSpecWithTemplate,
- /// \brief The global specifier '::'. There is no stored value.
- Global,
- /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
- /// the class it appeared in.
- Super
- };
-
-private:
- /// \brief Builds the global specifier.
- NestedNameSpecifier()
- : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
-
- /// \brief Copy constructor used internally to clone nested name
- /// specifiers.
- NestedNameSpecifier(const NestedNameSpecifier &Other)
- : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
- Specifier(Other.Specifier) {
- }
-
- void operator=(const NestedNameSpecifier &) = delete;
-
- /// \brief Either find or insert the given nested name specifier
- /// mockup in the given context.
- static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
- const NestedNameSpecifier &Mockup);
-
-public:
- /// \brief Builds a specifier combining a prefix and an identifier.
- ///
- /// The prefix must be dependent, since nested name specifiers
- /// referencing an identifier are only permitted when the identifier
- /// cannot be resolved.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- IdentifierInfo *II);
-
- /// \brief Builds a nested name specifier that names a namespace.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceDecl *NS);
-
- /// \brief Builds a nested name specifier that names a namespace alias.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- NamespaceAliasDecl *Alias);
-
- /// \brief Builds a nested name specifier that names a type.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- bool Template, const Type *T);
-
- /// \brief Builds a specifier that consists of just an identifier.
- ///
- /// The nested-name-specifier is assumed to be dependent, but has no
- /// prefix because the prefix is implied by something outside of the
- /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
- /// type.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- IdentifierInfo *II);
-
- /// \brief Returns the nested name specifier representing the global
- /// scope.
- static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
-
- /// \brief Returns the nested name specifier representing the __super scope
- /// for the given CXXRecordDecl.
- static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
- CXXRecordDecl *RD);
-
- /// \brief Return the prefix of this nested name specifier.
- ///
- /// The prefix contains all of the parts of the nested name
- /// specifier that preced this current specifier. For example, for a
- /// nested name specifier that represents "foo::bar::", the current
- /// specifier will contain "bar::" and the prefix will contain
- /// "foo::".
- NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
-
- /// \brief Determine what kind of nested name specifier is stored.
- SpecifierKind getKind() const;
-
- /// \brief Retrieve the identifier stored in this nested name
- /// specifier.
- IdentifierInfo *getAsIdentifier() const {
- if (Prefix.getInt() == StoredIdentifier)
- return (IdentifierInfo *)Specifier;
-
- return nullptr;
- }
-
- /// \brief Retrieve the namespace stored in this nested name
- /// specifier.
- NamespaceDecl *getAsNamespace() const;
-
- /// \brief Retrieve the namespace alias stored in this nested name
- /// specifier.
- NamespaceAliasDecl *getAsNamespaceAlias() const;
-
- /// \brief Retrieve the record declaration stored in this nested name
- /// specifier.
- CXXRecordDecl *getAsRecordDecl() const;
-
- /// \brief Retrieve the type stored in this nested name specifier.
- const Type *getAsType() const {
- if (Prefix.getInt() == StoredTypeSpec ||
- Prefix.getInt() == StoredTypeSpecWithTemplate)
- return (const Type *)Specifier;
-
- return nullptr;
- }
-
- /// \brief Whether this nested name specifier refers to a dependent
- /// type or not.
- bool isDependent() const;
-
- /// \brief Whether this nested name specifier involves a template
- /// parameter.
- bool isInstantiationDependent() const;
-
- /// \brief Whether this nested-name-specifier contains an unexpanded
- /// parameter pack (for C++11 variadic templates).
- bool containsUnexpandedParameterPack() const;
-
- /// \brief Print this nested name specifier to the given output
- /// stream.
- void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddPointer(Prefix.getOpaqueValue());
- ID.AddPointer(Specifier);
- }
-
- /// \brief Dump the nested name specifier to standard output to aid
- /// in debugging.
- void dump(const LangOptions &LO) const;
- void dump() const;
-};
-
-/// \brief A C++ nested-name-specifier augmented with source location
-/// information.
-class NestedNameSpecifierLoc {
- NestedNameSpecifier *Qualifier;
- void *Data;
-
- /// \brief Determines the data length for the last component in the
- /// given nested-name-specifier.
- static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
-
- /// \brief Determines the data length for the entire
- /// nested-name-specifier.
- static unsigned getDataLength(NestedNameSpecifier *Qualifier);
-
-public:
- /// \brief Construct an empty nested-name-specifier.
- NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
-
- /// \brief Construct a nested-name-specifier with source location information
- /// from
- NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
- : Qualifier(Qualifier), Data(Data) { }
-
- /// \brief Evalutes true when this nested-name-specifier location is
- /// non-empty.
- explicit operator bool() const { return Qualifier; }
-
- /// \brief Evalutes true when this nested-name-specifier location is
- /// empty.
- bool hasQualifier() const { return Qualifier; }
-
- /// \brief Retrieve the nested-name-specifier to which this instance
- /// refers.
- NestedNameSpecifier *getNestedNameSpecifier() const {
- return Qualifier;
- }
-
- /// \brief Retrieve the opaque pointer that refers to source-location data.
- void *getOpaqueData() const { return Data; }
-
- /// \brief Retrieve the source range covering the entirety of this
- /// nested-name-specifier.
- ///
- /// For example, if this instance refers to a nested-name-specifier
- /// \c \::std::vector<int>::, the returned source range would cover
- /// from the initial '::' to the last '::'.
- SourceRange getSourceRange() const LLVM_READONLY;
-
- /// \brief Retrieve the source range covering just the last part of
- /// this nested-name-specifier, not including the prefix.
- ///
- /// For example, if this instance refers to a nested-name-specifier
- /// \c \::std::vector<int>::, the returned source range would cover
- /// from "vector" to the last '::'.
- SourceRange getLocalSourceRange() const;
-
- /// \brief Retrieve the location of the beginning of this
- /// nested-name-specifier.
- SourceLocation getBeginLoc() const {
- return getSourceRange().getBegin();
- }
-
- /// \brief Retrieve the location of the end of this
- /// nested-name-specifier.
- SourceLocation getEndLoc() const {
- return getSourceRange().getEnd();
- }
-
- /// \brief Retrieve the location of the beginning of this
- /// component of the nested-name-specifier.
- SourceLocation getLocalBeginLoc() const {
- return getLocalSourceRange().getBegin();
- }
-
- /// \brief Retrieve the location of the end of this component of the
- /// nested-name-specifier.
- SourceLocation getLocalEndLoc() const {
- return getLocalSourceRange().getEnd();
- }
-
- /// \brief Return the prefix of this nested-name-specifier.
- ///
- /// For example, if this instance refers to a nested-name-specifier
- /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
- /// returned prefix may be empty, if this is the first component of
- /// the nested-name-specifier.
- NestedNameSpecifierLoc getPrefix() const {
- if (!Qualifier)
- return *this;
-
- return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
- }
-
- /// \brief For a nested-name-specifier that refers to a type,
- /// retrieve the type with source-location information.
- TypeLoc getTypeLoc() const;
-
- /// \brief Determines the data length for the entire
- /// nested-name-specifier.
- unsigned getDataLength() const { return getDataLength(Qualifier); }
-
- friend bool operator==(NestedNameSpecifierLoc X,
- NestedNameSpecifierLoc Y) {
- return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
- }
-
- friend bool operator!=(NestedNameSpecifierLoc X,
- NestedNameSpecifierLoc Y) {
- return !(X == Y);
- }
-};
-
-/// \brief Class that aids in the construction of nested-name-specifiers along
-/// with source-location information for all of the components of the
-/// nested-name-specifier.
-class NestedNameSpecifierLocBuilder {
- /// \brief The current representation of the nested-name-specifier we're
- /// building.
- NestedNameSpecifier *Representation;
-
- /// \brief Buffer used to store source-location information for the
- /// nested-name-specifier.
- ///
- /// Note that we explicitly manage the buffer (rather than using a
- /// SmallVector) because \c Declarator expects it to be possible to memcpy()
- /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
- char *Buffer;
-
- /// \brief The size of the buffer used to store source-location information
- /// for the nested-name-specifier.
- unsigned BufferSize;
-
- /// \brief The capacity of the buffer used to store source-location
- /// information for the nested-name-specifier.
- unsigned BufferCapacity;
-
-public:
- NestedNameSpecifierLocBuilder()
- : Representation(nullptr), Buffer(nullptr), BufferSize(0),
- BufferCapacity(0) {}
-
- NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
-
- NestedNameSpecifierLocBuilder &
- operator=(const NestedNameSpecifierLocBuilder &Other);
-
- ~NestedNameSpecifierLocBuilder() {
- if (BufferCapacity)
- free(Buffer);
- }
-
- /// \brief Retrieve the representation of the nested-name-specifier.
- NestedNameSpecifier *getRepresentation() const { return Representation; }
-
- /// \brief Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'type::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param TemplateKWLoc The location of the 'template' keyword, if present.
- ///
- /// \param TL The TypeLoc that describes the type preceding the '::'.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
- SourceLocation ColonColonLoc);
-
- /// \brief Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'identifier::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Identifier The identifier.
- ///
- /// \param IdentifierLoc The location of the identifier.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, IdentifierInfo *Identifier,
- SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
-
- /// \brief Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'namespace::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Namespace The namespace.
- ///
- /// \param NamespaceLoc The location of the namespace name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceDecl *Namespace,
- SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
-
- /// \brief Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'namespace-alias::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Alias The namespace alias.
- ///
- /// \param AliasLoc The location of the namespace alias
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc, SourceLocation ColonColonLoc);
-
- /// \brief Turn this (empty) nested-name-specifier into the global
- /// nested-name-specifier '::'.
- void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
-
- /// \brief Turns this (empty) nested-name-specifier into '__super'
- /// nested-name-specifier.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param RD The declaration of the class in which nested-name-specifier
- /// appeared.
- ///
- /// \param SuperLoc The location of the '__super' keyword.
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
- SourceLocation SuperLoc, SourceLocation ColonColonLoc);
- /// \brief Make a new nested-name-specifier from incomplete source-location
- /// information.
- ///
- /// This routine should be used very, very rarely, in cases where we
- /// need to synthesize a nested-name-specifier. Most code should instead use
- /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
- void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
- SourceRange R);
-
- /// \brief Adopt an existing nested-name-specifier (with source-range
- /// information).
- void Adopt(NestedNameSpecifierLoc Other);
-
- /// \brief Retrieve the source range covered by this nested-name-specifier.
- SourceRange getSourceRange() const LLVM_READONLY {
- return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
- }
-
- /// \brief Retrieve a nested-name-specifier with location information,
- /// copied into the given AST context.
- ///
- /// \param Context The context into which this nested-name-specifier will be
- /// copied.
- NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
-
- /// \brief Retrieve a nested-name-specifier with location
- /// information based on the information in this builder.
- ///
- /// This loc will contain references to the builder's internal data and may
- /// be invalidated by any change to the builder.
- NestedNameSpecifierLoc getTemporary() const {
- return NestedNameSpecifierLoc(Representation, Buffer);
- }
-
- /// \brief Clear out this builder, and prepare it to build another
- /// nested-name-specifier with source-location information.
- void Clear() {
- Representation = nullptr;
- BufferSize = 0;
- }
-
- /// \brief Retrieve the underlying buffer.
- ///
- /// \returns A pair containing a pointer to the buffer of source-location
- /// data and the size of the source-location data that resides in that
- /// buffer.
- std::pair<char *, unsigned> getBuffer() const {
- return std::make_pair(Buffer, BufferSize);
- }
-};
-
-/// Insertion operator for diagnostics. This allows sending
-/// NestedNameSpecifiers into a diagnostic with <<.
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- NestedNameSpecifier *NNS) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
- DiagnosticsEngine::ak_nestednamespec);
- return DB;
-}
-
-}
-
-#endif
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
deleted file mode 100644
index 7632a4b..0000000
--- a/include/clang/AST/OpenMPClause.h
+++ /dev/null
@@ -1,3198 +0,0 @@
-//===- OpenMPClause.h - Classes for OpenMP clauses --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// \brief This file defines OpenMP AST classes for clauses.
-/// There are clauses for executable directives, clauses for declarative
-/// directives and clauses which can be used in both kinds of directives.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H
-#define LLVM_CLANG_AST_OPENMPCLAUSE_H
-
-#include "clang/AST/Expr.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Basic/OpenMPKinds.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-// AST classes for clauses.
-//===----------------------------------------------------------------------===//
-
-/// \brief This is a basic class for representing single OpenMP clause.
-///
-class OMPClause {
- /// \brief Starting location of the clause (the clause keyword).
- SourceLocation StartLoc;
- /// \brief Ending location of the clause.
- SourceLocation EndLoc;
- /// \brief Kind of the clause.
- OpenMPClauseKind Kind;
-
-protected:
- OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
- : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
-
-public:
- /// \brief Returns the starting location of the clause.
- SourceLocation getLocStart() const { return StartLoc; }
- /// \brief Returns the ending location of the clause.
- SourceLocation getLocEnd() const { return EndLoc; }
-
- /// \brief Sets the starting location of the clause.
- void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
- /// \brief Sets the ending location of the clause.
- void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
-
- /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
- OpenMPClauseKind getClauseKind() const { return Kind; }
-
- bool isImplicit() const { return StartLoc.isInvalid(); }
-
- typedef StmtIterator child_iterator;
- typedef ConstStmtIterator const_child_iterator;
- typedef llvm::iterator_range<child_iterator> child_range;
- typedef llvm::iterator_range<const_child_iterator> const_child_range;
-
- child_range children();
- const_child_range children() const {
- auto Children = const_cast<OMPClause *>(this)->children();
- return const_child_range(Children.begin(), Children.end());
- }
- static bool classof(const OMPClause *) { return true; }
-};
-
-/// \brief This represents clauses with the list of variables like 'private',
-/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
-/// '#pragma omp ...' directives.
-template <class T> class OMPVarListClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Number of variables in the list.
- unsigned NumVars;
-
-protected:
- /// \brief Fetches list of variables associated with this clause.
- MutableArrayRef<Expr *> getVarRefs() {
- return MutableArrayRef<Expr *>(
- static_cast<T *>(this)->template getTrailingObjects<Expr *>(), NumVars);
- }
-
- /// \brief Sets the list of variables for this clause.
- void setVarRefs(ArrayRef<Expr *> VL) {
- assert(VL.size() == NumVars &&
- "Number of variables is not the same as the preallocated buffer");
- std::copy(VL.begin(), VL.end(),
- static_cast<T *>(this)->template getTrailingObjects<Expr *>());
- }
-
- /// \brief Build a clause with \a N variables
- ///
- /// \param K Kind of the clause.
- /// \param StartLoc Starting location of the clause (the clause keyword).
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
- : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
-
-public:
- typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
- typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
- typedef llvm::iterator_range<varlist_iterator> varlist_range;
- typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
-
- unsigned varlist_size() const { return NumVars; }
- bool varlist_empty() const { return NumVars == 0; }
-
- varlist_range varlists() {
- return varlist_range(varlist_begin(), varlist_end());
- }
- varlist_const_range varlists() const {
- return varlist_const_range(varlist_begin(), varlist_end());
- }
-
- varlist_iterator varlist_begin() { return getVarRefs().begin(); }
- varlist_iterator varlist_end() { return getVarRefs().end(); }
- varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
- varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Fetches list of all variables in the clause.
- ArrayRef<const Expr *> getVarRefs() const {
- return llvm::makeArrayRef(
- static_cast<const T *>(this)->template getTrailingObjects<Expr *>(),
- NumVars);
- }
-};
-
-/// \brief This represents 'if' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp parallel if(parallel:a > 5)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'if' clause with
-/// condition 'a > 5' and directive name modifier 'parallel'.
-///
-class OMPIfClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Condition of the 'if' clause.
- Stmt *Condition;
- /// \brief Location of ':' (if any).
- SourceLocation ColonLoc;
- /// \brief Directive name modifier for the clause.
- OpenMPDirectiveKind NameModifier;
- /// \brief Name modifier location.
- SourceLocation NameModifierLoc;
-
- /// \brief Set condition.
- ///
- void setCondition(Expr *Cond) { Condition = Cond; }
- /// \brief Set directive name modifier for the clause.
- ///
- void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; }
- /// \brief Set location of directive name modifier for the clause.
- ///
- void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; }
- /// \brief Set location of ':'.
- ///
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
-
-public:
- /// \brief Build 'if' clause with condition \a Cond.
- ///
- /// \param NameModifier [OpenMP 4.1] Directive name modifier of clause.
- /// \param Cond Condition of the clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param NameModifierLoc Location of directive name modifier.
- /// \param ColonLoc [OpenMP 4.1] Location of ':'.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation NameModifierLoc, SourceLocation ColonLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier),
- NameModifierLoc(NameModifierLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPIfClause()
- : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(),
- Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown),
- NameModifierLoc() {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return the location of ':'.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- /// \brief Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
- /// \brief Return directive name modifier associated with the clause.
- OpenMPDirectiveKind getNameModifier() const { return NameModifier; }
-
- /// \brief Return the location of directive name modifier.
- SourceLocation getNameModifierLoc() const { return NameModifierLoc; }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_if;
- }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-};
-
-/// \brief This represents 'final' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp task final(a > 5)
-/// \endcode
-/// In this example directive '#pragma omp task' has simple 'final'
-/// clause with condition 'a > 5'.
-///
-class OMPFinalClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Condition of the 'if' clause.
- Stmt *Condition;
-
- /// \brief Set condition.
- ///
- void setCondition(Expr *Cond) { Condition = Cond; }
-
-public:
- /// \brief Build 'final' clause with condition \a Cond.
- ///
- /// \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) {}
-
- /// \brief Build an empty clause.
- ///
- OMPFinalClause()
- : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Condition(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_final;
- }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-};
-
-/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp parallel num_threads(6)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'num_threads'
-/// clause with number of threads '6'.
-///
-class OMPNumThreadsClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Condition of the 'num_threads' clause.
- Stmt *NumThreads;
-
- /// \brief Set condition.
- ///
- void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
-
-public:
- /// \brief Build 'num_threads' clause with condition \a NumThreads.
- ///
- /// \param NumThreads Number of threads for the construct.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_num_threads, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumThreads(NumThreads) {}
-
- /// \brief Build an empty clause.
- ///
- OMPNumThreadsClause()
- : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumThreads(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns number of threads.
- Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_num_threads;
- }
-
- child_range children() { return child_range(&NumThreads, &NumThreads + 1); }
-};
-
-/// \brief This represents 'safelen' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp simd safelen(4)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'safelen'
-/// with single expression '4'.
-/// If the safelen clause is used then no two iterations executed
-/// concurrently with SIMD instructions can have a greater distance
-/// in the logical iteration space than its value. The parameter of
-/// the safelen clause must be a constant positive integer expression.
-///
-class OMPSafelenClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
- Stmt *Safelen;
-
- /// \brief Set safelen.
- void setSafelen(Expr *Len) { Safelen = Len; }
-
-public:
- /// \brief Build 'safelen' clause.
- ///
- /// \param Len Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Safelen(Len) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPSafelenClause()
- : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Safelen(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return safe iteration space distance.
- Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_safelen;
- }
-
- child_range children() { return child_range(&Safelen, &Safelen + 1); }
-};
-
-/// \brief This represents 'simdlen' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp simd simdlen(4)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'simdlen'
-/// with single expression '4'.
-/// If the 'simdlen' clause is used then it specifies the preferred number of
-/// iterations to be executed concurrently. The parameter of the 'simdlen'
-/// clause must be a constant positive integer expression.
-///
-class OMPSimdlenClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
- Stmt *Simdlen;
-
- /// \brief Set simdlen.
- void setSimdlen(Expr *Len) { Simdlen = Len; }
-
-public:
- /// \brief Build 'simdlen' clause.
- ///
- /// \param Len Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Simdlen(Len) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPSimdlenClause()
- : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Simdlen(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return safe iteration space distance.
- Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_simdlen;
- }
-
- child_range children() { return child_range(&Simdlen, &Simdlen + 1); }
-};
-
-/// \brief This represents 'collapse' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp simd collapse(3)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'collapse'
-/// with single expression '3'.
-/// The parameter must be a constant positive integer expression, it specifies
-/// the number of nested loops that should be collapsed into a single iteration
-/// space.
-///
-class OMPCollapseClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Number of for-loops.
- Stmt *NumForLoops;
-
- /// \brief Set the number of associated for-loops.
- void setNumForLoops(Expr *Num) { NumForLoops = Num; }
-
-public:
- /// \brief Build 'collapse' clause.
- ///
- /// \param Num Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumForLoops(Num) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPCollapseClause()
- : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return the number of associated for-loops.
- Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_collapse;
- }
-
- child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
-};
-
-/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp parallel default(shared)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'default'
-/// clause with kind 'shared'.
-///
-class OMPDefaultClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief A kind of the 'default' clause.
- OpenMPDefaultClauseKind Kind;
- /// \brief Start location of the kind in source code.
- SourceLocation KindKwLoc;
-
- /// \brief Set kind of the clauses.
- ///
- /// \param K Argument of clause.
- ///
- void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
-
- /// \brief Set argument location.
- ///
- /// \param KLoc Argument location.
- ///
- void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
-
-public:
- /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
- ///
- /// \param A Argument of the clause ('none' or 'shared').
- /// \param ALoc Starting location of the argument.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(A), KindKwLoc(ALoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPDefaultClause()
- : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown),
- KindKwLoc(SourceLocation()) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns kind of the clause.
- OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
-
- /// \brief Returns location of clause kind.
- SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_default;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'proc_bind' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp parallel proc_bind(master)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'proc_bind'
-/// clause with kind 'master'.
-///
-class OMPProcBindClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief A kind of the 'proc_bind' clause.
- OpenMPProcBindClauseKind Kind;
- /// \brief Start location of the kind in source code.
- SourceLocation KindKwLoc;
-
- /// \brief Set kind of the clause.
- ///
- /// \param K Kind of clause.
- ///
- void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
-
- /// \brief Set clause kind location.
- ///
- /// \param KLoc Kind location.
- ///
- void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
-
-public:
- /// \brief Build 'proc_bind' clause with argument \a A ('master', 'close' or
- /// 'spread').
- ///
- /// \param A Argument of the clause ('master', 'close' or 'spread').
- /// \param ALoc Starting location of the argument.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(A), KindKwLoc(ALoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPProcBindClause()
- : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Kind(OMPC_PROC_BIND_unknown),
- KindKwLoc(SourceLocation()) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns kind of the clause.
- OpenMPProcBindClauseKind getProcBindKind() const { return Kind; }
-
- /// \brief Returns location of clause kind.
- SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_proc_bind;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'schedule' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp for schedule(static, 3)
-/// \endcode
-/// In this example directive '#pragma omp for' has 'schedule' clause with
-/// arguments 'static' and '3'.
-///
-class OMPScheduleClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief A kind of the 'schedule' clause.
- OpenMPScheduleClauseKind Kind;
- /// \brief Modifiers for 'schedule' clause.
- enum {FIRST, SECOND, NUM_MODIFIERS};
- OpenMPScheduleClauseModifier Modifiers[NUM_MODIFIERS];
- /// \brief Locations of modifiers.
- SourceLocation ModifiersLoc[NUM_MODIFIERS];
- /// \brief Start location of the schedule ind in source code.
- SourceLocation KindLoc;
- /// \brief Location of ',' (if any).
- SourceLocation CommaLoc;
- /// \brief Chunk size and a reference to pseudo variable for combined
- /// directives.
- enum { CHUNK_SIZE, HELPER_CHUNK_SIZE, NUM_EXPRS };
- Stmt *ChunkSizes[NUM_EXPRS];
-
- /// \brief Set schedule kind.
- ///
- /// \param K Schedule kind.
- ///
- void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; }
- /// \brief Set the first schedule modifier.
- ///
- /// \param M Schedule modifier.
- ///
- void setFirstScheduleModifier(OpenMPScheduleClauseModifier M) {
- Modifiers[FIRST] = M;
- }
- /// \brief Set the second schedule modifier.
- ///
- /// \param M Schedule modifier.
- ///
- void setSecondScheduleModifier(OpenMPScheduleClauseModifier M) {
- Modifiers[SECOND] = M;
- }
- /// \brief Set location of the first schedule modifier.
- ///
- void setFirstScheduleModifierLoc(SourceLocation Loc) {
- ModifiersLoc[FIRST] = Loc;
- }
- /// \brief Set location of the second schedule modifier.
- ///
- void setSecondScheduleModifierLoc(SourceLocation Loc) {
- ModifiersLoc[SECOND] = Loc;
- }
- /// \brief Set schedule modifier location.
- ///
- /// \param M Schedule modifier location.
- ///
- void setScheduleModifer(OpenMPScheduleClauseModifier M) {
- if (Modifiers[FIRST] == OMPC_SCHEDULE_MODIFIER_unknown)
- Modifiers[FIRST] = M;
- else {
- assert(Modifiers[SECOND] == OMPC_SCHEDULE_MODIFIER_unknown);
- Modifiers[SECOND] = M;
- }
- }
- /// \brief Sets the location of '('.
- ///
- /// \param Loc Location of '('.
- ///
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Set schedule kind start location.
- ///
- /// \param KLoc Schedule kind location.
- ///
- void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
- /// \brief Set location of ','.
- ///
- /// \param Loc Location of ','.
- ///
- void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
- /// \brief Set chunk size.
- ///
- /// \param E Chunk size.
- ///
- void setChunkSize(Expr *E) { ChunkSizes[CHUNK_SIZE] = E; }
- /// \brief Set helper chunk size.
- ///
- /// \param E Helper chunk size.
- ///
- void setHelperChunkSize(Expr *E) { ChunkSizes[HELPER_CHUNK_SIZE] = E; }
-
-public:
- /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size
- /// expression \a ChunkSize.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param KLoc Starting location of the argument.
- /// \param CommaLoc Location of ','.
- /// \param EndLoc Ending location of the clause.
- /// \param Kind Schedule kind.
- /// \param ChunkSize Chunk size.
- /// \param HelperChunkSize Helper chunk size for combined directives.
- /// \param M1 The first modifier applied to 'schedule' clause.
- /// \param M1Loc Location of the first modifier
- /// \param M2 The second modifier applied to 'schedule' clause.
- /// \param M2Loc Location of the second modifier
- ///
- OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation KLoc, SourceLocation CommaLoc,
- SourceLocation EndLoc, OpenMPScheduleClauseKind Kind,
- Expr *ChunkSize, Expr *HelperChunkSize,
- OpenMPScheduleClauseModifier M1, SourceLocation M1Loc,
- OpenMPScheduleClauseModifier M2, SourceLocation M2Loc)
- : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc) {
- ChunkSizes[CHUNK_SIZE] = ChunkSize;
- ChunkSizes[HELPER_CHUNK_SIZE] = HelperChunkSize;
- Modifiers[FIRST] = M1;
- Modifiers[SECOND] = M2;
- ModifiersLoc[FIRST] = M1Loc;
- ModifiersLoc[SECOND] = M2Loc;
- }
-
- /// \brief Build an empty clause.
- ///
- explicit OMPScheduleClause()
- : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
- Kind(OMPC_SCHEDULE_unknown) {
- ChunkSizes[CHUNK_SIZE] = nullptr;
- ChunkSizes[HELPER_CHUNK_SIZE] = nullptr;
- Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown;
- Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown;
- }
-
- /// \brief Get kind of the clause.
- ///
- OpenMPScheduleClauseKind getScheduleKind() const { return Kind; }
- /// \brief Get the first modifier of the clause.
- ///
- OpenMPScheduleClauseModifier getFirstScheduleModifier() const {
- return Modifiers[FIRST];
- }
- /// \brief Get the second modifier of the clause.
- ///
- OpenMPScheduleClauseModifier getSecondScheduleModifier() const {
- return Modifiers[SECOND];
- }
- /// \brief Get location of '('.
- ///
- SourceLocation getLParenLoc() { return LParenLoc; }
- /// \brief Get kind location.
- ///
- SourceLocation getScheduleKindLoc() { return KindLoc; }
- /// \brief Get the first modifier location.
- ///
- SourceLocation getFirstScheduleModifierLoc() const {
- return ModifiersLoc[FIRST];
- }
- /// \brief Get the second modifier location.
- ///
- SourceLocation getSecondScheduleModifierLoc() const {
- return ModifiersLoc[SECOND];
- }
- /// \brief Get location of ','.
- ///
- SourceLocation getCommaLoc() { return CommaLoc; }
- /// \brief Get chunk size.
- ///
- Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]); }
- /// \brief Get chunk size.
- ///
- Expr *getChunkSize() const {
- return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]);
- }
- /// \brief Get helper chunk size.
- ///
- Expr *getHelperChunkSize() {
- return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]);
- }
- /// \brief Get helper chunk size.
- ///
- Expr *getHelperChunkSize() const {
- return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]);
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_schedule;
- }
-
- child_range children() {
- return child_range(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1);
- }
-};
-
-/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp for ordered (2)
-/// \endcode
-/// In this example directive '#pragma omp for' has 'ordered' clause with
-/// parameter 2.
-///
-class OMPOrderedClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Number of for-loops.
- Stmt *NumForLoops;
-
- /// \brief Set the number of associated for-loops.
- void setNumForLoops(Expr *Num) { NumForLoops = Num; }
-
-public:
- /// \brief Build 'ordered' clause.
- ///
- /// \param Num Expression, possibly associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPOrderedClause(Expr *Num, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumForLoops(Num) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPOrderedClause()
- : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return the number of associated for-loops.
- Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_ordered;
- }
-
- child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
-};
-
-/// \brief This represents 'nowait' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp for nowait
-/// \endcode
-/// In this example directive '#pragma omp for' has 'nowait' clause.
-///
-class OMPNowaitClause : public OMPClause {
-public:
- /// \brief Build 'nowait' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_nowait, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPNowaitClause()
- : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_nowait;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'untied' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp task untied
-/// \endcode
-/// In this example directive '#pragma omp task' has 'untied' clause.
-///
-class OMPUntiedClause : public OMPClause {
-public:
- /// \brief Build 'untied' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_untied, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPUntiedClause()
- : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_untied;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'mergeable' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp task mergeable
-/// \endcode
-/// In this example directive '#pragma omp task' has 'mergeable' clause.
-///
-class OMPMergeableClause : public OMPClause {
-public:
- /// \brief Build 'mergeable' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPMergeableClause()
- : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_mergeable;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'read' clause in the '#pragma omp atomic' directive.
-///
-/// \code
-/// #pragma omp atomic read
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'read' clause.
-///
-class OMPReadClause : public OMPClause {
-public:
- /// \brief Build 'read' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_read, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_read;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'write' clause in the '#pragma omp atomic' directive.
-///
-/// \code
-/// #pragma omp atomic write
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'write' clause.
-///
-class OMPWriteClause : public OMPClause {
-public:
- /// \brief Build 'write' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_write, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPWriteClause()
- : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_write;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'update' clause in the '#pragma omp atomic'
-/// directive.
-///
-/// \code
-/// #pragma omp atomic update
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'update' clause.
-///
-class OMPUpdateClause : public OMPClause {
-public:
- /// \brief Build 'update' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_update, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPUpdateClause()
- : OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_update;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'capture' clause in the '#pragma omp atomic'
-/// directive.
-///
-/// \code
-/// #pragma omp atomic capture
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'capture' clause.
-///
-class OMPCaptureClause : public OMPClause {
-public:
- /// \brief Build 'capture' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_capture, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPCaptureClause()
- : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_capture;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'seq_cst' clause in the '#pragma omp atomic'
-/// directive.
-///
-/// \code
-/// #pragma omp atomic seq_cst
-/// \endcode
-/// In this example directive '#pragma omp atomic' has 'seq_cst' clause.
-///
-class OMPSeqCstClause : public OMPClause {
-public:
- /// \brief Build 'seq_cst' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPSeqCstClause()
- : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_seq_cst;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel private(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'private'
-/// with the variables 'a' and 'b'.
-///
-class OMPPrivateClause final
- : public OMPVarListClause<OMPPrivateClause>,
- private llvm::TrailingObjects<OMPPrivateClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
- EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPPrivateClause(unsigned N)
- : OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N) {}
-
- /// \brief Sets the list of references to private copies with initializers for
- /// new private variables.
- /// \param VL List of references.
- void setPrivateCopies(ArrayRef<Expr *> VL);
-
- /// \brief Gets the list of references to private copies with initializers for
- /// new private variables.
- MutableArrayRef<Expr *> getPrivateCopies() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param PrivateVL List of references to private copies with initializers.
- ///
- static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL,
- ArrayRef<Expr *> PrivateVL);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
- typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
- typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
- typedef llvm::iterator_range<private_copies_const_iterator>
- private_copies_const_range;
-
- private_copies_range private_copies() {
- return private_copies_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
- private_copies_const_range private_copies() const {
- return private_copies_const_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_private;
- }
-};
-
-/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp parallel firstprivate(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
-/// with the variables 'a' and 'b'.
-///
-class OMPFirstprivateClause final
- : public OMPVarListClause<OMPFirstprivateClause>,
- private llvm::TrailingObjects<OMPFirstprivateClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
-
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc,
- LParenLoc, EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPFirstprivateClause(unsigned N)
- : OMPVarListClause<OMPFirstprivateClause>(
- OMPC_firstprivate, SourceLocation(), SourceLocation(),
- SourceLocation(), N) {}
- /// \brief Sets the list of references to private copies with initializers for
- /// new private variables.
- /// \param VL List of references.
- void setPrivateCopies(ArrayRef<Expr *> VL);
-
- /// \brief Gets the list of references to private copies with initializers for
- /// new private variables.
- MutableArrayRef<Expr *> getPrivateCopies() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief Sets the list of references to initializer variables for new
- /// private variables.
- /// \param VL List of references.
- void setInits(ArrayRef<Expr *> VL);
-
- /// \brief Gets the list of references to initializer variables for new
- /// private variables.
- MutableArrayRef<Expr *> getInits() {
- return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
- }
- ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the original variables.
- /// \param PrivateVL List of references to private copies with initializers.
- /// \param InitVL List of references to auto generated variables used for
- /// initialization of a single array element. Used if firstprivate variable is
- /// of array type.
- ///
- static OMPFirstprivateClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
- ArrayRef<Expr *> InitVL);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;
- typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;
- typedef llvm::iterator_range<private_copies_iterator> private_copies_range;
- typedef llvm::iterator_range<private_copies_const_iterator>
- private_copies_const_range;
-
- private_copies_range private_copies() {
- return private_copies_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
- private_copies_const_range private_copies() const {
- return private_copies_const_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
-
- typedef MutableArrayRef<Expr *>::iterator inits_iterator;
- typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
- typedef llvm::iterator_range<inits_iterator> inits_range;
- typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
-
- inits_range inits() {
- return inits_range(getInits().begin(), getInits().end());
- }
- inits_const_range inits() const {
- return inits_const_range(getInits().begin(), getInits().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_firstprivate;
- }
-};
-
-/// \brief This represents clause 'lastprivate' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp simd lastprivate(a,b)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'lastprivate'
-/// with the variables 'a' and 'b'.
-class OMPLastprivateClause final
- : public OMPVarListClause<OMPLastprivateClause>,
- private llvm::TrailingObjects<OMPLastprivateClause, Expr *> {
- // There are 4 additional tail-allocated arrays at the end of the class:
- // 1. Contains list of pseudo variables with the default initialization for
- // each non-firstprivate variables. Used in codegen for initialization of
- // lastprivate copies.
- // 2. List of helper expressions for proper generation of assignment operation
- // required for lastprivate clause. This list represents private variables
- // (for arrays, single array element).
- // 3. List of helper expressions for proper generation of assignment operation
- // required for lastprivate clause. This list represents original variables
- // (for arrays, single array element).
- // 4. List of helper expressions that represents assignment operation:
- // \code
- // DstExprs = SrcExprs;
- // \endcode
- // Required for proper codegen of final assignment performed by the
- // lastprivate clause.
- //
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
-
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc,
- LParenLoc, EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPLastprivateClause(unsigned N)
- : OMPVarListClause<OMPLastprivateClause>(
- OMPC_lastprivate, SourceLocation(), SourceLocation(),
- SourceLocation(), N) {}
-
- /// \brief Get the list of helper expressions for initialization of private
- /// copies for lastprivate variables.
- MutableArrayRef<Expr *> getPrivateCopies() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief Set list of helper expressions, required for proper codegen of the
- /// clause. These expressions represent private variables (for arrays, single
- /// array element) in the final assignment statement performed by the
- /// lastprivate clause.
- void setSourceExprs(ArrayRef<Expr *> SrcExprs);
-
- /// \brief Get the list of helper source expressions.
- MutableArrayRef<Expr *> getSourceExprs() {
- return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
- }
- ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
- }
-
- /// \brief Set list of helper expressions, required for proper codegen of the
- /// clause. These expressions represent original variables (for arrays, single
- /// array element) in the final assignment statement performed by the
- /// lastprivate clause.
- void setDestinationExprs(ArrayRef<Expr *> DstExprs);
-
- /// \brief Get the list of helper destination expressions.
- MutableArrayRef<Expr *> getDestinationExprs() {
- return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
- }
-
- /// \brief Set list of helper assignment expressions, required for proper
- /// codegen of the clause. These expressions are assignment expressions that
- /// assign private copy of the variable to original variable.
- void setAssignmentOps(ArrayRef<Expr *> AssignmentOps);
-
- /// \brief Get the list of helper assignment expressions.
- MutableArrayRef<Expr *> getAssignmentOps() {
- return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param SrcExprs List of helper expressions for proper generation of
- /// assignment operation required for lastprivate clause. This list represents
- /// private variables (for arrays, single array element).
- /// \param DstExprs List of helper expressions for proper generation of
- /// assignment operation required for lastprivate clause. This list represents
- /// original variables (for arrays, single array element).
- /// \param AssignmentOps List of helper expressions that represents assignment
- /// operation:
- /// \code
- /// DstExprs = SrcExprs;
- /// \endcode
- /// Required for proper codegen of final assignment performed by the
- /// lastprivate clause.
- ///
- ///
- static OMPLastprivateClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
- ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
-
- /// \brief Set list of helper expressions, required for generation of private
- /// copies of original lastprivate variables.
- void setPrivateCopies(ArrayRef<Expr *> PrivateCopies);
-
- helper_expr_const_range private_copies() const {
- return helper_expr_const_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
- helper_expr_range private_copies() {
- return helper_expr_range(getPrivateCopies().begin(),
- getPrivateCopies().end());
- }
- helper_expr_const_range source_exprs() const {
- return helper_expr_const_range(getSourceExprs().begin(),
- getSourceExprs().end());
- }
- helper_expr_range source_exprs() {
- return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
- }
- helper_expr_const_range destination_exprs() const {
- return helper_expr_const_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_range destination_exprs() {
- return helper_expr_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_const_range assignment_ops() const {
- return helper_expr_const_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
- helper_expr_range assignment_ops() {
- return helper_expr_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_lastprivate;
- }
-};
-
-/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel shared(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'shared'
-/// with the variables 'a' and 'b'.
-///
-class OMPSharedClause final
- : public OMPVarListClause<OMPSharedClause>,
- private llvm::TrailingObjects<OMPSharedClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
- EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPSharedClause(unsigned N)
- : OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N) {}
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- ///
- static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_shared;
- }
-};
-
-/// \brief This represents clause 'reduction' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp parallel reduction(+:a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'reduction'
-/// with operator '+' and the variables 'a' and 'b'.
-///
-class OMPReductionClause final
- : public OMPVarListClause<OMPReductionClause>,
- private llvm::TrailingObjects<OMPReductionClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Location of ':'.
- SourceLocation ColonLoc;
- /// \brief Nested name specifier for C++.
- NestedNameSpecifierLoc QualifierLoc;
- /// \brief Name of custom operator.
- DeclarationNameInfo NameInfo;
-
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param ColonLoc Location of ':'.
- /// \param N Number of the variables in the clause.
- /// \param QualifierLoc The nested-name qualifier with location information
- /// \param NameInfo The full name info for reduction identifier.
- ///
- OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo)
- : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc,
- LParenLoc, EndLoc, N),
- ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPReductionClause(unsigned N)
- : OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N),
- ColonLoc(), QualifierLoc(), NameInfo() {}
-
- /// \brief Sets location of ':' symbol in clause.
- void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
- /// \brief Sets the name info for specified reduction identifier.
- void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
- /// \brief Sets the nested name specifier.
- void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
-
- /// \brief Set list of helper expressions, required for proper codegen of the
- /// clause. These expressions represent private copy of the reduction
- /// variable.
- void setPrivates(ArrayRef<Expr *> Privates);
-
- /// \brief Get the list of helper privates.
- MutableArrayRef<Expr *> getPrivates() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief Set list of helper expressions, required for proper codegen of the
- /// clause. These expressions represent LHS expression in the final
- /// reduction expression performed by the reduction clause.
- void setLHSExprs(ArrayRef<Expr *> LHSExprs);
-
- /// \brief Get the list of helper LHS expressions.
- MutableArrayRef<Expr *> getLHSExprs() {
- return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
- }
- ArrayRef<const Expr *> getLHSExprs() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
- }
-
- /// \brief Set list of helper expressions, required for proper codegen of the
- /// clause. These expressions represent RHS expression in the final
- /// reduction expression performed by the reduction clause.
- /// Also, variables in these expressions are used for proper initialization of
- /// reduction copies.
- void setRHSExprs(ArrayRef<Expr *> RHSExprs);
-
- /// \brief Get the list of helper destination expressions.
- MutableArrayRef<Expr *> getRHSExprs() {
- return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getRHSExprs() const {
- return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
- }
-
- /// \brief Set list of helper reduction expressions, required for proper
- /// codegen of the clause. These expressions are binary expressions or
- /// operator/custom reduction call that calculates new value from source
- /// helper expressions to destination helper expressions.
- void setReductionOps(ArrayRef<Expr *> ReductionOps);
-
- /// \brief Get the list of helper reduction expressions.
- MutableArrayRef<Expr *> getReductionOps() {
- return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getReductionOps() const {
- return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param VL The variables in the clause.
- /// \param QualifierLoc The nested-name qualifier with location information
- /// \param NameInfo The full name info for reduction identifier.
- /// \param Privates List of helper expressions for proper generation of
- /// private copies.
- /// \param LHSExprs List of helper expressions for proper generation of
- /// assignment operation required for copyprivate clause. This list represents
- /// LHSs of the reduction expressions.
- /// \param RHSExprs List of helper expressions for proper generation of
- /// assignment operation required for copyprivate clause. This list represents
- /// RHSs of the reduction expressions.
- /// Also, variables in these expressions are used for proper initialization of
- /// reduction copies.
- /// \param ReductionOps List of helper expressions that represents reduction
- /// expressions:
- /// \code
- /// LHSExprs binop RHSExprs;
- /// operator binop(LHSExpr, RHSExpr);
- /// <CutomReduction>(LHSExpr, RHSExpr);
- /// \endcode
- /// Required for proper codegen of final reduction operation performed by the
- /// reduction clause.
- ///
- static OMPReductionClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates,
- ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
- ArrayRef<Expr *> ReductionOps);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- /// \brief Gets location of ':' symbol in clause.
- SourceLocation getColonLoc() const { return ColonLoc; }
- /// \brief Gets the name info for specified reduction identifier.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
- /// \brief Gets the nested name specifier.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
-
- helper_expr_const_range privates() const {
- return helper_expr_const_range(getPrivates().begin(), getPrivates().end());
- }
- helper_expr_range privates() {
- return helper_expr_range(getPrivates().begin(), getPrivates().end());
- }
- helper_expr_const_range lhs_exprs() const {
- return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end());
- }
- helper_expr_range lhs_exprs() {
- return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end());
- }
- helper_expr_const_range rhs_exprs() const {
- return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end());
- }
- helper_expr_range rhs_exprs() {
- return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end());
- }
- helper_expr_const_range reduction_ops() const {
- return helper_expr_const_range(getReductionOps().begin(),
- getReductionOps().end());
- }
- helper_expr_range reduction_ops() {
- return helper_expr_range(getReductionOps().begin(),
- getReductionOps().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_reduction;
- }
-};
-
-/// \brief This represents clause 'linear' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp simd linear(a,b : 2)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'linear'
-/// with variables 'a', 'b' and linear step '2'.
-///
-class OMPLinearClause final
- : public OMPVarListClause<OMPLinearClause>,
- private llvm::TrailingObjects<OMPLinearClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Modifier of 'linear' clause.
- OpenMPLinearClauseKind Modifier;
- /// \brief Location of linear modifier if any.
- SourceLocation ModifierLoc;
- /// \brief Location of ':'.
- SourceLocation ColonLoc;
-
- /// \brief Sets the linear step for clause.
- void setStep(Expr *Step) { *(getFinals().end()) = Step; }
-
- /// \brief Sets the expression to calculate linear step for clause.
- void setCalcStep(Expr *CalcStep) { *(getFinals().end() + 1) = CalcStep; }
-
- /// \brief Build 'linear' clause with given number of variables \a NumVars.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of variables.
- ///
- OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc,
- unsigned NumVars)
- : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc,
- EndLoc, NumVars),
- Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param NumVars Number of variables.
- ///
- explicit OMPLinearClause(unsigned NumVars)
- : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(),
- SourceLocation(), SourceLocation(),
- NumVars),
- Modifier(OMPC_LINEAR_val), ModifierLoc(), ColonLoc() {}
-
- /// \brief Gets the list of initial values for linear variables.
- ///
- /// There are NumVars expressions with initial values allocated after the
- /// varlist, they are followed by NumVars update expressions (used to update
- /// the linear variable's value on current iteration) and they are followed by
- /// NumVars final expressions (used to calculate the linear variable's
- /// value after the loop body). After these lists, there are 2 helper
- /// expressions - linear step and a helper to calculate it before the
- /// loop body (used when the linear step is not constant):
- ///
- /// { Vars[] /* in OMPVarListClause */; Privates[]; Inits[]; Updates[];
- /// Finals[]; Step; CalcStep; }
- ///
- MutableArrayRef<Expr *> getPrivates() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- MutableArrayRef<Expr *> getInits() {
- return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
- }
- ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
- }
-
- /// \brief Sets the list of update expressions for linear variables.
- MutableArrayRef<Expr *> getUpdates() {
- return MutableArrayRef<Expr *>(getInits().end(), varlist_size());
- }
- ArrayRef<const Expr *> getUpdates() const {
- return llvm::makeArrayRef(getInits().end(), varlist_size());
- }
-
- /// \brief Sets the list of final update expressions for linear variables.
- MutableArrayRef<Expr *> getFinals() {
- return MutableArrayRef<Expr *>(getUpdates().end(), varlist_size());
- }
- ArrayRef<const Expr *> getFinals() const {
- return llvm::makeArrayRef(getUpdates().end(), varlist_size());
- }
-
- /// \brief Sets the list of the copies of original linear variables.
- /// \param PL List of expressions.
- void setPrivates(ArrayRef<Expr *> PL);
-
- /// \brief Sets the list of the initial values for linear variables.
- /// \param IL List of expressions.
- void setInits(ArrayRef<Expr *> IL);
-
-public:
- /// \brief Creates clause with a list of variables \a VL and a linear step
- /// \a Step.
- ///
- /// \param C AST Context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param Modifier Modifier of 'linear' clause.
- /// \param ModifierLoc Modifier location.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param PL List of private copies of original variables.
- /// \param IL List of initial values for the variables.
- /// \param Step Linear step.
- /// \param CalcStep Calculation of the linear step.
- static OMPLinearClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
- ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep);
-
- /// \brief Creates an empty clause with the place for \a NumVars variables.
- ///
- /// \param C AST context.
- /// \param NumVars Number of variables.
- ///
- static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
-
- /// \brief Set modifier.
- void setModifier(OpenMPLinearClauseKind Kind) { Modifier = Kind; }
- /// \brief Return modifier.
- OpenMPLinearClauseKind getModifier() const { return Modifier; }
-
- /// \brief Set modifier location.
- void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
- /// \brief Return modifier location.
- SourceLocation getModifierLoc() const { return ModifierLoc; }
-
- /// \brief Sets the location of ':'.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
- /// \brief Returns the location of ':'.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- /// \brief Returns linear step.
- Expr *getStep() { return *(getFinals().end()); }
- /// \brief Returns linear step.
- const Expr *getStep() const { return *(getFinals().end()); }
- /// \brief Returns expression to calculate linear step.
- Expr *getCalcStep() { return *(getFinals().end() + 1); }
- /// \brief Returns expression to calculate linear step.
- const Expr *getCalcStep() const { return *(getFinals().end() + 1); }
-
- /// \brief Sets the list of update expressions for linear variables.
- /// \param UL List of expressions.
- void setUpdates(ArrayRef<Expr *> UL);
-
- /// \brief Sets the list of final update expressions for linear variables.
- /// \param FL List of expressions.
- void setFinals(ArrayRef<Expr *> FL);
-
- typedef MutableArrayRef<Expr *>::iterator privates_iterator;
- typedef ArrayRef<const Expr *>::iterator privates_const_iterator;
- typedef llvm::iterator_range<privates_iterator> privates_range;
- typedef llvm::iterator_range<privates_const_iterator> privates_const_range;
-
- privates_range privates() {
- return privates_range(getPrivates().begin(), getPrivates().end());
- }
- privates_const_range privates() const {
- return privates_const_range(getPrivates().begin(), getPrivates().end());
- }
-
- typedef MutableArrayRef<Expr *>::iterator inits_iterator;
- typedef ArrayRef<const Expr *>::iterator inits_const_iterator;
- typedef llvm::iterator_range<inits_iterator> inits_range;
- typedef llvm::iterator_range<inits_const_iterator> inits_const_range;
-
- inits_range inits() {
- return inits_range(getInits().begin(), getInits().end());
- }
- inits_const_range inits() const {
- return inits_const_range(getInits().begin(), getInits().end());
- }
-
- typedef MutableArrayRef<Expr *>::iterator updates_iterator;
- typedef ArrayRef<const Expr *>::iterator updates_const_iterator;
- typedef llvm::iterator_range<updates_iterator> updates_range;
- typedef llvm::iterator_range<updates_const_iterator> updates_const_range;
-
- updates_range updates() {
- return updates_range(getUpdates().begin(), getUpdates().end());
- }
- updates_const_range updates() const {
- return updates_const_range(getUpdates().begin(), getUpdates().end());
- }
-
- typedef MutableArrayRef<Expr *>::iterator finals_iterator;
- typedef ArrayRef<const Expr *>::iterator finals_const_iterator;
- typedef llvm::iterator_range<finals_iterator> finals_range;
- typedef llvm::iterator_range<finals_const_iterator> finals_const_range;
-
- finals_range finals() {
- return finals_range(getFinals().begin(), getFinals().end());
- }
- finals_const_range finals() const {
- return finals_const_range(getFinals().begin(), getFinals().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_linear;
- }
-};
-
-/// \brief This represents clause 'aligned' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp simd aligned(a,b : 8)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clause 'aligned'
-/// with variables 'a', 'b' and alignment '8'.
-///
-class OMPAlignedClause final
- : public OMPVarListClause<OMPAlignedClause>,
- private llvm::TrailingObjects<OMPAlignedClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Location of ':'.
- SourceLocation ColonLoc;
-
- /// \brief Sets the alignment for clause.
- void setAlignment(Expr *A) { *varlist_end() = A; }
-
- /// \brief Build 'aligned' clause with given number of variables \a NumVars.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of variables.
- ///
- OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc,
- unsigned NumVars)
- : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc,
- EndLoc, NumVars),
- ColonLoc(ColonLoc) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param NumVars Number of variables.
- ///
- explicit OMPAlignedClause(unsigned NumVars)
- : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
- SourceLocation(), SourceLocation(),
- NumVars),
- ColonLoc(SourceLocation()) {}
-
-public:
- /// \brief Creates clause with a list of variables \a VL and alignment \a A.
- ///
- /// \param C AST Context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param ColonLoc Location of ':'.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param A Alignment.
- static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation ColonLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL,
- Expr *A);
-
- /// \brief Creates an empty clause with the place for \a NumVars variables.
- ///
- /// \param C AST context.
- /// \param NumVars Number of variables.
- ///
- static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
-
- /// \brief Sets the location of ':'.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
- /// \brief Returns the location of ':'.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- /// \brief Returns alignment.
- Expr *getAlignment() { return *varlist_end(); }
- /// \brief Returns alignment.
- const Expr *getAlignment() const { return *varlist_end(); }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_aligned;
- }
-};
-
-/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel copyin(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'copyin'
-/// with the variables 'a' and 'b'.
-///
-class OMPCopyinClause final
- : public OMPVarListClause<OMPCopyinClause>,
- private llvm::TrailingObjects<OMPCopyinClause, Expr *> {
- // Class has 3 additional tail allocated arrays:
- // 1. List of helper expressions for proper generation of assignment operation
- // required for copyin clause. This list represents sources.
- // 2. List of helper expressions for proper generation of assignment operation
- // required for copyin clause. This list represents destinations.
- // 3. List of helper expressions that represents assignment operation:
- // \code
- // DstExprs = SrcExprs;
- // \endcode
- // Required for proper codegen of propagation of master's thread values of
- // threadprivate variables to local instances of that variables in other
- // implicit threads.
-
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
- EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPCopyinClause(unsigned N)
- : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N) {}
-
- /// \brief Set list of helper expressions, required for proper codegen of the
- /// clause. These expressions represent source expression in the final
- /// assignment statement performed by the copyin clause.
- void setSourceExprs(ArrayRef<Expr *> SrcExprs);
-
- /// \brief Get the list of helper source expressions.
- MutableArrayRef<Expr *> getSourceExprs() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief Set list of helper expressions, required for proper codegen of the
- /// clause. These expressions represent destination expression in the final
- /// assignment statement performed by the copyin clause.
- void setDestinationExprs(ArrayRef<Expr *> DstExprs);
-
- /// \brief Get the list of helper destination expressions.
- MutableArrayRef<Expr *> getDestinationExprs() {
- return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
- }
-
- /// \brief Set list of helper assignment expressions, required for proper
- /// codegen of the clause. These expressions are assignment expressions that
- /// assign source helper expressions to destination helper expressions
- /// correspondingly.
- void setAssignmentOps(ArrayRef<Expr *> AssignmentOps);
-
- /// \brief Get the list of helper assignment expressions.
- MutableArrayRef<Expr *> getAssignmentOps() {
- return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param SrcExprs List of helper expressions for proper generation of
- /// assignment operation required for copyin clause. This list represents
- /// sources.
- /// \param DstExprs List of helper expressions for proper generation of
- /// assignment operation required for copyin clause. This list represents
- /// destinations.
- /// \param AssignmentOps List of helper expressions that represents assignment
- /// operation:
- /// \code
- /// DstExprs = SrcExprs;
- /// \endcode
- /// Required for proper codegen of propagation of master's thread values of
- /// threadprivate variables to local instances of that variables in other
- /// implicit threads.
- ///
- static OMPCopyinClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
- ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
-
- helper_expr_const_range source_exprs() const {
- return helper_expr_const_range(getSourceExprs().begin(),
- getSourceExprs().end());
- }
- helper_expr_range source_exprs() {
- return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
- }
- helper_expr_const_range destination_exprs() const {
- return helper_expr_const_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_range destination_exprs() {
- return helper_expr_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_const_range assignment_ops() const {
- return helper_expr_const_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
- helper_expr_range assignment_ops() {
- return helper_expr_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_copyin;
- }
-};
-
-/// \brief This represents clause 'copyprivate' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp single copyprivate(a,b)
-/// \endcode
-/// In this example directive '#pragma omp single' has clause 'copyprivate'
-/// with the variables 'a' and 'b'.
-///
-class OMPCopyprivateClause final
- : public OMPVarListClause<OMPCopyprivateClause>,
- private llvm::TrailingObjects<OMPCopyprivateClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,
- LParenLoc, EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPCopyprivateClause(unsigned N)
- : OMPVarListClause<OMPCopyprivateClause>(
- OMPC_copyprivate, SourceLocation(), SourceLocation(),
- SourceLocation(), N) {}
-
- /// \brief Set list of helper expressions, required for proper codegen of the
- /// clause. These expressions represent source expression in the final
- /// assignment statement performed by the copyprivate clause.
- void setSourceExprs(ArrayRef<Expr *> SrcExprs);
-
- /// \brief Get the list of helper source expressions.
- MutableArrayRef<Expr *> getSourceExprs() {
- return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
- }
- ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
- }
-
- /// \brief Set list of helper expressions, required for proper codegen of the
- /// clause. These expressions represent destination expression in the final
- /// assignment statement performed by the copyprivate clause.
- void setDestinationExprs(ArrayRef<Expr *> DstExprs);
-
- /// \brief Get the list of helper destination expressions.
- MutableArrayRef<Expr *> getDestinationExprs() {
- return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
- }
-
- /// \brief Set list of helper assignment expressions, required for proper
- /// codegen of the clause. These expressions are assignment expressions that
- /// assign source helper expressions to destination helper expressions
- /// correspondingly.
- void setAssignmentOps(ArrayRef<Expr *> AssignmentOps);
-
- /// \brief Get the list of helper assignment expressions.
- MutableArrayRef<Expr *> getAssignmentOps() {
- return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
- }
- ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
- }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param SrcExprs List of helper expressions for proper generation of
- /// assignment operation required for copyprivate clause. This list represents
- /// sources.
- /// \param DstExprs List of helper expressions for proper generation of
- /// assignment operation required for copyprivate clause. This list represents
- /// destinations.
- /// \param AssignmentOps List of helper expressions that represents assignment
- /// operation:
- /// \code
- /// DstExprs = SrcExprs;
- /// \endcode
- /// Required for proper codegen of final assignment performed by the
- /// copyprivate clause.
- ///
- static OMPCopyprivateClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
- ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
- typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
- typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
- typedef llvm::iterator_range<helper_expr_const_iterator>
- helper_expr_const_range;
-
- helper_expr_const_range source_exprs() const {
- return helper_expr_const_range(getSourceExprs().begin(),
- getSourceExprs().end());
- }
- helper_expr_range source_exprs() {
- return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
- }
- helper_expr_const_range destination_exprs() const {
- return helper_expr_const_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_range destination_exprs() {
- return helper_expr_range(getDestinationExprs().begin(),
- getDestinationExprs().end());
- }
- helper_expr_const_range assignment_ops() const {
- return helper_expr_const_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
- helper_expr_range assignment_ops() {
- return helper_expr_range(getAssignmentOps().begin(),
- getAssignmentOps().end());
- }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_copyprivate;
- }
-};
-
-/// \brief This represents implicit clause 'flush' for the '#pragma omp flush'
-/// directive.
-/// This clause does not exist by itself, it can be only as a part of 'omp
-/// flush' directive. This clause is introduced to keep the original structure
-/// of \a OMPExecutableDirective class and its derivatives and to use the
-/// existing infrastructure of clauses with the list of variables.
-///
-/// \code
-/// #pragma omp flush(a,b)
-/// \endcode
-/// In this example directive '#pragma omp flush' has implicit clause 'flush'
-/// with the variables 'a' and 'b'.
-///
-class OMPFlushClause final
- : public OMPVarListClause<OMPFlushClause>,
- private llvm::TrailingObjects<OMPFlushClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
- EndLoc, N) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPFlushClause(unsigned N)
- : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N) {}
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- ///
- static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_flush;
- }
-};
-
-/// \brief This represents implicit clause 'depend' for the '#pragma omp task'
-/// directive.
-///
-/// \code
-/// #pragma omp task depend(in:a,b)
-/// \endcode
-/// In this example directive '#pragma omp task' with clause 'depend' with the
-/// variables 'a' and 'b' with dependency 'in'.
-///
-class OMPDependClause final
- : public OMPVarListClause<OMPDependClause>,
- private llvm::TrailingObjects<OMPDependClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
- /// \brief Dependency type (one of in, out, inout).
- OpenMPDependClauseKind DepKind;
- /// \brief Dependency type location.
- SourceLocation DepLoc;
- /// \brief Colon location.
- SourceLocation ColonLoc;
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPDependClause>(OMPC_depend, StartLoc, LParenLoc,
- EndLoc, N),
- DepKind(OMPC_DEPEND_unknown) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPDependClause(unsigned N)
- : OMPVarListClause<OMPDependClause>(OMPC_depend, SourceLocation(),
- SourceLocation(), SourceLocation(),
- N),
- DepKind(OMPC_DEPEND_unknown) {}
- /// \brief Set dependency kind.
- void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; }
-
- /// \brief Set dependency kind and its location.
- void setDependencyLoc(SourceLocation Loc) { DepLoc = Loc; }
-
- /// \brief Set colon location.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param DepKind Dependency type.
- /// \param DepLoc Location of the dependency type.
- /// \param ColonLoc Colon location.
- /// \param VL List of references to the variables.
- ///
- static OMPDependClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, OpenMPDependClauseKind DepKind,
- SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL);
- /// \brief Creates an empty clause with \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPDependClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- /// \brief Get dependency type.
- OpenMPDependClauseKind getDependencyKind() const { return DepKind; }
- /// \brief Get dependency type location.
- SourceLocation getDependencyLoc() const { return DepLoc; }
- /// \brief Get colon location.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_depend;
- }
-};
-
-/// \brief This represents 'device' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp target device(a)
-/// \endcode
-/// In this example directive '#pragma omp target' has clause 'device'
-/// with single expression 'a'.
-///
-class OMPDeviceClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Device number.
- Stmt *Device;
- /// \brief Set the device number.
- ///
- /// \param E Device number.
- ///
- void setDevice(Expr *E) { Device = E; }
-
-public:
- /// \brief Build 'device' clause.
- ///
- /// \param E Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPDeviceClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_device, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Device(E) {}
-
- /// \brief Build an empty clause.
- ///
- OMPDeviceClause()
- : OMPClause(OMPC_device, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Device(nullptr) {}
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return device number.
- Expr *getDevice() { return cast<Expr>(Device); }
- /// \brief Return device number.
- Expr *getDevice() const { return cast<Expr>(Device); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_device;
- }
-
- child_range children() { return child_range(&Device, &Device + 1); }
-};
-
-/// \brief This represents 'threads' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp ordered threads
-/// \endcode
-/// In this example directive '#pragma omp ordered' has simple 'threads' clause.
-///
-class OMPThreadsClause : public OMPClause {
-public:
- /// \brief Build 'threads' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_threads, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPThreadsClause()
- : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_threads;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'simd' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp ordered simd
-/// \endcode
-/// In this example directive '#pragma omp ordered' has simple 'simd' clause.
-///
-class OMPSIMDClause : public OMPClause {
-public:
- /// \brief Build 'simd' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_simd, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_simd;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents clause 'map' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp target map(a,b)
-/// \endcode
-/// In this example directive '#pragma omp target' has clause 'map'
-/// with the variables 'a' and 'b'.
-///
-class OMPMapClause final : public OMPVarListClause<OMPMapClause>,
- private llvm::TrailingObjects<OMPMapClause, Expr *> {
- friend TrailingObjects;
- friend OMPVarListClause;
- friend class OMPClauseReader;
-
- /// \brief Map type modifier for the 'map' clause.
- OpenMPMapClauseKind MapTypeModifier;
- /// \brief Map type for the 'map' clause.
- OpenMPMapClauseKind MapType;
- /// \brief Location of the map type.
- SourceLocation MapLoc;
- /// \brief Colon location.
- SourceLocation ColonLoc;
-
- /// \brief Set type modifier for the clause.
- ///
- /// \param T Type Modifier for the clause.
- ///
- void setMapTypeModifier(OpenMPMapClauseKind T) { MapTypeModifier = T; }
-
- /// \brief Set type for the clause.
- ///
- /// \param T Type for the clause.
- ///
- void setMapType(OpenMPMapClauseKind T) { MapType = T; }
-
- /// \brief Set type location.
- ///
- /// \param TLoc Type location.
- ///
- void setMapLoc(SourceLocation TLoc) { MapLoc = TLoc; }
-
- /// \brief Set colon location.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
-
- /// \brief Build clause with number of variables \a N.
- ///
- /// \param MapTypeModifier Map type modifier.
- /// \param MapType Map type.
- /// \param MapLoc Location of the map type.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- /// \param N Number of the variables in the clause.
- ///
- explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier,
- OpenMPMapClauseKind MapType, SourceLocation MapLoc,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned N)
- : OMPVarListClause<OMPMapClause>(OMPC_map, StartLoc, LParenLoc, EndLoc, N),
- MapTypeModifier(MapTypeModifier), MapType(MapType), MapLoc(MapLoc) {}
-
- /// \brief Build an empty clause.
- ///
- /// \param N Number of variables.
- ///
- explicit OMPMapClause(unsigned N)
- : OMPVarListClause<OMPMapClause>(OMPC_map, SourceLocation(),
- SourceLocation(), SourceLocation(), N),
- MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), MapLoc() {}
-
-public:
- /// \brief Creates clause with a list of variables \a VL.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- /// \param VL List of references to the variables.
- /// \param TypeModifier Map type modifier.
- /// \param Type Map type.
- /// \param TypeLoc Location of the map type.
- ///
- static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> VL,
- OpenMPMapClauseKind TypeModifier,
- OpenMPMapClauseKind Type, SourceLocation TypeLoc);
- /// \brief Creates an empty clause with the place for \a N variables.
- ///
- /// \param C AST context.
- /// \param N The number of variables.
- ///
- static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned N);
-
- /// \brief Fetches mapping kind for the clause.
- OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; }
-
- /// \brief Fetches the map type modifier for the clause.
- OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY {
- return MapTypeModifier;
- }
-
- /// \brief Fetches location of clause mapping kind.
- SourceLocation getMapLoc() const LLVM_READONLY { return MapLoc; }
-
- /// \brief Get colon location.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_map;
- }
-
- child_range children() {
- return child_range(
- reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
- }
-};
-
-/// \brief This represents 'num_teams' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp teams num_teams(n)
-/// \endcode
-/// In this example directive '#pragma omp teams' has clause 'num_teams'
-/// with single expression 'n'.
-///
-class OMPNumTeamsClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief NumTeams number.
- Stmt *NumTeams;
- /// \brief Set the NumTeams number.
- ///
- /// \param E NumTeams number.
- ///
- void setNumTeams(Expr *E) { NumTeams = E; }
-
-public:
- /// \brief Build 'num_teams' clause.
- ///
- /// \param E Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPNumTeamsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_num_teams, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumTeams(E) {}
-
- /// \brief Build an empty clause.
- ///
- OMPNumTeamsClause()
- : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumTeams(nullptr) {}
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return NumTeams number.
- Expr *getNumTeams() { return cast<Expr>(NumTeams); }
- /// \brief Return NumTeams number.
- Expr *getNumTeams() const { return cast<Expr>(NumTeams); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_num_teams;
- }
-
- child_range children() { return child_range(&NumTeams, &NumTeams + 1); }
-};
-
-/// \brief This represents 'thread_limit' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp teams thread_limit(n)
-/// \endcode
-/// In this example directive '#pragma omp teams' has clause 'thread_limit'
-/// with single expression 'n'.
-///
-class OMPThreadLimitClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief ThreadLimit number.
- Stmt *ThreadLimit;
- /// \brief Set the ThreadLimit number.
- ///
- /// \param E ThreadLimit number.
- ///
- void setThreadLimit(Expr *E) { ThreadLimit = E; }
-
-public:
- /// \brief Build 'thread_limit' clause.
- ///
- /// \param E Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPThreadLimitClause(Expr *E, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), LParenLoc(LParenLoc),
- ThreadLimit(E) {}
-
- /// \brief Build an empty clause.
- ///
- OMPThreadLimitClause()
- : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), ThreadLimit(nullptr) {}
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return ThreadLimit number.
- Expr *getThreadLimit() { return cast<Expr>(ThreadLimit); }
- /// \brief Return ThreadLimit number.
- Expr *getThreadLimit() const { return cast<Expr>(ThreadLimit); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_thread_limit;
- }
-
- child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); }
-};
-
-/// \brief This represents 'priority' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp task priority(n)
-/// \endcode
-/// In this example directive '#pragma omp teams' has clause 'priority' with
-/// single expression 'n'.
-///
-class OMPPriorityClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Priority number.
- Stmt *Priority;
- /// \brief Set the Priority number.
- ///
- /// \param E Priority number.
- ///
- void setPriority(Expr *E) { Priority = E; }
-
-public:
- /// \brief Build 'priority' clause.
- ///
- /// \param E Expression associated with this clause.
- /// \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) {}
-
- /// \brief Build an empty clause.
- ///
- OMPPriorityClause()
- : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Priority(nullptr) {}
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- /// \brief Return Priority number.
- Expr *getPriority() { return cast<Expr>(Priority); }
- /// \brief Return Priority number.
- Expr *getPriority() const { return cast<Expr>(Priority); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_priority;
- }
-
- child_range children() { return child_range(&Priority, &Priority + 1); }
-};
-
-/// \brief This represents 'grainsize' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp taskloop grainsize(4)
-/// \endcode
-/// In this example directive '#pragma omp taskloop' has clause 'grainsize'
-/// with single expression '4'.
-///
-class OMPGrainsizeClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
- Stmt *Grainsize;
-
- /// \brief Set safelen.
- void setGrainsize(Expr *Size) { Grainsize = Size; }
-
-public:
- /// \brief Build 'grainsize' clause.
- ///
- /// \param Size Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPGrainsizeClause(Expr *Size, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_grainsize, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Grainsize(Size) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPGrainsizeClause()
- : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Grainsize(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return safe iteration space distance.
- Expr *getGrainsize() const { return cast_or_null<Expr>(Grainsize); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_grainsize;
- }
-
- child_range children() { return child_range(&Grainsize, &Grainsize + 1); }
-};
-
-/// \brief This represents 'nogroup' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp taskloop nogroup
-/// \endcode
-/// In this example directive '#pragma omp taskloop' has 'nogroup' clause.
-///
-class OMPNogroupClause : public OMPClause {
-public:
- /// \brief Build 'nogroup' clause.
- ///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_nogroup, StartLoc, EndLoc) {}
-
- /// \brief Build an empty clause.
- ///
- OMPNogroupClause()
- : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_nogroup;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This represents 'num_tasks' clause in the '#pragma omp ...'
-/// directive.
-///
-/// \code
-/// #pragma omp taskloop num_tasks(4)
-/// \endcode
-/// In this example directive '#pragma omp taskloop' has clause 'num_tasks'
-/// with single expression '4'.
-///
-class OMPNumTasksClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Safe iteration space distance.
- Stmt *NumTasks;
-
- /// \brief Set safelen.
- void setNumTasks(Expr *Size) { NumTasks = Size; }
-
-public:
- /// \brief Build 'num_tasks' clause.
- ///
- /// \param Size Expression associated with this clause.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPNumTasksClause(Expr *Size, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), LParenLoc(LParenLoc),
- NumTasks(Size) {}
-
- /// \brief Build an empty clause.
- ///
- explicit OMPNumTasksClause()
- : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), NumTasks(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Return safe iteration space distance.
- Expr *getNumTasks() const { return cast_or_null<Expr>(NumTasks); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_num_tasks;
- }
-
- child_range children() { return child_range(&NumTasks, &NumTasks + 1); }
-};
-
-/// \brief This represents 'hint' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp critical (name) hint(6)
-/// \endcode
-/// In this example directive '#pragma omp critical' has name 'name' and clause
-/// 'hint' with argument '6'.
-///
-class OMPHintClause : public OMPClause {
- friend class OMPClauseReader;
- /// \brief Location of '('.
- SourceLocation LParenLoc;
- /// \brief Hint expression of the 'hint' clause.
- Stmt *Hint;
-
- /// \brief Set hint expression.
- ///
- void setHint(Expr *H) { Hint = H; }
-
-public:
- /// \brief Build 'hint' clause with expression \a Hint.
- ///
- /// \param Hint Hint expression.
- /// \param StartLoc Starting location of the clause.
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- ///
- OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
- : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc),
- Hint(Hint) {}
-
- /// \brief Build an empty clause.
- ///
- OMPHintClause()
- : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()),
- LParenLoc(SourceLocation()), Hint(nullptr) {}
-
- /// \brief Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- /// \brief Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
-
- /// \brief Returns number of threads.
- Expr *getHint() const { return cast_or_null<Expr>(Hint); }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == OMPC_hint;
- }
-
- child_range children() { return child_range(&Hint, &Hint + 1); }
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
deleted file mode 100644
index 2235c10..0000000
--- a/include/clang/AST/OperationKinds.h
+++ /dev/null
@@ -1,356 +0,0 @@
-//===- OperationKinds.h - Operation enums -----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file enumerates the different kinds of operations that can be
-// performed by various expressions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_OPERATIONKINDS_H
-#define LLVM_CLANG_AST_OPERATIONKINDS_H
-
-namespace clang {
-
-/// CastKind - The kind of operation required for a conversion.
-enum CastKind {
- /// CK_Dependent - A conversion which cannot yet be analyzed because
- /// either the expression or target type is dependent. These are
- /// created only for explicit casts; dependent ASTs aren't required
- /// to even approximately type-check.
- /// (T*) malloc(sizeof(T))
- /// reinterpret_cast<intptr_t>(A<T>::alloc());
- CK_Dependent,
-
- /// CK_BitCast - A conversion which causes a bit pattern of one type
- /// to be reinterpreted as a bit pattern of another type. Generally
- /// the operands must have equivalent size and unrelated types.
- ///
- /// The pointer conversion char* -> int* is a bitcast. A conversion
- /// from any pointer type to a C pointer type is a bitcast unless
- /// it's actually BaseToDerived or DerivedToBase. A conversion to a
- /// block pointer or ObjC pointer type is a bitcast only if the
- /// operand has the same type kind; otherwise, it's one of the
- /// specialized casts below.
- ///
- /// Vector coercions are bitcasts.
- CK_BitCast,
-
- /// CK_LValueBitCast - A conversion which reinterprets the address of
- /// an l-value as an l-value of a different kind. Used for
- /// reinterpret_casts of l-value expressions to reference types.
- /// bool b; reinterpret_cast<char&>(b) = 'a';
- CK_LValueBitCast,
-
- /// CK_LValueToRValue - A conversion which causes the extraction of
- /// an r-value from the operand gl-value. The result of an r-value
- /// conversion is always unqualified.
- CK_LValueToRValue,
-
- /// CK_NoOp - A conversion which does not affect the type other than
- /// (possibly) adding qualifiers.
- /// int -> int
- /// char** -> const char * const *
- CK_NoOp,
-
- /// CK_BaseToDerived - A conversion from a C++ class pointer/reference
- /// to a derived class pointer/reference.
- /// B *b = static_cast<B*>(a);
- CK_BaseToDerived,
-
- /// CK_DerivedToBase - A conversion from a C++ class pointer
- /// to a base class pointer.
- /// A *a = new B();
- CK_DerivedToBase,
-
- /// CK_UncheckedDerivedToBase - A conversion from a C++ class
- /// pointer/reference to a base class that can assume that the
- /// derived pointer is not null.
- /// const A &a = B();
- /// b->method_from_a();
- CK_UncheckedDerivedToBase,
-
- /// CK_Dynamic - A C++ dynamic_cast.
- CK_Dynamic,
-
- /// CK_ToUnion - The GCC cast-to-union extension.
- /// int -> union { int x; float y; }
- /// float -> union { int x; float y; }
- CK_ToUnion,
-
- /// CK_ArrayToPointerDecay - Array to pointer decay.
- /// int[10] -> int*
- /// char[5][6] -> char(*)[6]
- CK_ArrayToPointerDecay,
-
- /// CK_FunctionToPointerDecay - Function to pointer decay.
- /// void(int) -> void(*)(int)
- CK_FunctionToPointerDecay,
-
- /// CK_NullToPointer - Null pointer constant to pointer, ObjC
- /// pointer, or block pointer.
- /// (void*) 0
- /// void (^block)() = 0;
- CK_NullToPointer,
-
- /// CK_NullToMemberPointer - Null pointer constant to member pointer.
- /// int A::*mptr = 0;
- /// int (A::*fptr)(int) = nullptr;
- CK_NullToMemberPointer,
-
- /// CK_BaseToDerivedMemberPointer - Member pointer in base class to
- /// member pointer in derived class.
- /// int B::*mptr = &A::member;
- CK_BaseToDerivedMemberPointer,
-
- /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to
- /// member pointer in base class.
- /// int A::*mptr = static_cast<int A::*>(&B::member);
- CK_DerivedToBaseMemberPointer,
-
- /// CK_MemberPointerToBoolean - Member pointer to boolean. A check
- /// against the null member pointer.
- CK_MemberPointerToBoolean,
-
- /// CK_ReinterpretMemberPointer - Reinterpret a member pointer as a
- /// different kind of member pointer. C++ forbids this from
- /// crossing between function and object types, but otherwise does
- /// not restrict it. However, the only operation that is permitted
- /// on a "punned" member pointer is casting it back to the original
- /// type, which is required to be a lossless operation (although
- /// many ABIs do not guarantee this on all possible intermediate types).
- CK_ReinterpretMemberPointer,
-
- /// CK_UserDefinedConversion - Conversion using a user defined type
- /// conversion function.
- /// struct A { operator int(); }; int i = int(A());
- CK_UserDefinedConversion,
-
- /// CK_ConstructorConversion - Conversion by constructor.
- /// struct A { A(int); }; A a = A(10);
- CK_ConstructorConversion,
-
- /// CK_IntegralToPointer - Integral to pointer. A special kind of
- /// reinterpreting conversion. Applies to normal, ObjC, and block
- /// pointers.
- /// (char*) 0x1001aab0
- /// reinterpret_cast<int*>(0)
- CK_IntegralToPointer,
-
- /// CK_PointerToIntegral - Pointer to integral. A special kind of
- /// reinterpreting conversion. Applies to normal, ObjC, and block
- /// pointers.
- /// (intptr_t) "help!"
- CK_PointerToIntegral,
-
- /// CK_PointerToBoolean - Pointer to boolean conversion. A check
- /// against null. Applies to normal, ObjC, and block pointers.
- CK_PointerToBoolean,
-
- /// CK_ToVoid - Cast to void, discarding the computed value.
- /// (void) malloc(2048)
- CK_ToVoid,
-
- /// CK_VectorSplat - A conversion from an arithmetic type to a
- /// vector of that element type. Fills all elements ("splats") with
- /// the source value.
- /// __attribute__((ext_vector_type(4))) int v = 5;
- CK_VectorSplat,
-
- /// CK_IntegralCast - A cast between integral types (other than to
- /// boolean). Variously a bitcast, a truncation, a sign-extension,
- /// or a zero-extension.
- /// long l = 5;
- /// (unsigned) i
- CK_IntegralCast,
-
- /// CK_IntegralToBoolean - Integral to boolean. A check against zero.
- /// (bool) i
- CK_IntegralToBoolean,
-
- /// CK_IntegralToFloating - Integral to floating point.
- /// float f = i;
- CK_IntegralToFloating,
-
- /// CK_FloatingToIntegral - Floating point to integral. Rounds
- /// towards zero, discarding any fractional component.
- /// (int) f
- CK_FloatingToIntegral,
-
- /// CK_FloatingToBoolean - Floating point to boolean.
- /// (bool) f
- CK_FloatingToBoolean,
-
- /// CK_FloatingCast - Casting between floating types of different size.
- /// (double) f
- /// (float) ld
- CK_FloatingCast,
-
- /// CK_CPointerToObjCPointerCast - Casting a C pointer kind to an
- /// Objective-C pointer.
- CK_CPointerToObjCPointerCast,
-
- /// CK_BlockPointerToObjCPointerCast - Casting a block pointer to an
- /// ObjC pointer.
- CK_BlockPointerToObjCPointerCast,
-
- /// CK_AnyPointerToBlockPointerCast - Casting any non-block pointer
- /// to a block pointer. Block-to-block casts are bitcasts.
- CK_AnyPointerToBlockPointerCast,
-
- /// \brief Converting between two Objective-C object types, which
- /// can occur when performing reference binding to an Objective-C
- /// object.
- CK_ObjCObjectLValueCast,
-
- /// \brief A conversion of a floating point real to a floating point
- /// complex of the original type. Injects the value as the real
- /// component with a zero imaginary component.
- /// float -> _Complex float
- CK_FloatingRealToComplex,
-
- /// \brief Converts a floating point complex to floating point real
- /// of the source's element type. Just discards the imaginary
- /// component.
- /// _Complex long double -> long double
- CK_FloatingComplexToReal,
-
- /// \brief Converts a floating point complex to bool by comparing
- /// against 0+0i.
- CK_FloatingComplexToBoolean,
-
- /// \brief Converts between different floating point complex types.
- /// _Complex float -> _Complex double
- CK_FloatingComplexCast,
-
- /// \brief Converts from a floating complex to an integral complex.
- /// _Complex float -> _Complex int
- CK_FloatingComplexToIntegralComplex,
-
- /// \brief Converts from an integral real to an integral complex
- /// whose element type matches the source. Injects the value as
- /// the real component with a zero imaginary component.
- /// long -> _Complex long
- CK_IntegralRealToComplex,
-
- /// \brief Converts an integral complex to an integral real of the
- /// source's element type by discarding the imaginary component.
- /// _Complex short -> short
- CK_IntegralComplexToReal,
-
- /// \brief Converts an integral complex to bool by comparing against
- /// 0+0i.
- CK_IntegralComplexToBoolean,
-
- /// \brief Converts between different integral complex types.
- /// _Complex char -> _Complex long long
- /// _Complex unsigned int -> _Complex signed int
- CK_IntegralComplexCast,
-
- /// \brief Converts from an integral complex to a floating complex.
- /// _Complex unsigned -> _Complex float
- CK_IntegralComplexToFloatingComplex,
-
- /// \brief [ARC] Produces a retainable object pointer so that it may
- /// be consumed, e.g. by being passed to a consuming parameter.
- /// Calls objc_retain.
- CK_ARCProduceObject,
-
- /// \brief [ARC] Consumes a retainable object pointer that has just
- /// been produced, e.g. as the return value of a retaining call.
- /// Enters a cleanup to call objc_release at some indefinite time.
- CK_ARCConsumeObject,
-
- /// \brief [ARC] Reclaim a retainable object pointer object that may
- /// have been produced and autoreleased as part of a function return
- /// sequence.
- CK_ARCReclaimReturnedObject,
-
- /// \brief [ARC] Causes a value of block type to be copied to the
- /// heap, if it is not already there. A number of other operations
- /// in ARC cause blocks to be copied; this is for cases where that
- /// would not otherwise be guaranteed, such as when casting to a
- /// non-block pointer type.
- CK_ARCExtendBlockObject,
-
- /// \brief Converts from _Atomic(T) to T.
- CK_AtomicToNonAtomic,
- /// \brief Converts from T to _Atomic(T).
- CK_NonAtomicToAtomic,
-
- /// \brief Causes a block literal to by copied to the heap and then
- /// autoreleased.
- ///
- /// This particular cast kind is used for the conversion from a C++11
- /// lambda expression to a block pointer.
- CK_CopyAndAutoreleaseBlockObject,
-
- // Convert a builtin function to a function pointer; only allowed in the
- // callee of a call expression.
- CK_BuiltinFnToFnPtr,
-
- // Convert a zero value for OpenCL event_t initialization.
- CK_ZeroToOCLEvent,
-
- // Convert a pointer to a different address space.
- CK_AddressSpaceConversion
-};
-
-static const CastKind CK_Invalid = static_cast<CastKind>(-1);
-
-enum BinaryOperatorKind {
- // Operators listed in order of precedence.
- // Note that additions to this should also update the StmtVisitor class.
- BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators.
- BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators.
- BO_Add, BO_Sub, // [C99 6.5.6] Additive operators.
- BO_Shl, BO_Shr, // [C99 6.5.7] Bitwise shift operators.
- BO_LT, BO_GT, BO_LE, BO_GE, // [C99 6.5.8] Relational operators.
- BO_EQ, BO_NE, // [C99 6.5.9] Equality operators.
- BO_And, // [C99 6.5.10] Bitwise AND operator.
- BO_Xor, // [C99 6.5.11] Bitwise XOR operator.
- BO_Or, // [C99 6.5.12] Bitwise OR operator.
- BO_LAnd, // [C99 6.5.13] Logical AND operator.
- BO_LOr, // [C99 6.5.14] Logical OR operator.
- BO_Assign, BO_MulAssign, // [C99 6.5.16] Assignment operators.
- BO_DivAssign, BO_RemAssign,
- BO_AddAssign, BO_SubAssign,
- BO_ShlAssign, BO_ShrAssign,
- BO_AndAssign, BO_XorAssign,
- BO_OrAssign,
- BO_Comma // [C99 6.5.17] Comma operator.
-};
-
-enum UnaryOperatorKind {
- // Note that additions to this should also update the StmtVisitor class.
- UO_PostInc, UO_PostDec, // [C99 6.5.2.4] Postfix increment and decrement
- UO_PreInc, UO_PreDec, // [C99 6.5.3.1] Prefix increment and decrement
- UO_AddrOf, UO_Deref, // [C99 6.5.3.2] Address and indirection
- UO_Plus, UO_Minus, // [C99 6.5.3.3] Unary arithmetic
- UO_Not, UO_LNot, // [C99 6.5.3.3] Unary arithmetic
- UO_Real, UO_Imag, // "__real expr"/"__imag expr" Extension.
- UO_Extension, // __extension__ marker.
- UO_Coawait // [C++ Coroutines] co_await operator
-};
-
-/// \brief The kind of bridging performed by the Objective-C bridge cast.
-enum ObjCBridgeCastKind {
- /// \brief Bridging via __bridge, which does nothing but reinterpret
- /// the bits.
- OBC_Bridge,
- /// \brief Bridging via __bridge_transfer, which transfers ownership of an
- /// Objective-C pointer into ARC.
- OBC_BridgeTransfer,
- /// \brief Bridging via __bridge_retain, which makes an ARC object available
- /// as a +1 C pointer.
- OBC_BridgeRetained
-};
-
-}
-
-#endif
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
deleted file mode 100644
index 8945c41..0000000
--- a/include/clang/AST/ParentMap.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===--- ParentMap.h - Mappings from Stmts to their Parents -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ParentMap class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_PARENTMAP_H
-#define LLVM_CLANG_AST_PARENTMAP_H
-
-namespace clang {
-class Stmt;
-class Expr;
-
-class ParentMap {
- void* Impl;
-public:
- ParentMap(Stmt* ASTRoot);
- ~ParentMap();
-
- /// \brief Adds and/or updates the parent/child-relations of the complete
- /// stmt tree of S. All children of S including indirect descendants are
- /// visited and updated or inserted but not the parents of S.
- void addStmt(Stmt* S);
-
- /// Manually sets the parent of \p S to \p Parent.
- ///
- /// If \p S is already in the map, this method will update the mapping.
- void setParent(const Stmt *S, const Stmt *Parent);
-
- Stmt *getParent(Stmt*) const;
- Stmt *getParentIgnoreParens(Stmt *) const;
- Stmt *getParentIgnoreParenCasts(Stmt *) const;
- Stmt *getParentIgnoreParenImpCasts(Stmt *) const;
- Stmt *getOuterParenParent(Stmt *) const;
-
- const Stmt *getParent(const Stmt* S) const {
- return getParent(const_cast<Stmt*>(S));
- }
-
- const Stmt *getParentIgnoreParens(const Stmt *S) const {
- return getParentIgnoreParens(const_cast<Stmt*>(S));
- }
-
- const Stmt *getParentIgnoreParenCasts(const Stmt *S) const {
- return getParentIgnoreParenCasts(const_cast<Stmt*>(S));
- }
-
- bool hasParent(Stmt* S) const {
- return getParent(S) != nullptr;
- }
-
- bool isConsumedExpr(Expr *E) const;
-
- bool isConsumedExpr(const Expr *E) const {
- return isConsumedExpr(const_cast<Expr*>(E));
- }
-};
-
-} // end clang namespace
-#endif
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
deleted file mode 100644
index 8ab3f617..0000000
--- a/include/clang/AST/PrettyPrinter.h
+++ /dev/null
@@ -1,175 +0,0 @@
-//===--- PrettyPrinter.h - Classes for aiding with AST printing -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the PrinterHelper interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_PRETTYPRINTER_H
-#define LLVM_CLANG_AST_PRETTYPRINTER_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
-
-namespace clang {
-
-class LangOptions;
-class SourceManager;
-class Stmt;
-class TagDecl;
-
-class PrinterHelper {
-public:
- virtual ~PrinterHelper();
- virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0;
-};
-
-/// \brief Describes how types, statements, expressions, and
-/// declarations should be printed.
-struct PrintingPolicy {
- /// \brief Create a default printing policy for C.
- PrintingPolicy(const LangOptions &LO)
- : LangOpts(LO), Indentation(2), SuppressSpecifiers(false),
- SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false),
- SuppressUnwrittenScope(false), SuppressInitializers(false),
- ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
- SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
- Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false),
- Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
- IncludeNewlines(true), MSVCFormatting(false) { }
-
- /// \brief What language we're printing.
- LangOptions LangOpts;
-
- /// \brief The number of spaces to use to indent each line.
- unsigned Indentation : 8;
-
- /// \brief Whether we should suppress printing of the actual specifiers for
- /// the given type or declaration.
- ///
- /// This flag is only used when we are printing declarators beyond
- /// the first declarator within a declaration group. For example, given:
- ///
- /// \code
- /// const int *x, *y;
- /// \endcode
- ///
- /// SuppressSpecifiers will be false when printing the
- /// declaration for "x", so that we will print "int *x"; it will be
- /// \c true when we print "y", so that we suppress printing the
- /// "const int" type specifier and instead only print the "*y".
- bool SuppressSpecifiers : 1;
-
- /// \brief Whether type printing should skip printing the tag keyword.
- ///
- /// This is used when printing the inner type of elaborated types,
- /// (as the tag keyword is part of the elaborated type):
- ///
- /// \code
- /// struct Geometry::Point;
- /// \endcode
- bool SuppressTagKeyword : 1;
-
- /// \brief Whether type printing should skip printing the actual tag type.
- ///
- /// This is used when the caller needs to print a tag definition in front
- /// of the type, as in constructs like the following:
- ///
- /// \code
- /// typedef struct { int x, y; } Point;
- /// \endcode
- bool SuppressTag : 1;
-
- /// \brief Suppresses printing of scope specifiers.
- bool SuppressScope : 1;
-
- /// \brief Suppress printing parts of scope specifiers that don't need
- /// to be written, e.g., for inline or anonymous namespaces.
- bool SuppressUnwrittenScope : 1;
-
- /// \brief Suppress printing of variable initializers.
- ///
- /// This flag is used when printing the loop variable in a for-range
- /// statement. For example, given:
- ///
- /// \code
- /// for (auto x : coll)
- /// \endcode
- ///
- /// SuppressInitializers will be true when printing "auto x", so that the
- /// internal initializer constructed for x will not be printed.
- bool SuppressInitializers : 1;
-
- /// \brief Whether we should print the sizes of constant array expressions
- /// as written in the sources.
- ///
- /// This flag determines whether array types declared as
- ///
- /// \code
- /// int a[4+10*10];
- /// char a[] = "A string";
- /// \endcode
- ///
- /// will be printed as written or as follows:
- ///
- /// \code
- /// int a[104];
- /// char a[9] = "A string";
- /// \endcode
- bool ConstantArraySizeAsWritten : 1;
-
- /// \brief When printing an anonymous tag name, also print the location of
- /// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just
- /// prints "(anonymous)" for the name.
- bool AnonymousTagLocations : 1;
-
- /// \brief When true, suppress printing of the __strong lifetime qualifier in
- /// ARC.
- unsigned SuppressStrongLifetime : 1;
-
- /// \brief When true, suppress printing of lifetime qualifier in
- /// ARC.
- unsigned SuppressLifetimeQualifiers : 1;
-
- /// \brief Whether we can use 'bool' rather than '_Bool', even if the language
- /// doesn't actually have 'bool' (because, e.g., it is defined as a macro).
- unsigned Bool : 1;
-
- /// \brief Provide a 'terse' output.
- ///
- /// For example, in this mode we don't print function bodies, class members,
- /// declarations inside namespaces etc. Effectively, this should print
- /// only the requested declaration.
- unsigned TerseOutput : 1;
-
- /// \brief When true, do certain refinement needed for producing proper
- /// declaration tag; such as, do not print attributes attached to the declaration.
- ///
- unsigned PolishForDeclaration : 1;
-
- /// \brief When true, print the half-precision floating-point type as 'half'
- /// instead of '__fp16'
- unsigned Half : 1;
-
- /// \brief When true, print the built-in wchar_t type as __wchar_t. For use in
- /// Microsoft mode when wchar_t is not available.
- unsigned MSWChar : 1;
-
- /// \brief When true, include newlines after statements like "break", etc.
- unsigned IncludeNewlines : 1;
-
- /// \brief Use whitespace and punctuation like MSVC does. In particular, this
- /// prints anonymous namespaces as `anonymous namespace' and does not insert
- /// spaces after template arguments.
- bool MSVCFormatting : 1;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
deleted file mode 100644
index 2e005dd..0000000
--- a/include/clang/AST/RawCommentList.h
+++ /dev/null
@@ -1,203 +0,0 @@
-//===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_RAWCOMMENTLIST_H
-#define LLVM_CLANG_AST_RAWCOMMENTLIST_H
-
-#include "clang/Basic/CommentOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/ArrayRef.h"
-
-namespace clang {
-
-class ASTContext;
-class ASTReader;
-class Decl;
-class Preprocessor;
-
-namespace comments {
- class FullComment;
-} // end namespace comments
-
-class RawComment {
-public:
- enum CommentKind {
- RCK_Invalid, ///< Invalid comment
- RCK_OrdinaryBCPL, ///< Any normal BCPL comments
- RCK_OrdinaryC, ///< Any normal C comment
- RCK_BCPLSlash, ///< \code /// stuff \endcode
- RCK_BCPLExcl, ///< \code //! stuff \endcode
- RCK_JavaDoc, ///< \code /** stuff */ \endcode
- RCK_Qt, ///< \code /*! stuff */ \endcode, also used by HeaderDoc
- RCK_Merged ///< Two or more documentation comments merged together
- };
-
- RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { }
-
- RawComment(const SourceManager &SourceMgr, SourceRange SR,
- bool Merged, bool ParseAllComments);
-
- CommentKind getKind() const LLVM_READONLY {
- return (CommentKind) Kind;
- }
-
- bool isInvalid() const LLVM_READONLY {
- return Kind == RCK_Invalid;
- }
-
- bool isMerged() const LLVM_READONLY {
- return Kind == RCK_Merged;
- }
-
- /// Is this comment attached to any declaration?
- bool isAttached() const LLVM_READONLY {
- return IsAttached;
- }
-
- void setAttached() {
- IsAttached = true;
- }
-
- /// Returns true if it is a comment that should be put after a member:
- /// \code ///< stuff \endcode
- /// \code //!< stuff \endcode
- /// \code /**< stuff */ \endcode
- /// \code /*!< stuff */ \endcode
- bool isTrailingComment() const LLVM_READONLY {
- assert(isDocumentation());
- return IsTrailingComment;
- }
-
- /// Returns true if it is a probable typo:
- /// \code //< stuff \endcode
- /// \code /*< stuff */ \endcode
- bool isAlmostTrailingComment() const LLVM_READONLY {
- return IsAlmostTrailingComment;
- }
-
- /// Returns true if this comment is not a documentation comment.
- bool isOrdinary() const LLVM_READONLY {
- return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) &&
- !ParseAllComments;
- }
-
- /// Returns true if this comment any kind of a documentation comment.
- bool isDocumentation() const LLVM_READONLY {
- return !isInvalid() && !isOrdinary();
- }
-
- /// Returns whether we are parsing all comments.
- bool isParseAllComments() const LLVM_READONLY {
- return ParseAllComments;
- }
-
- /// Returns raw comment text with comment markers.
- StringRef getRawText(const SourceManager &SourceMgr) const {
- if (RawTextValid)
- return RawText;
-
- RawText = getRawTextSlow(SourceMgr);
- RawTextValid = true;
- return RawText;
- }
-
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
-
- const char *getBriefText(const ASTContext &Context) const {
- if (BriefTextValid)
- return BriefText;
-
- return extractBriefText(Context);
- }
-
- /// Parse the comment, assuming it is attached to decl \c D.
- comments::FullComment *parse(const ASTContext &Context,
- const Preprocessor *PP, const Decl *D) const;
-
-private:
- SourceRange Range;
-
- mutable StringRef RawText;
- mutable const char *BriefText;
-
- mutable bool RawTextValid : 1; ///< True if RawText is valid
- mutable bool BriefTextValid : 1; ///< True if BriefText is valid
-
- unsigned Kind : 3;
-
- /// True if comment is attached to a declaration in ASTContext.
- bool IsAttached : 1;
-
- bool IsTrailingComment : 1;
- bool IsAlmostTrailingComment : 1;
-
- /// When true, ordinary comments starting with "//" and "/*" will be
- /// considered as documentation comments.
- bool ParseAllComments : 1;
-
- /// \brief Constructor for AST deserialization.
- RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment,
- bool IsAlmostTrailingComment,
- bool ParseAllComments) :
- Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K),
- IsAttached(false), IsTrailingComment(IsTrailingComment),
- IsAlmostTrailingComment(IsAlmostTrailingComment),
- ParseAllComments(ParseAllComments)
- { }
-
- StringRef getRawTextSlow(const SourceManager &SourceMgr) const;
-
- const char *extractBriefText(const ASTContext &Context) const;
-
- friend class ASTReader;
-};
-
-/// \brief Compare comments' source locations.
-template<>
-class BeforeThanCompare<RawComment> {
- const SourceManager &SM;
-
-public:
- explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { }
-
- bool operator()(const RawComment &LHS, const RawComment &RHS) {
- return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart());
- }
-
- bool operator()(const RawComment *LHS, const RawComment *RHS) {
- return operator()(*LHS, *RHS);
- }
-};
-
-/// \brief This class represents all comments included in the translation unit,
-/// sorted in order of appearance in the translation unit.
-class RawCommentList {
-public:
- RawCommentList(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {}
-
- void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator);
-
- ArrayRef<RawComment *> getComments() const {
- return Comments;
- }
-
-private:
- SourceManager &SourceMgr;
- std::vector<RawComment *> Comments;
-
- void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments);
-
- friend class ASTReader;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
deleted file mode 100644
index 667f235..0000000
--- a/include/clang/AST/RecordLayout.h
+++ /dev/null
@@ -1,315 +0,0 @@
-//===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the RecordLayout interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_RECORDLAYOUT_H
-#define LLVM_CLANG_AST_RECORDLAYOUT_H
-
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/DeclCXX.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
- class ASTContext;
- class FieldDecl;
- class RecordDecl;
- class CXXRecordDecl;
-
-/// ASTRecordLayout -
-/// This class contains layout information for one RecordDecl,
-/// which is a struct/union/class. The decl represented must be a definition,
-/// not a forward declaration.
-/// This class is also used to contain layout information for one
-/// ObjCInterfaceDecl. FIXME - Find appropriate name.
-/// These objects are managed by ASTContext.
-class ASTRecordLayout {
-public:
- struct VBaseInfo {
- /// The offset to this virtual base in the complete-object layout
- /// of this class.
- CharUnits VBaseOffset;
-
- private:
- /// Whether this virtual base requires a vtordisp field in the
- /// Microsoft ABI. These fields are required for certain operations
- /// in constructors and destructors.
- bool HasVtorDisp;
-
- public:
- bool hasVtorDisp() const { return HasVtorDisp; }
-
- VBaseInfo() : HasVtorDisp(false) {}
-
- VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) :
- VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
- };
-
- typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>
- VBaseOffsetsMapTy;
-
-private:
- /// Size - Size of record in characters.
- CharUnits Size;
-
- /// DataSize - Size of record in characters without tail padding.
- CharUnits DataSize;
-
- // Alignment - Alignment of record in characters.
- CharUnits Alignment;
-
- /// RequiredAlignment - The required alignment of the object. In the MS-ABI
- /// the __declspec(align()) trumps #pramga pack and must always be obeyed.
- CharUnits RequiredAlignment;
-
- /// FieldOffsets - Array of field offsets in bits.
- uint64_t *FieldOffsets;
-
- // FieldCount - Number of fields.
- unsigned FieldCount;
-
- /// CXXRecordLayoutInfo - Contains C++ specific layout information.
- struct CXXRecordLayoutInfo {
- /// NonVirtualSize - The non-virtual size (in chars) of an object, which is
- /// the size of the object without virtual bases.
- CharUnits NonVirtualSize;
-
- /// NonVirtualAlignment - The non-virtual alignment (in chars) of an object,
- /// which is the alignment of the object without virtual bases.
- CharUnits NonVirtualAlignment;
-
- /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
- /// (either a base or a member). Will be zero if the class doesn't contain
- /// any empty subobjects.
- CharUnits SizeOfLargestEmptySubobject;
-
- /// VBPtrOffset - Virtual base table offset (Microsoft-only).
- CharUnits VBPtrOffset;
-
- /// HasOwnVFPtr - Does this class provide a virtual function table
- /// (vtable in Itanium, vftbl in Microsoft) that is independent from
- /// its base classes?
- bool HasOwnVFPtr : 1;
-
- /// HasVFPtr - Does this class have a vftable that could be extended by
- /// a derived class. The class may have inherited this pointer from
- /// a primary base class.
- bool HasExtendableVFPtr : 1;
-
- /// HasZeroSizedSubObject - True if this class contains a zero sized member
- /// or base or a base with a zero sized member or base. Only used for
- /// MS-ABI.
- bool HasZeroSizedSubObject : 1;
-
- /// \brief True if this class is zero sized or first base is zero sized or
- /// has this property. Only used for MS-ABI.
- bool LeadsWithZeroSizedBase : 1;
-
- /// PrimaryBase - The primary base info for this record.
- llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
-
- /// BaseSharingVBPtr - The base we share vbptr with.
- const CXXRecordDecl *BaseSharingVBPtr;
-
- /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
- typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
-
- /// BaseOffsets - Contains a map from base classes to their offset.
- BaseOffsetsMapTy BaseOffsets;
-
- /// VBaseOffsets - Contains a map from vbase classes to their offset.
- VBaseOffsetsMapTy VBaseOffsets;
- };
-
- /// CXXInfo - If the record layout is for a C++ record, this will have
- /// C++ specific information about the record.
- CXXRecordLayoutInfo *CXXInfo;
-
- friend class ASTContext;
-
- ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
- CharUnits requiredAlignment,
- CharUnits datasize, const uint64_t *fieldoffsets,
- unsigned fieldcount);
-
- // Constructor for C++ records.
- typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
- ASTRecordLayout(const ASTContext &Ctx,
- CharUnits size, CharUnits alignment,
- CharUnits requiredAlignment,
- bool hasOwnVFPtr, bool hasExtendableVFPtr,
- CharUnits vbptroffset,
- CharUnits datasize,
- const uint64_t *fieldoffsets, unsigned fieldcount,
- CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
- CharUnits SizeOfLargestEmptySubobject,
- const CXXRecordDecl *PrimaryBase,
- bool IsPrimaryBaseVirtual,
- const CXXRecordDecl *BaseSharingVBPtr,
- bool HasZeroSizedSubObject,
- bool LeadsWithZeroSizedBase,
- const BaseOffsetsMapTy& BaseOffsets,
- const VBaseOffsetsMapTy& VBaseOffsets);
-
- ~ASTRecordLayout() = default;
-
- void Destroy(ASTContext &Ctx);
-
- ASTRecordLayout(const ASTRecordLayout &) = delete;
- void operator=(const ASTRecordLayout &) = delete;
-public:
-
- /// getAlignment - Get the record alignment in characters.
- CharUnits getAlignment() const { return Alignment; }
-
- /// getSize - Get the record size in characters.
- CharUnits getSize() const { return Size; }
-
- /// getFieldCount - Get the number of fields in the layout.
- unsigned getFieldCount() const { return FieldCount; }
-
- /// getFieldOffset - Get the offset of the given field index, in
- /// bits.
- uint64_t getFieldOffset(unsigned FieldNo) const {
- assert (FieldNo < FieldCount && "Invalid Field No");
- return FieldOffsets[FieldNo];
- }
-
- /// getDataSize() - Get the record data size, which is the record size
- /// without tail padding, in characters.
- CharUnits getDataSize() const {
- return DataSize;
- }
-
- /// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
- /// which is the size of the object without virtual bases.
- CharUnits getNonVirtualSize() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
-
- return CXXInfo->NonVirtualSize;
- }
-
- /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
- /// which is the alignment of the object without virtual bases.
- CharUnits getNonVirtualAlignment() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
-
- return CXXInfo->NonVirtualAlignment;
- }
-
- /// getPrimaryBase - Get the primary base for this record.
- const CXXRecordDecl *getPrimaryBase() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
-
- return CXXInfo->PrimaryBase.getPointer();
- }
-
- /// isPrimaryBaseVirtual - Get whether the primary base for this record
- /// is virtual or not.
- bool isPrimaryBaseVirtual() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
-
- return CXXInfo->PrimaryBase.getInt();
- }
-
- /// getBaseClassOffset - Get the offset, in chars, for the given base class.
- CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
-
- return CXXInfo->BaseOffsets[Base];
- }
-
- /// getVBaseClassOffset - Get the offset, in chars, for the given base class.
- CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
-
- return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
- }
-
- CharUnits getSizeOfLargestEmptySubobject() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->SizeOfLargestEmptySubobject;
- }
-
- /// hasOwnVFPtr - Does this class provide its own virtual-function
- /// table pointer, rather than inheriting one from a primary base
- /// class? If so, it is at offset zero.
- ///
- /// This implies that the ABI has no primary base class, meaning
- /// that it has no base classes that are suitable under the conditions
- /// of the ABI.
- bool hasOwnVFPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->HasOwnVFPtr;
- }
-
- /// hasVFPtr - Does this class have a virtual function table pointer
- /// that can be extended by a derived class? This is synonymous with
- /// this class having a VFPtr at offset zero.
- bool hasExtendableVFPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->HasExtendableVFPtr;
- }
-
- /// hasOwnVBPtr - Does this class provide its own virtual-base
- /// table pointer, rather than inheriting one from a primary base
- /// class?
- ///
- /// This implies that the ABI has no primary base class, meaning
- /// that it has no base classes that are suitable under the conditions
- /// of the ABI.
- bool hasOwnVBPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return hasVBPtr() && !CXXInfo->BaseSharingVBPtr;
- }
-
- /// hasVBPtr - Does this class have a virtual function table pointer.
- bool hasVBPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return !CXXInfo->VBPtrOffset.isNegative();
- }
-
- CharUnits getRequiredAlignment() const {
- return RequiredAlignment;
- }
-
- bool hasZeroSizedSubObject() const {
- return CXXInfo && CXXInfo->HasZeroSizedSubObject;
- }
-
- bool leadsWithZeroSizedBase() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->LeadsWithZeroSizedBase;
- }
-
- /// getVBPtrOffset - Get the offset for virtual base table pointer.
- /// This is only meaningful with the Microsoft ABI.
- CharUnits getVBPtrOffset() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->VBPtrOffset;
- }
-
- const CXXRecordDecl *getBaseSharingVBPtr() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->BaseSharingVBPtr;
- }
-
- const VBaseOffsetsMapTy &getVBaseOffsetsMap() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->VBaseOffsets;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
deleted file mode 100644
index e6f7583..0000000
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ /dev/null
@@ -1,2805 +0,0 @@
-//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the RecursiveASTVisitor interface, which recursively
-// traverses the entire AST.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
-#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
-
-#include <type_traits>
-
-#include "clang/AST/Attr.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExprOpenMP.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
-#include "clang/AST/StmtOpenMP.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TypeLoc.h"
-
-// The following three macros are used for meta programming. The code
-// using them is responsible for defining macro OPERATOR().
-
-// All unary operators.
-#define UNARYOP_LIST() \
- OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \
- OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \
- OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \
- OPERATOR(Extension) OPERATOR(Coawait)
-
-// All binary operators (excluding compound assign operators).
-#define BINOP_LIST() \
- OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
- OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
- OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
- OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \
- OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
-
-// All compound assign operators.
-#define CAO_LIST() \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
- OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
-
-namespace clang {
-
-// A helper macro to implement short-circuiting when recursing. It
-// invokes CALL_EXPR, which must be a method call, on the derived
-// object (s.t. a user of RecursiveASTVisitor can override the method
-// in CALL_EXPR).
-#define TRY_TO(CALL_EXPR) \
- do { \
- if (!getDerived().CALL_EXPR) \
- return false; \
- } while (0)
-
-/// \brief A class that does preorder depth-first traversal on the
-/// entire Clang AST and visits each node.
-///
-/// This class performs three distinct tasks:
-/// 1. traverse the AST (i.e. go to each node);
-/// 2. at a given node, walk up the class hierarchy, starting from
-/// the node's dynamic type, until the top-most class (e.g. Stmt,
-/// Decl, or Type) is reached.
-/// 3. given a (node, class) combination, where 'class' is some base
-/// class of the dynamic type of 'node', call a user-overridable
-/// function to actually visit the node.
-///
-/// These tasks are done by three groups of methods, respectively:
-/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
-/// for traversing an AST rooted at x. This method simply
-/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
-/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
-/// then recursively visits the child nodes of x.
-/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
-/// similarly.
-/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
-/// any child node of x. Instead, it first calls WalkUpFromBar(x)
-/// where Bar is the direct parent class of Foo (unless Foo has
-/// no parent), and then calls VisitFoo(x) (see the next list item).
-/// 3. VisitFoo(Foo *x) does task #3.
-///
-/// These three method groups are tiered (Traverse* > WalkUpFrom* >
-/// Visit*). A method (e.g. Traverse*) may call methods from the same
-/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
-/// It may not call methods from a higher tier.
-///
-/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
-/// is Foo's super class) before calling VisitFoo(), the result is
-/// that the Visit*() methods for a given node are called in the
-/// top-down order (e.g. for a node of type NamespaceDecl, the order will
-/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
-///
-/// This scheme guarantees that all Visit*() calls for the same AST
-/// node are grouped together. In other words, Visit*() methods for
-/// different nodes are never interleaved.
-///
-/// Clients of this visitor should subclass the visitor (providing
-/// themselves as the template argument, using the curiously recurring
-/// template pattern) and override any of the Traverse*, WalkUpFrom*,
-/// and Visit* methods for declarations, types, statements,
-/// expressions, or other AST nodes where the visitor should customize
-/// behavior. Most users only need to override Visit*. Advanced
-/// users may override Traverse* and WalkUpFrom* to implement custom
-/// traversal strategies. Returning false from one of these overridden
-/// functions will abort the entire traversal.
-///
-/// By default, this visitor tries to visit every part of the explicit
-/// source code exactly once. The default policy towards templates
-/// is to descend into the 'pattern' class or function body, not any
-/// explicit or implicit instantiations. Explicit specializations
-/// are still visited, and the patterns of partial specializations
-/// are visited separately. This behavior can be changed by
-/// overriding shouldVisitTemplateInstantiations() in the derived class
-/// to return true, in which case all known implicit and explicit
-/// instantiations will be visited at the same time as the pattern
-/// from which they were produced.
-template <typename Derived> class RecursiveASTVisitor {
-public:
- /// A queue used for performing data recursion over statements.
- /// Parameters involving this type are used to implement data
- /// recursion over Stmts and Exprs within this class, and should
- /// typically not be explicitly specified by derived classes.
- typedef SmallVectorImpl<Stmt *> DataRecursionQueue;
-
- /// \brief Return a reference to the derived class.
- Derived &getDerived() { return *static_cast<Derived *>(this); }
-
- /// \brief Return whether this visitor should recurse into
- /// template instantiations.
- bool shouldVisitTemplateInstantiations() const { return false; }
-
- /// \brief Return whether this visitor should recurse into the types of
- /// TypeLocs.
- bool shouldWalkTypesOfTypeLocs() const { return true; }
-
- /// \brief Return whether this visitor should recurse into implicit
- /// code, e.g., implicit constructors and destructors.
- bool shouldVisitImplicitCode() const { return false; }
-
- /// \brief Recursively visit a statement or expression, by
- /// dispatching to Traverse*() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is nullptr).
- bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
-
- /// \brief Recursively visit a type, by dispatching to
- /// Traverse*Type() based on the argument's getTypeClass() property.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type).
- bool TraverseType(QualType T);
-
- /// \brief Recursively visit a type with location, by dispatching to
- /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type location).
- bool TraverseTypeLoc(TypeLoc TL);
-
- /// \brief Recursively visit an attribute, by dispatching to
- /// Traverse*Attr() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type location).
- bool TraverseAttr(Attr *At);
-
- /// \brief Recursively visit a declaration, by dispatching to
- /// Traverse*Decl() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is NULL).
- bool TraverseDecl(Decl *D);
-
- /// \brief Recursively visit a C++ nested-name-specifier.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
-
- /// \brief Recursively visit a C++ nested-name-specifier with location
- /// information.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
-
- /// \brief Recursively visit a name with its location information.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
-
- /// \brief Recursively visit a template name and dispatch to the
- /// appropriate method.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseTemplateName(TemplateName Template);
-
- /// \brief Recursively visit a template argument and dispatch to the
- /// appropriate method for the argument type.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- // FIXME: migrate callers to TemplateArgumentLoc instead.
- bool TraverseTemplateArgument(const TemplateArgument &Arg);
-
- /// \brief Recursively visit a template argument location and dispatch to the
- /// appropriate method for the argument type.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
-
- /// \brief Recursively visit a set of template arguments.
- /// This can be overridden by a subclass, but it's not expected that
- /// will be needed -- this visitor always dispatches to another.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
- bool TraverseTemplateArguments(const TemplateArgument *Args,
- unsigned NumArgs);
-
- /// \brief Recursively visit a constructor initializer. This
- /// automatically dispatches to another visitor for the initializer
- /// expression, but not for the name of the initializer, so may
- /// be overridden for clients that need access to the name.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
-
- /// \brief Recursively visit a lambda capture.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
-
- /// \brief Recursively visit the body of a lambda expression.
- ///
- /// This provides a hook for visitors that need more context when visiting
- /// \c LE->getBody().
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaBody(LambdaExpr *LE, DataRecursionQueue *Queue = nullptr);
-
- /// \brief Recursively visit the syntactic or semantic form of an
- /// initialization list.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseSynOrSemInitListExpr(InitListExpr *S,
- DataRecursionQueue *Queue = nullptr);
-
- // ---- Methods on Attrs ----
-
- // \brief Visit an attribute.
- bool VisitAttr(Attr *A) { return true; }
-
-// Declare Traverse* and empty Visit* for all Attr classes.
-#define ATTR_VISITOR_DECLS_ONLY
-#include "clang/AST/AttrVisitor.inc"
-#undef ATTR_VISITOR_DECLS_ONLY
-
-// ---- Methods on Stmts ----
-
-private:
- template<typename T, typename U>
- struct has_same_member_pointer_type : std::false_type {};
- template<typename T, typename U, typename R, typename... P>
- struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
- : std::true_type {};
-
- // Traverse the given statement. If the most-derived traverse function takes a
- // data recursion queue, pass it on; otherwise, discard it. Note that the
- // first branch of this conditional must compile whether or not the derived
- // class can take a queue, so if we're taking the second arm, make the first
- // arm call our function rather than the derived class version.
-#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \
- (has_same_member_pointer_type<decltype( \
- &RecursiveASTVisitor::Traverse##NAME), \
- decltype(&Derived::Traverse##NAME)>::value \
- ? static_cast<typename std::conditional< \
- has_same_member_pointer_type< \
- decltype(&RecursiveASTVisitor::Traverse##NAME), \
- decltype(&Derived::Traverse##NAME)>::value, \
- Derived &, RecursiveASTVisitor &>::type>(*this) \
- .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \
- : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))
-
-// Try to traverse the given statement, or enqueue it if we're performing data
-// recursion in the middle of traversing another statement. Can only be called
-// from within a DEF_TRAVERSE_STMT body or similar context.
-#define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S) \
- do { \
- if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \
- return false; \
- } while (0)
-
-public:
-// Declare Traverse*() for all concrete Stmt classes.
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- bool Traverse##CLASS(CLASS *S, DataRecursionQueue *Queue = nullptr);
-#include "clang/AST/StmtNodes.inc"
- // The above header #undefs ABSTRACT_STMT and STMT upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
- bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
- bool VisitStmt(Stmt *S) { return true; }
-#define STMT(CLASS, PARENT) \
- bool WalkUpFrom##CLASS(CLASS *S) { \
- TRY_TO(WalkUpFrom##PARENT(S)); \
- TRY_TO(Visit##CLASS(S)); \
- return true; \
- } \
- bool Visit##CLASS(CLASS *S) { return true; }
-#include "clang/AST/StmtNodes.inc"
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
-// operator methods. Unary operators are not classes in themselves
-// (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME) \
- bool TraverseUnary##NAME(UnaryOperator *S, \
- DataRecursionQueue *Queue = nullptr) { \
- TRY_TO(WalkUpFromUnary##NAME(S)); \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \
- return true; \
- } \
- bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnaryOperator(S)); \
- TRY_TO(VisitUnary##NAME(S)); \
- return true; \
- } \
- bool VisitUnary##NAME(UnaryOperator *S) { return true; }
-
- UNARYOP_LIST()
-#undef OPERATOR
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
-// operator methods. Binary operators are not classes in themselves
-// (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
- bool TraverseBin##NAME(BINOP_TYPE *S, DataRecursionQueue *Queue = nullptr) { \
- TRY_TO(WalkUpFromBin##NAME(S)); \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS()); \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS()); \
- return true; \
- } \
- bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
- TRY_TO(VisitBin##NAME(S)); \
- return true; \
- } \
- bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
-
-#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
- BINOP_LIST()
-#undef OPERATOR
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
-// assignment methods. Compound assignment operators are not
-// classes in themselves (they're all opcodes in
-// CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
- GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
-
- CAO_LIST()
-#undef OPERATOR
-#undef GENERAL_BINOP_FALLBACK
-
-// ---- Methods on Types ----
-// FIXME: revamp to take TypeLoc's rather than Types.
-
-// 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"
- // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all Type classes.
- bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
- bool VisitType(Type *T) { return true; }
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
- TRY_TO(WalkUpFrom##BASE(T)); \
- TRY_TO(Visit##CLASS##Type(T)); \
- return true; \
- } \
- bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
-#include "clang/AST/TypeNodes.def"
-
-// ---- Methods on TypeLocs ----
-// FIXME: this currently just calls the matching Type methods
-
-// Declare Traverse*() for all concrete TypeLoc classes.
-#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
-#include "clang/AST/TypeLocNodes.def"
- // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
- bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
- bool VisitTypeLoc(TypeLoc TL) { return true; }
-
- // QualifiedTypeLoc and UnqualTypeLoc are not declared in
- // TypeNodes.def and thus need to be handled specially.
- bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
- return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
- }
- bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
- bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
- return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
- }
- bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
-
-// Note that BASE includes trailing 'Type' which CLASS doesn't.
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
- TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
- TRY_TO(Visit##CLASS##TypeLoc(TL)); \
- return true; \
- } \
- bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
-#include "clang/AST/TypeNodes.def"
-
-// ---- Methods on Decls ----
-
-// Declare Traverse*() for all concrete Decl classes.
-#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
-#include "clang/AST/DeclNodes.inc"
- // The above header #undefs ABSTRACT_DECL and DECL upon exit.
-
- // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
- bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
- bool VisitDecl(Decl *D) { return true; }
-#define DECL(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
- TRY_TO(WalkUpFrom##BASE(D)); \
- TRY_TO(Visit##CLASS##Decl(D)); \
- return true; \
- } \
- bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
-#include "clang/AST/DeclNodes.inc"
-
-private:
- // These are helper methods used by more than one Traverse* method.
- bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
-#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
- bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
- DEF_TRAVERSE_TMPL_INST(Class)
- DEF_TRAVERSE_TMPL_INST(Var)
- DEF_TRAVERSE_TMPL_INST(Function)
-#undef DEF_TRAVERSE_TMPL_INST
- bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
- unsigned Count);
- bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
- bool TraverseRecordHelper(RecordDecl *D);
- bool TraverseCXXRecordHelper(CXXRecordDecl *D);
- bool TraverseDeclaratorHelper(DeclaratorDecl *D);
- bool TraverseDeclContextHelper(DeclContext *DC);
- bool TraverseFunctionHelper(FunctionDecl *D);
- bool TraverseVarHelper(VarDecl *D);
- bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
- bool TraverseOMPLoopDirective(OMPLoopDirective *S);
- bool TraverseOMPClause(OMPClause *C);
-#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
-#include "clang/Basic/OpenMPKinds.def"
- /// \brief Process clauses with list of variables.
- template <typename T> bool VisitOMPClauseList(T *Node);
-
- bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
-};
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
- DataRecursionQueue *Queue) {
-#define DISPATCH_STMT(NAME, CLASS, VAR) \
- return TRAVERSE_STMT_BASE(NAME, CLASS, VAR, Queue);
-
- // If we have a binary expr, dispatch to the subcode of the binop. A smart
- // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
- // below.
- if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
- switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case BO_##NAME: \
- DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
-
- BINOP_LIST()
-#undef OPERATOR
-#undef BINOP_LIST
-
-#define OPERATOR(NAME) \
- case BO_##NAME##Assign: \
- DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
-
- CAO_LIST()
-#undef OPERATOR
-#undef CAO_LIST
- }
- } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
- switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case UO_##NAME: \
- DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
-
- UNARYOP_LIST()
-#undef OPERATOR
-#undef UNARYOP_LIST
- }
- }
-
- // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
- switch (S->getStmtClass()) {
- case Stmt::NoStmtClass:
- break;
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: \
- DISPATCH_STMT(CLASS, CLASS, S);
-#include "clang/AST/StmtNodes.inc"
- }
-
- return true;
-}
-
-#undef DISPATCH_STMT
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S,
- DataRecursionQueue *Queue) {
- if (!S)
- return true;
-
- if (Queue) {
- Queue->push_back(S);
- return true;
- }
-
- SmallVector<Stmt *, 8> LocalQueue;
- LocalQueue.push_back(S);
-
- while (!LocalQueue.empty()) {
- Stmt *CurrS = LocalQueue.pop_back_val();
-
- size_t N = LocalQueue.size();
- TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
- // Process new children in the order they were added.
- std::reverse(LocalQueue.begin() + N, LocalQueue.end());
- }
-
- return true;
-}
-
-#define DISPATCH(NAME, CLASS, VAR) \
- return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
- if (T.isNull())
- return true;
-
- switch (T->getTypeClass()) {
-#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- case Type::CLASS: \
- DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
-#include "clang/AST/TypeNodes.def"
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
- if (TL.isNull())
- return true;
-
- switch (TL.getTypeLocClass()) {
-#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- case TypeLoc::CLASS: \
- return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
-#include "clang/AST/TypeLocNodes.def"
- }
-
- return true;
-}
-
-// Define the Traverse*Attr(Attr* A) methods
-#define VISITORCLASS RecursiveASTVisitor
-#include "clang/AST/AttrVisitor.inc"
-#undef VISITORCLASS
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
- if (!D)
- return true;
-
- // As a syntax visitor, by default we want to ignore declarations for
- // implicit declarations (ones not typed explicitly by the user).
- if (!getDerived().shouldVisitImplicitCode() && D->isImplicit())
- return true;
-
- switch (D->getKind()) {
-#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- case Decl::CLASS: \
- if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
- return false; \
- 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;
-}
-
-#undef DISPATCH
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
- NestedNameSpecifier *NNS) {
- if (!NNS)
- return true;
-
- if (NNS->getPrefix())
- TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- return true;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
- NestedNameSpecifierLoc NNS) {
- if (!NNS)
- return true;
-
- if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
- TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
-
- switch (NNS.getNestedNameSpecifier()->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- return true;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
- break;
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
- DeclarationNameInfo NameInfo) {
- switch (NameInfo.getName().getNameKind()) {
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
- TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
-
- break;
-
- case DeclarationName::Identifier:
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXOperatorName:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXUsingDirective:
- break;
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
- if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
- TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
- else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
- TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
- const TemplateArgument &Arg) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::NullPtr:
- return true;
-
- case TemplateArgument::Type:
- return getDerived().TraverseType(Arg.getAsType());
-
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
-
- case TemplateArgument::Expression:
- return getDerived().TraverseStmt(Arg.getAsExpr());
-
- case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
- }
-
- return true;
-}
-
-// FIXME: no template name location?
-// FIXME: no source locations for a template argument pack?
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
- const TemplateArgumentLoc &ArgLoc) {
- const TemplateArgument &Arg = ArgLoc.getArgument();
-
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::NullPtr:
- return true;
-
- case TemplateArgument::Type: {
- // FIXME: how can TSI ever be NULL?
- if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
- return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
- else
- return getDerived().TraverseType(Arg.getAsType());
- }
-
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- if (ArgLoc.getTemplateQualifierLoc())
- TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
- ArgLoc.getTemplateQualifierLoc()));
- return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
-
- case TemplateArgument::Expression:
- return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
-
- case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
- const TemplateArgument *Args, unsigned NumArgs) {
- for (unsigned I = 0; I != NumArgs; ++I) {
- TRY_TO(TraverseTemplateArgument(Args[I]));
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
- CXXCtorInitializer *Init) {
- if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-
- if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
- TRY_TO(TraverseStmt(Init->getInit()));
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
- const LambdaCapture *C) {
- if (LE->isInitCapture(C))
- TRY_TO(TraverseDecl(C->getCapturedVar()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(
- LambdaExpr *LE, DataRecursionQueue *Queue) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(LE->getBody());
- return true;
-}
-
-// ----------------- Type traversal -----------------
-
-// This macro makes available a variable T, the passed-in type.
-#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
- TRY_TO(WalkUpFrom##TYPE(T)); \
- { CODE; } \
- return true; \
- }
-
-DEF_TRAVERSE_TYPE(BuiltinType, {})
-
-DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
-
-DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(BlockPointerType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(LValueReferenceType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(RValueReferenceType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseType(QualType(T->getClass(), 0)));
- TRY_TO(TraverseType(T->getPointeeType()));
-})
-
-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(IncompleteArrayType,
- { TRY_TO(TraverseType(T->getElementType())); })
-
-DEF_TRAVERSE_TYPE(VariableArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- TRY_TO(TraverseStmt(T->getSizeExpr()));
-})
-
-DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
-})
-
-DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- TRY_TO(TraverseType(T->getElementType()));
-})
-
-DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
-
-DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
-
-DEF_TRAVERSE_TYPE(FunctionNoProtoType,
- { TRY_TO(TraverseType(T->getReturnType())); })
-
-DEF_TRAVERSE_TYPE(FunctionProtoType, {
- TRY_TO(TraverseType(T->getReturnType()));
-
- for (const auto &A : T->param_types()) {
- TRY_TO(TraverseType(A));
- }
-
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
-
- if (Expr *NE = T->getNoexceptExpr())
- TRY_TO(TraverseStmt(NE));
-})
-
-DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
-DEF_TRAVERSE_TYPE(TypedefType, {})
-
-DEF_TRAVERSE_TYPE(TypeOfExprType,
- { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
-
-DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
-
-DEF_TRAVERSE_TYPE(DecltypeType,
- { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
-
-DEF_TRAVERSE_TYPE(UnaryTransformType, {
- TRY_TO(TraverseType(T->getBaseType()));
- TRY_TO(TraverseType(T->getUnderlyingType()));
-})
-
-DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
-
-DEF_TRAVERSE_TYPE(RecordType, {})
-DEF_TRAVERSE_TYPE(EnumType, {})
-DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
-
-DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
-})
-
-DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
-
-DEF_TRAVERSE_TYPE(AttributedType,
- { TRY_TO(TraverseType(T->getModifiedType())); })
-
-DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
-
-DEF_TRAVERSE_TYPE(ElaboratedType, {
- if (T->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- }
- TRY_TO(TraverseType(T->getNamedType()));
-})
-
-DEF_TRAVERSE_TYPE(DependentNameType,
- { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
-
-DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
-})
-
-DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
-
-DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
-
-DEF_TRAVERSE_TYPE(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (T->getBaseType().getTypePtr() != T)
- TRY_TO(TraverseType(T->getBaseType()));
- for (auto typeArg : T->getTypeArgsAsWritten()) {
- TRY_TO(TraverseType(typeArg));
- }
-})
-
-DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
-
-DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
-
-#undef DEF_TRAVERSE_TYPE
-
-// ----------------- TypeLoc traversal -----------------
-
-// This macro makes available a variable TL, the passed-in TypeLoc.
-// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
-// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
-// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
-// continue to work.
-#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
- if (getDerived().shouldWalkTypesOfTypeLocs()) \
- TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
- TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
- { CODE; } \
- return true; \
- }
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
- // Move this over to the 'main' typeloc tree. Note that this is a
- // move -- we pretend that we were really looking at the unqualified
- // typeloc all along -- rather than a recursion, so we don't follow
- // the normal CRTP plan of going through
- // getDerived().TraverseTypeLoc. If we did, we'd be traversing
- // twice for the same type (once as a QualifiedTypeLoc version of
- // the type, once as an UnqualifiedTypeLoc version of the type),
- // which in effect means we'd call VisitTypeLoc twice with the
- // 'same' type. This solves that problem, at the cost of never
- // seeing the qualified version of the type (unless the client
- // subclasses TraverseQualifiedTypeLoc themselves). It's not a
- // perfect solution. A perfect solution probably requires making
- // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
- // wrapper around Type* -- rather than being its own class in the
- // type hierarchy.
- return TraverseTypeLoc(TL.getUnqualifiedLoc());
-}
-
-DEF_TRAVERSE_TYPELOC(BuiltinType, {})
-
-// FIXME: ComplexTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(ComplexType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-})
-
-DEF_TRAVERSE_TYPELOC(PointerType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-DEF_TRAVERSE_TYPELOC(BlockPointerType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-DEF_TRAVERSE_TYPELOC(LValueReferenceType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-DEF_TRAVERSE_TYPELOC(RValueReferenceType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-// FIXME: location of base class?
-// We traverse this in the type case as well, but how is it not reached through
-// the pointee type?
-DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(AdjustedType,
- { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
-
-DEF_TRAVERSE_TYPELOC(DecayedType,
- { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
- // This isn't available for ArrayType, but is for the ArrayTypeLoc.
- TRY_TO(TraverseStmt(TL.getSizeExpr()));
- return true;
-}
-
-DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
-})
-
-DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
-})
-
-DEF_TRAVERSE_TYPELOC(VariableArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
-})
-
-DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
-})
-
-// FIXME: order? why not size expr first?
-// FIXME: base VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
- if (TL.getTypePtr()->getSizeExpr())
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-})
-
-// FIXME: VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(VectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-})
-
-// FIXME: size and attributes
-// FIXME: base VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(ExtVectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-})
-
-DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
- { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
-
-// FIXME: location of exception specifications (attributes?)
-DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
-
- const FunctionProtoType *T = TL.getTypePtr();
-
- for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
- if (TL.getParam(I)) {
- TRY_TO(TraverseDecl(TL.getParam(I)));
- } else if (I < T->getNumParams()) {
- TRY_TO(TraverseType(T->getParamType(I)));
- }
- }
-
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
-
- if (Expr *NE = T->getNoexceptExpr())
- TRY_TO(TraverseStmt(NE));
-})
-
-DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
-DEF_TRAVERSE_TYPELOC(TypedefType, {})
-
-DEF_TRAVERSE_TYPELOC(TypeOfExprType,
- { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
-
-DEF_TRAVERSE_TYPELOC(TypeOfType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
-})
-
-// FIXME: location of underlying expr
-DEF_TRAVERSE_TYPELOC(DecltypeType, {
- TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
-})
-
-DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(AutoType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
-})
-
-DEF_TRAVERSE_TYPELOC(RecordType, {})
-DEF_TRAVERSE_TYPELOC(EnumType, {})
-DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
-
-// FIXME: use the loc for the template name?
-DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
-})
-
-DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
-
-DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
-
-DEF_TRAVERSE_TYPELOC(AttributedType,
- { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
-
-DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
- TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
-
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
-})
-
-DEF_TRAVERSE_TYPELOC(PackExpansionType,
- { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
-
-DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
-
-DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
- TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
- for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
- TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
-})
-
-DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-
-DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
-
-#undef DEF_TRAVERSE_TYPELOC
-
-// ----------------- Decl traversal -----------------
-//
-// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
-// the children that come from the DeclContext associated with it.
-// Therefore each Traverse* only needs to worry about children other
-// than those.
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
- if (!DC)
- return true;
-
- for (auto *Child : DC->decls()) {
- // BlockDecls and CapturedDecls are traversed through BlockExprs and
- // CapturedStmts respectively.
- if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
- TRY_TO(TraverseDecl(Child));
- }
-
- return true;
-}
-
-// This macro makes available a variable D, the passed-in decl.
-#define DEF_TRAVERSE_DECL(DECL, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
- TRY_TO(WalkUpFrom##DECL(D)); \
- { CODE; } \
- TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
- return true; \
- }
-
-DEF_TRAVERSE_DECL(AccessSpecDecl, {})
-
-DEF_TRAVERSE_DECL(BlockDecl, {
- if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- TRY_TO(TraverseStmt(D->getBody()));
- for (const auto &I : D->captures()) {
- if (I.hasCopyExpr()) {
- TRY_TO(TraverseStmt(I.getCopyExpr()));
- }
- }
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
-})
-
-DEF_TRAVERSE_DECL(CapturedDecl, {
- TRY_TO(TraverseStmt(D->getBody()));
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
-})
-
-DEF_TRAVERSE_DECL(EmptyDecl, {})
-
-DEF_TRAVERSE_DECL(FileScopeAsmDecl,
- { TRY_TO(TraverseStmt(D->getAsmString())); })
-
-DEF_TRAVERSE_DECL(ImportDecl, {})
-
-DEF_TRAVERSE_DECL(FriendDecl, {
- // Friend is either decl or a type.
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
-})
-
-DEF_TRAVERSE_DECL(FriendTemplateDecl, {
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
- TemplateParameterList *TPL = D->getTemplateParameterList(I);
- for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
- ITPL != ETPL; ++ITPL) {
- TRY_TO(TraverseDecl(*ITPL));
- }
- }
-})
-
-DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
- TRY_TO(TraverseDecl(D->getSpecialization()));
-
- if (D->hasExplicitTemplateArgs()) {
- const TemplateArgumentListInfo &args = D->templateArgs();
- TRY_TO(TraverseTemplateArgumentLocsHelper(args.getArgumentArray(),
- args.size()));
- }
-})
-
-DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
-
-DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
- })
-
-DEF_TRAVERSE_DECL(StaticAssertDecl, {
- TRY_TO(TraverseStmt(D->getAssertExpr()));
- TRY_TO(TraverseStmt(D->getMessage()));
-})
-
-DEF_TRAVERSE_DECL(
- TranslationUnitDecl,
- {// Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
-
-DEF_TRAVERSE_DECL(ExternCContextDecl, {})
-
-DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-
- // We shouldn't traverse an aliased namespace, since it will be
- // defined (and, therefore, traversed) somewhere else.
- //
- // This return statement makes sure the traversal of nodes in
- // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
- // is skipped - don't remove it.
- return true;
-})
-
-DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
- })
-
-DEF_TRAVERSE_DECL(
- NamespaceDecl,
- {// Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
-
-DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
- if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
- for (auto typeParam : *typeParamList) {
- TRY_TO(TraverseObjCTypeParamDecl(typeParam));
- }
- }
-})
-
-DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
- if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
- for (auto typeParam : *typeParamList) {
- TRY_TO(TraverseObjCTypeParamDecl(typeParam));
- }
- }
-
- if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
- TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
- }
-})
-
-DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
- })
-
-DEF_TRAVERSE_DECL(ObjCMethodDecl, {
- if (D->getReturnTypeSourceInfo()) {
- TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
- }
- for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
- }
- if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody()));
- }
- return true;
-})
-
-DEF_TRAVERSE_DECL(ObjCTypeParamDecl, {
- if (D->hasExplicitBound()) {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type alias, not something that was written in the
- // source.
- }
-})
-
-DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
- if (D->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- else
- TRY_TO(TraverseType(D->getType()));
- return true;
-})
-
-DEF_TRAVERSE_DECL(UsingDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-})
-
-DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-})
-
-DEF_TRAVERSE_DECL(UsingShadowDecl, {})
-
-DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
- for (auto *I : D->varlists()) {
- TRY_TO(TraverseStmt(I));
- }
-})
-
-// A helper method for TemplateDecl's children.
-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));
- }
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
- ClassTemplateDecl *D) {
- for (auto *SD : D->specializations()) {
- for (auto *RD : SD->redecls()) {
- // We don't want to visit injected-class-names in this traversal.
- if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
- continue;
-
- switch (
- cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
- // Visit the implicit instantiations with the requested pattern.
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- TRY_TO(TraverseDecl(RD));
- break;
-
- // We don't need to do anything on an explicit instantiation
- // or explicit specialization because there will be an explicit
- // node for it elsewhere.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- case TSK_ExplicitSpecialization:
- break;
- }
- }
- }
-
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
- VarTemplateDecl *D) {
- for (auto *SD : D->specializations()) {
- for (auto *RD : SD->redecls()) {
- switch (
- cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- TRY_TO(TraverseDecl(RD));
- break;
-
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- case TSK_ExplicitSpecialization:
- break;
- }
- }
- }
-
- return true;
-}
-
-// A helper method for traversing the instantiations of a
-// function while skipping its specializations.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
- FunctionTemplateDecl *D) {
- for (auto *FD : D->specializations()) {
- for (auto *RD : FD->redecls()) {
- switch (RD->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- // We don't know what kind of FunctionDecl this is.
- TRY_TO(TraverseDecl(RD));
- break;
-
- // FIXME: For now traverse explicit instantiations here. Change that
- // once they are represented as dedicated nodes in the AST.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- TRY_TO(TraverseDecl(RD));
- break;
-
- case TSK_ExplicitSpecialization:
- break;
- }
- }
- }
-
- return true;
-}
-
-// This macro unifies the traversal of class, variable and function
-// template declarations.
-#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
- DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
- TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
- \
- /* By default, we do not traverse the instantiations of \
- class templates since they do not appear in the user code. The \
- following code optionally traverses them. \
- \
- We only traverse the class instantiations when we see the canonical \
- declaration of the template, to ensure we only visit them once. */ \
- if (getDerived().shouldVisitTemplateInstantiations() && \
- D == D->getCanonicalDecl()) \
- TRY_TO(TraverseTemplateInstantiations(D)); \
- \
- /* Note that getInstantiatedFromMemberTemplate() is just a link \
- from a template instantiation back to the template from which \
- it was instantiated, and thus should not be traversed. */ \
- })
-
-DEF_TRAVERSE_TMPL_DECL(Class)
-DEF_TRAVERSE_TMPL_DECL(Var)
-DEF_TRAVERSE_TMPL_DECL(Function)
-
-DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
- // D is the "T" in something like
- // template <template <typename> class T> class container { };
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
- TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
- }
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-})
-
-DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-})
-
-DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
- // D is the "T" in something like "template<typename T> class vector;"
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_DECL(TypedefDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the typedef, not something that was written in the
- // source.
-})
-
-DEF_TRAVERSE_DECL(TypeAliasDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type alias, not something that was written in the
- // source.
-})
-
-DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-})
-
-DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
- // A dependent using declaration which was marked with 'typename'.
- // template<class T> class A : public B<T> { using typename B<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the
- // source.
-})
-
-DEF_TRAVERSE_DECL(EnumDecl, {
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // The enumerators are already traversed by
- // decls_begin()/decls_end().
-})
-
-// Helper methods for RecordDecl and its children.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the source.
-
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
- if (!TraverseRecordHelper(D))
- return false;
- if (D->isCompleteDefinition()) {
- for (const auto &I : D->bases()) {
- TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
- }
- // We don't traverse the friends or the conversions, as they are
- // already in decls_begin()/decls_end().
- }
- return true;
-}
-
-DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
-
-DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
-
-#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \
- DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
- /* For implicit instantiations ("set<int> x;"), we don't want to \
- recurse at all, since the instatiated template isn't written in \
- the source code anywhere. (Note the instatiated *type* -- \
- set<int> -- is written, and will still get a callback of \
- TemplateSpecializationType). For explicit instantiations \
- ("template set<int>;"), we do need a callback, since this \
- is the only callback that's made for this instantiation. \
- We use getTypeAsWritten() to distinguish. */ \
- if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
- \
- if (!getDerived().shouldVisitTemplateInstantiations() && \
- D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \
- /* Returning from here skips traversing the \
- declaration context of the *TemplateSpecializationDecl \
- (embedded in the DEF_TRAVERSE_DECL() macro) \
- which contains the instantiated members of the template. */ \
- return true; \
- })
-
-DEF_TRAVERSE_TMPL_SPEC_DECL(Class)
-DEF_TRAVERSE_TMPL_SPEC_DECL(Var)
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
- const TemplateArgumentLoc *TAL, unsigned Count) {
- for (unsigned I = 0; I < Count; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
- }
- return true;
-}
-
-#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
- DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
- /* The partial specialization. */ \
- if (TemplateParameterList *TPL = D->getTemplateParameters()) { \
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \
- I != E; ++I) { \
- TRY_TO(TraverseDecl(*I)); \
- } \
- } \
- /* The args that remains unspecialized. */ \
- TRY_TO(TraverseTemplateArgumentLocsHelper( \
- D->getTemplateArgsAsWritten()->getTemplateArgs(), \
- D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
- \
- /* Don't need the *TemplatePartialSpecializationHelper, even \
- though that's our parent class -- we already visit all the \
- template args here. */ \
- TRY_TO(Traverse##DECLKIND##Helper(D)); \
- \
- /* Instantiations will have been visited with the primary template. */ \
- })
-
-DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
-DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var)
-
-DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
-
-DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
- // Like UnresolvedUsingTypenameDecl, but without the 'typename':
- // template <class T> Class A : public Base<T> { using Base<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-})
-
-DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- if (D->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- else
- TRY_TO(TraverseType(D->getType()));
- return true;
-}
-
-DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
-
-DEF_TRAVERSE_DECL(FieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- else if (D->hasInClassInitializer())
- TRY_TO(TraverseStmt(D->getInClassInitializer()));
-})
-
-DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
-})
-
-DEF_TRAVERSE_DECL(ObjCIvarDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
-})
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-
- // If we're an explicit template specialization, iterate over the
- // template args that were explicitly specified. If we were doing
- // this in typing order, we'd do it between the return type and
- // the function args, but both are handled by the FunctionTypeLoc
- // above, so we have to choose one side. I've decided to do before.
- if (const FunctionTemplateSpecializationInfo *FTSI =
- D->getTemplateSpecializationInfo()) {
- if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
- FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
- // A specialization might not have explicit template arguments if it has
- // a templated return type and concrete arguments.
- if (const ASTTemplateArgumentListInfo *TALI =
- FTSI->TemplateArgumentsAsWritten) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
- TALI->NumTemplateArgs));
- }
- }
- }
-
- // Visit the function type itself, which can be either
- // FunctionNoProtoType or FunctionProtoType, or a typedef. This
- // also covers the return type and the function parameters,
- // including exception specifications.
- if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
- } else if (getDerived().shouldVisitImplicitCode()) {
- // Visit parameter variable declarations of the implicit function
- // if the traverser is visiting implicit code. Parameter variable
- // declarations do not have valid TypeSourceInfo, so to visit them
- // we need to traverse the declarations explicitly.
- for (FunctionDecl::param_const_iterator I = D->param_begin(),
- E = D->param_end();
- I != E; ++I)
- TRY_TO(TraverseDecl(*I));
- }
-
- if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
- // Constructor initializers.
- for (auto *I : Ctor->inits()) {
- TRY_TO(TraverseConstructorInitializer(I));
- }
- }
-
- if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody())); // Function body.
- }
- return true;
-}
-
-DEF_TRAVERSE_DECL(FunctionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-DEF_TRAVERSE_DECL(CXXMethodDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-DEF_TRAVERSE_DECL(CXXConstructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-// CXXConversionDecl is the declaration of a type conversion operator.
-// It's not a cast expression.
-DEF_TRAVERSE_DECL(CXXConversionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-DEF_TRAVERSE_DECL(CXXDestructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- return TraverseFunctionHelper(D);
-})
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
- TRY_TO(TraverseDeclaratorHelper(D));
- // Default params are taken care of when we traverse the ParmVarDecl.
- if (!isa<ParmVarDecl>(D) &&
- (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
- TRY_TO(TraverseStmt(D->getInit()));
- return true;
-}
-
-DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
-
-DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
-
-DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
- // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- TRY_TO(TraverseStmt(D->getDefaultArgument()));
-})
-
-DEF_TRAVERSE_DECL(ParmVarDecl, {
- TRY_TO(TraverseVarHelper(D));
-
- if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
-
- if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getDefaultArg()));
-})
-
-#undef DEF_TRAVERSE_DECL
-
-// ----------------- Stmt traversal -----------------
-//
-// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
-// over the children defined in children() (every stmt defines these,
-// though sometimes the range is empty). Each individual Traverse*
-// method only needs to worry about children other than those. To see
-// what children() does for a given class, see, e.g.,
-// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
-
-// This macro makes available a variable S, the passed-in stmt.
-#define DEF_TRAVERSE_STMT(STMT, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##STMT( \
- STMT *S, DataRecursionQueue *Queue) { \
- TRY_TO(WalkUpFrom##STMT(S)); \
- { CODE; } \
- for (Stmt *SubStmt : S->children()) { \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
- } \
- return true; \
- }
-
-DEF_TRAVERSE_STMT(GCCAsmStmt, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
- for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I));
- }
- // children() iterates over inputExpr and outputExpr.
-})
-
-DEF_TRAVERSE_STMT(
- MSAsmStmt,
- {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
- // added this needs to be implemented.
- })
-
-DEF_TRAVERSE_STMT(CXXCatchStmt, {
- TRY_TO(TraverseDecl(S->getExceptionDecl()));
- // children() iterates over the handler block.
-})
-
-DEF_TRAVERSE_STMT(DeclStmt, {
- for (auto *I : S->decls()) {
- TRY_TO(TraverseDecl(I));
- }
- // Suppress the default iteration over children() by
- // returning. Here's why: A DeclStmt looks like 'type var [=
- // initializer]'. The decls above already traverse over the
- // initializers, so we don't have to do it again (which
- // children() would do).
- return true;
-})
-
-// These non-expr stmts (most of them), do not need any action except
-// iterating over the children.
-DEF_TRAVERSE_STMT(BreakStmt, {})
-DEF_TRAVERSE_STMT(CXXTryStmt, {})
-DEF_TRAVERSE_STMT(CaseStmt, {})
-DEF_TRAVERSE_STMT(CompoundStmt, {})
-DEF_TRAVERSE_STMT(ContinueStmt, {})
-DEF_TRAVERSE_STMT(DefaultStmt, {})
-DEF_TRAVERSE_STMT(DoStmt, {})
-DEF_TRAVERSE_STMT(ForStmt, {})
-DEF_TRAVERSE_STMT(GotoStmt, {})
-DEF_TRAVERSE_STMT(IfStmt, {})
-DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
-DEF_TRAVERSE_STMT(LabelStmt, {})
-DEF_TRAVERSE_STMT(AttributedStmt, {})
-DEF_TRAVERSE_STMT(NullStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
-DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
-DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
-DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
-DEF_TRAVERSE_STMT(CXXForRangeStmt, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
- // Visit everything else only if shouldVisitImplicitCode().
- return true;
- }
-})
-DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
-})
-DEF_TRAVERSE_STMT(ReturnStmt, {})
-DEF_TRAVERSE_STMT(SwitchStmt, {})
-DEF_TRAVERSE_STMT(WhileStmt, {})
-
-DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(DeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
-})
-
-DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(MemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
-})
-
-DEF_TRAVERSE_STMT(
- ImplicitCastExpr,
- {// We don't traverse the cast type, as it's not written in the
- // source code.
- })
-
-DEF_TRAVERSE_STMT(CStyleCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXConstCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
- InitListExpr *S, DataRecursionQueue *Queue) {
- if (S) {
- TRY_TO(WalkUpFromInitListExpr(S));
- // All we need are the default actions. FIXME: use a helper function.
- for (Stmt *SubStmt : S->children()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt);
- }
- }
- 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.
-DEF_TRAVERSE_STMT(InitListExpr, {
- TRY_TO(TraverseSynOrSemInitListExpr(
- S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
- TRY_TO(TraverseSynOrSemInitListExpr(
- S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
- return true;
-})
-
-// GenericSelectionExpr is a special case because the types and expressions
-// are interleaved. We also need to watch out for null types (default
-// generic associations).
-DEF_TRAVERSE_STMT(GenericSelectionExpr, {
- TRY_TO(TraverseStmt(S->getControllingExpr()));
- for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
- if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
- TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAssocExpr(i));
- }
- return true;
-})
-
-// PseudoObjectExpr is a special case because of the weirdness with
-// syntactic expressions and opaque values.
-DEF_TRAVERSE_STMT(PseudoObjectExpr, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
- for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
- e = S->semantics_end();
- i != e; ++i) {
- Expr *sub = *i;
- if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
- sub = OVE->getSourceExpr();
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(sub);
- }
- return true;
-})
-
-DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
- // This is called for code like 'return T()' where T is a built-in
- // (i.e. non-class) type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXNewExpr, {
- // The child-iterator will pick up the other arguments.
- TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(OffsetOfExpr, {
- // The child-iterator will pick up the expression representing
- // the field.
- // FIMXE: for code like offsetof(Foo, a.b.c), should we get
- // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isArgumentType())
- TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXTypeidExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-})
-
-DEF_TRAVERSE_STMT(MSPropertySubscriptExpr, {})
-
-DEF_TRAVERSE_STMT(CXXUuidofExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(TypeTraitExpr, {
- for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
- TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(ExpressionTraitExpr,
- { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
-
-DEF_TRAVERSE_STMT(VAArgExpr, {
- // The child-iterator will pick up the expression argument.
- TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
- // This is called for code like 'return T()' where T is a class type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-
-// Walk only the visible parts of lambda expressions.
-DEF_TRAVERSE_STMT(LambdaExpr, {
- for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
- CEnd = S->explicit_capture_end();
- C != CEnd; ++C) {
- TRY_TO(TraverseLambdaCapture(S, C));
- }
-
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
-
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
- } else {
- if (S->hasExplicitParameters()) {
- // Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
- TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- } else if (S->hasExplicitResultType()) {
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
- }
-
- auto *T = Proto.getTypePtr();
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
-
- if (Expr *NE = T->getNoexceptExpr())
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE);
- }
-
- return TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue);
-})
-
-DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
- // This is called for code like 'T()', where T is a template argument.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-
-// These expressions all might take explicit template arguments.
-// We traverse those if so. FIXME: implement these.
-DEF_TRAVERSE_STMT(CXXConstructExpr, {})
-DEF_TRAVERSE_STMT(CallExpr, {})
-DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
-
-// These exprs (most of them), do not need any action except iterating
-// over the children.
-DEF_TRAVERSE_STMT(AddrLabelExpr, {})
-DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
-DEF_TRAVERSE_STMT(OMPArraySectionExpr, {})
-DEF_TRAVERSE_STMT(BlockExpr, {
- TRY_TO(TraverseDecl(S->getBlockDecl()));
- return true; // no child statements to loop through.
-})
-DEF_TRAVERSE_STMT(ChooseExpr, {})
-DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
-DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
-DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
-DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
-DEF_TRAVERSE_STMT(ExprWithCleanups, {})
-DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
-DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
-DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
- TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
- if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
- TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(CXXThisExpr, {})
-DEF_TRAVERSE_STMT(CXXThrowExpr, {})
-DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
-DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
-DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
-DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
-DEF_TRAVERSE_STMT(GNUNullExpr, {})
-DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
-DEF_TRAVERSE_STMT(NoInitExpr, {})
-DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
-DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
- if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
-DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
-DEF_TRAVERSE_STMT(ObjCMessageExpr, {
- if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
-DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
-DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
-DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
-DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
-DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ParenExpr, {})
-DEF_TRAVERSE_STMT(ParenListExpr, {})
-DEF_TRAVERSE_STMT(PredefinedExpr, {})
-DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
-DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
-DEF_TRAVERSE_STMT(StmtExpr, {})
-DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
-})
-
-DEF_TRAVERSE_STMT(SEHTryStmt, {})
-DEF_TRAVERSE_STMT(SEHExceptStmt, {})
-DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
-DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
-DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
-
-DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
-DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
-DEF_TRAVERSE_STMT(TypoExpr, {})
-DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
-
-// These operators (all of them) do not need any action except
-// iterating over the children.
-DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
-DEF_TRAVERSE_STMT(ConditionalOperator, {})
-DEF_TRAVERSE_STMT(UnaryOperator, {})
-DEF_TRAVERSE_STMT(BinaryOperator, {})
-DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
-DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
-DEF_TRAVERSE_STMT(PackExpansionExpr, {})
-DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
-DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
-DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
-DEF_TRAVERSE_STMT(CXXFoldExpr, {})
-DEF_TRAVERSE_STMT(AtomicExpr, {})
-
-// For coroutines expressions, traverse either the operand
-// as written or the implied calls, depending on what the
-// derived class requests.
-DEF_TRAVERSE_STMT(CoroutineBodyStmt, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
- return true;
- }
-})
-DEF_TRAVERSE_STMT(CoreturnStmt, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- return true;
- }
-})
-DEF_TRAVERSE_STMT(CoawaitExpr, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- return true;
- }
-})
-DEF_TRAVERSE_STMT(CoyieldExpr, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- return true;
- }
-})
-
-// These literals (all of them) do not need any action.
-DEF_TRAVERSE_STMT(IntegerLiteral, {})
-DEF_TRAVERSE_STMT(CharacterLiteral, {})
-DEF_TRAVERSE_STMT(FloatingLiteral, {})
-DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
-DEF_TRAVERSE_STMT(StringLiteral, {})
-DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
-DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
-DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
-DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
-
-// Traverse OpenCL: AsType, Convert.
-DEF_TRAVERSE_STMT(AsTypeExpr, {})
-
-// OpenMP directives.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
- OMPExecutableDirective *S) {
- for (auto *C : S->clauses()) {
- TRY_TO(TraverseOMPClause(C));
- }
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
- return TraverseOMPExecutableDirective(S);
-}
-
-DEF_TRAVERSE_STMT(OMPParallelDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPSectionsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPSectionDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPSingleDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPMasterDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPCriticalDirective, {
- TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
- TRY_TO(TraverseOMPExecutableDirective(S));
-})
-
-DEF_TRAVERSE_STMT(OMPParallelForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPBarrierDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPCancelDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPFlushDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPOrderedDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPAtomicDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTargetDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTargetDataDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTeamsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-DEF_TRAVERSE_STMT(OMPDistributeDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
-
-// OpenMP clauses.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
- if (!C)
- return true;
- switch (C->getClauseKind()) {
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_##Name: \
- TRY_TO(Visit##Class(static_cast<Class *>(C))); \
- break;
-#include "clang/Basic/OpenMPKinds.def"
- case OMPC_threadprivate:
- case OMPC_unknown:
- break;
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
- TRY_TO(TraverseStmt(C->getCondition()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
- TRY_TO(TraverseStmt(C->getCondition()));
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
- TRY_TO(TraverseStmt(C->getNumThreads()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
- TRY_TO(TraverseStmt(C->getSafelen()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
- TRY_TO(TraverseStmt(C->getSimdlen()));
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
- TRY_TO(TraverseStmt(C->getNumForLoops()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
- TRY_TO(TraverseStmt(C->getChunkSize()));
- TRY_TO(TraverseStmt(C->getHelperChunkSize()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *C) {
- TRY_TO(TraverseStmt(C->getNumForLoops()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) {
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPNogroupClause(OMPNogroupClause *) {
- return true;
-}
-
-template <typename Derived>
-template <typename T>
-bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
- for (auto *E : Node->varlists()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->private_copies()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
- OMPFirstprivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->private_copies()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->inits()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
- OMPLastprivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->private_copies()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->source_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->destination_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->assignment_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
- TRY_TO(TraverseStmt(C->getStep()));
- TRY_TO(TraverseStmt(C->getCalcStep()));
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->privates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->inits()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->updates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->finals()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
- TRY_TO(TraverseStmt(C->getAlignment()));
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->source_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->destination_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->assignment_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
- OMPCopyprivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->source_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->destination_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->assignment_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
- TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->privates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->lhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->rhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->reduction_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) {
- TRY_TO(TraverseStmt(C->getDevice()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
- OMPNumTeamsClause *C) {
- TRY_TO(TraverseStmt(C->getNumTeams()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause(
- OMPThreadLimitClause *C) {
- TRY_TO(TraverseStmt(C->getThreadLimit()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause(
- OMPPriorityClause *C) {
- TRY_TO(TraverseStmt(C->getPriority()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause(
- OMPGrainsizeClause *C) {
- TRY_TO(TraverseStmt(C->getGrainsize()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPNumTasksClause(
- OMPNumTasksClause *C) {
- TRY_TO(TraverseStmt(C->getNumTasks()));
- return true;
-}
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPHintClause(OMPHintClause *C) {
- TRY_TO(TraverseStmt(C->getHint()));
- return true;
-}
-
-// FIXME: look at the following tricky-seeming exprs to see if we
-// need to recurse on anything. These are ones that have methods
-// returning decls or qualtypes or nestednamespecifier -- though I'm
-// not sure if they own them -- or just seemed very complicated, or
-// had lots of sub-types to explore.
-//
-// VisitOverloadExpr and its children: recurse on template args? etc?
-
-// FIXME: go through all the stmts and exprs again, and see which of them
-// create new types, and recurse on the types (TypeLocs?) of those.
-// Candidates:
-//
-// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
-// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
-// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
-// Every class that has getQualifier.
-
-#undef DEF_TRAVERSE_STMT
-#undef TRAVERSE_STMT
-#undef TRAVERSE_STMT_BASE
-
-#undef TRY_TO
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
deleted file mode 100644
index eaa22f8..0000000
--- a/include/clang/AST/Redeclarable.h
+++ /dev/null
@@ -1,285 +0,0 @@
-//===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Redeclarable interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_REDECLARABLE_H
-#define LLVM_CLANG_AST_REDECLARABLE_H
-
-#include "clang/AST/ExternalASTSource.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Casting.h"
-#include <iterator>
-
-namespace clang {
-class ASTContext;
-
-/// \brief Provides common interface for the Decls that can be redeclared.
-template<typename decl_type>
-class Redeclarable {
-protected:
- class DeclLink {
- /// A pointer to a known latest declaration, either statically known or
- /// generationally updated as decls are added by an external source.
- typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
- &ExternalASTSource::CompleteRedeclChain>
- KnownLatest;
-
- /// We store a pointer to the ASTContext in the UninitializedLatest
- /// pointer, but to avoid circular type dependencies when we steal the low
- /// bits of this pointer, we use a raw void* here.
- typedef const void *UninitializedLatest;
-
- typedef Decl *Previous;
-
- /// A pointer to either an uninitialized latest declaration (where either
- /// we've not yet set the previous decl or there isn't one), or to a known
- /// previous declaration.
- typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
-
- mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
-
- public:
- enum PreviousTag { PreviousLink };
- enum LatestTag { LatestLink };
-
- DeclLink(LatestTag, const ASTContext &Ctx)
- : Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
- DeclLink(PreviousTag, decl_type *D)
- : Next(NotKnownLatest(Previous(D))) {}
-
- bool NextIsPrevious() const {
- return Next.is<NotKnownLatest>() &&
- // FIXME: 'template' is required on the next line due to an
- // apparent clang bug.
- Next.get<NotKnownLatest>().template is<Previous>();
- }
-
- bool NextIsLatest() const { return !NextIsPrevious(); }
-
- decl_type *getNext(const decl_type *D) const {
- if (Next.is<NotKnownLatest>()) {
- NotKnownLatest NKL = Next.get<NotKnownLatest>();
- if (NKL.is<Previous>())
- return static_cast<decl_type*>(NKL.get<Previous>());
-
- // Allocate the generational 'most recent' cache now, if needed.
- Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
- NKL.get<UninitializedLatest>()),
- const_cast<decl_type *>(D));
- }
-
- return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
- }
-
- void setPrevious(decl_type *D) {
- assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
- Next = Previous(D);
- }
-
- void setLatest(decl_type *D) {
- assert(NextIsLatest() && "decl became canonical unexpectedly");
- if (Next.is<NotKnownLatest>()) {
- NotKnownLatest NKL = Next.get<NotKnownLatest>();
- Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
- NKL.get<UninitializedLatest>()),
- D);
- } else {
- auto Latest = Next.get<KnownLatest>();
- Latest.set(D);
- Next = Latest;
- }
- }
-
- void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
-
- Decl *getLatestNotUpdated() const {
- assert(NextIsLatest() && "expected a canonical decl");
- if (Next.is<NotKnownLatest>())
- return nullptr;
- return Next.get<KnownLatest>().getNotUpdated();
- }
- };
-
- static DeclLink PreviousDeclLink(decl_type *D) {
- return DeclLink(DeclLink::PreviousLink, D);
- }
-
- static DeclLink LatestDeclLink(const ASTContext &Ctx) {
- return DeclLink(DeclLink::LatestLink, Ctx);
- }
-
- /// \brief Points to the next redeclaration in the chain.
- ///
- /// If NextIsPrevious() is true, this is a link to the previous declaration
- /// of this same Decl. If NextIsLatest() is true, this is the first
- /// declaration and Link points to the latest declaration. For example:
- ///
- /// #1 int f(int x, int y = 1); // <pointer to #3, true>
- /// #2 int f(int x = 0, int y); // <pointer to #1, false>
- /// #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
- ///
- /// If there is only one declaration, it is <pointer to self, true>
- DeclLink RedeclLink;
- decl_type *First;
-
- decl_type *getNextRedeclaration() const {
- return RedeclLink.getNext(static_cast<const decl_type *>(this));
- }
-
-public:
- Redeclarable(const ASTContext &Ctx)
- : RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {}
-
- /// \brief Return the previous declaration of this declaration or NULL if this
- /// is the first declaration.
- decl_type *getPreviousDecl() {
- if (RedeclLink.NextIsPrevious())
- return getNextRedeclaration();
- return nullptr;
- }
- const decl_type *getPreviousDecl() const {
- return const_cast<decl_type *>(
- static_cast<const decl_type*>(this))->getPreviousDecl();
- }
-
- /// \brief Return the first declaration of this declaration or itself if this
- /// is the only declaration.
- decl_type *getFirstDecl() { return First; }
-
- /// \brief Return the first declaration of this declaration or itself if this
- /// is the only declaration.
- const decl_type *getFirstDecl() const { return First; }
-
- /// \brief True if this is the first declaration in its redeclaration chain.
- bool isFirstDecl() const { return RedeclLink.NextIsLatest(); }
-
- /// \brief Returns the most recent (re)declaration of this declaration.
- decl_type *getMostRecentDecl() {
- return getFirstDecl()->getNextRedeclaration();
- }
-
- /// \brief Returns the most recent (re)declaration of this declaration.
- const decl_type *getMostRecentDecl() const {
- return getFirstDecl()->getNextRedeclaration();
- }
-
- /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
- /// first and only declaration.
- void setPreviousDecl(decl_type *PrevDecl);
-
- /// \brief Iterates through all the redeclarations of the same decl.
- class redecl_iterator {
- /// Current - The current declaration.
- decl_type *Current;
- decl_type *Starter;
- bool PassedFirst;
-
- public:
- typedef decl_type* value_type;
- typedef decl_type* reference;
- typedef decl_type* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- redecl_iterator() : Current(nullptr) { }
- explicit redecl_iterator(decl_type *C)
- : Current(C), Starter(C), PassedFirst(false) { }
-
- reference operator*() const { return Current; }
- pointer operator->() const { return Current; }
-
- redecl_iterator& operator++() {
- assert(Current && "Advancing while iterator has reached end");
- // Sanity check to avoid infinite loop on invalid redecl chain.
- if (Current->isFirstDecl()) {
- if (PassedFirst) {
- assert(0 && "Passed first decl twice, invalid redecl chain!");
- Current = nullptr;
- return *this;
- }
- PassedFirst = true;
- }
-
- // Get either previous decl or latest decl.
- decl_type *Next = Current->getNextRedeclaration();
- Current = (Next != Starter) ? Next : nullptr;
- return *this;
- }
-
- redecl_iterator operator++(int) {
- redecl_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
-
- friend bool operator==(redecl_iterator x, redecl_iterator y) {
- return x.Current == y.Current;
- }
- friend bool operator!=(redecl_iterator x, redecl_iterator y) {
- return x.Current != y.Current;
- }
- };
-
- typedef llvm::iterator_range<redecl_iterator> redecl_range;
-
- /// \brief Returns an iterator range for all the redeclarations of the same
- /// decl. It will iterate at least once (when this decl is the only one).
- redecl_range redecls() const {
- return redecl_range(redecl_iterator(const_cast<decl_type *>(
- static_cast<const decl_type *>(this))),
- redecl_iterator());
- }
-
- redecl_iterator redecls_begin() const { return redecls().begin(); }
- redecl_iterator redecls_end() const { return redecls().end(); }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Get the primary declaration for a declaration from an AST file. That
-/// will be the first-loaded declaration.
-Decl *getPrimaryMergedDecl(Decl *D);
-
-/// \brief Provides common interface for the Decls that cannot be redeclared,
-/// but can be merged if the same declaration is brought in from multiple
-/// modules.
-template<typename decl_type>
-class Mergeable {
-public:
- Mergeable() {}
-
- /// \brief Return the first declaration of this declaration or itself if this
- /// is the only declaration.
- decl_type *getFirstDecl() {
- decl_type *D = static_cast<decl_type*>(this);
- if (!D->isFromASTFile())
- return D;
- return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
- }
-
- /// \brief Return the first declaration of this declaration or itself if this
- /// is the only declaration.
- const decl_type *getFirstDecl() const {
- const decl_type *D = static_cast<const decl_type*>(this);
- if (!D->isFromASTFile())
- return D;
- return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
- }
-
- /// \brief Returns true if this is the first declaration.
- bool isFirstDecl() const { return getFirstDecl() == this; }
-};
-
-}
-
-#endif
diff --git a/include/clang/AST/SelectorLocationsKind.h b/include/clang/AST/SelectorLocationsKind.h
deleted file mode 100644
index 6d903f8..0000000
--- a/include/clang/AST/SelectorLocationsKind.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===--- SelectorLocationsKind.h - Kind of selector locations ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Describes whether the identifier locations for a selector are "standard"
-// or not.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
-#define LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
-
-#include "clang/Basic/LLVM.h"
-
-namespace clang {
- class Selector;
- class SourceLocation;
- class Expr;
- class ParmVarDecl;
-
-/// \brief Whether all locations of the selector identifiers are in a
-/// "standard" position.
-enum SelectorLocationsKind {
- /// \brief Non-standard.
- SelLoc_NonStandard = 0,
-
- /// \brief For nullary selectors, immediately before the end:
- /// "[foo release]" / "-(void)release;"
- /// Or immediately before the arguments:
- /// "[foo first:1 second:2]" / "-(id)first:(int)x second:(int)y;
- SelLoc_StandardNoSpace = 1,
-
- /// \brief For nullary selectors, immediately before the end:
- /// "[foo release]" / "-(void)release;"
- /// Or with a space between the arguments:
- /// "[foo first: 1 second: 2]" / "-(id)first: (int)x second: (int)y;
- SelLoc_StandardWithSpace = 2
-};
-
-/// \brief Returns true if all \p SelLocs are in a "standard" location.
-SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ArrayRef<Expr *> Args,
- SourceLocation EndLoc);
-
-/// \brief Get the "standard" location of a selector identifier, e.g:
-/// For nullary selectors, immediately before ']': "[foo release]"
-///
-/// \param WithArgSpace if true the standard location is with a space apart
-/// before arguments: "[foo first: 1 second: 2]"
-/// If false: "[foo first:1 second:2]"
-SourceLocation getStandardSelectorLoc(unsigned Index,
- Selector Sel,
- bool WithArgSpace,
- ArrayRef<Expr *> Args,
- SourceLocation EndLoc);
-
-/// \brief Returns true if all \p SelLocs are in a "standard" location.
-SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
- ArrayRef<SourceLocation> SelLocs,
- ArrayRef<ParmVarDecl *> Args,
- SourceLocation EndLoc);
-
-/// \brief Get the "standard" location of a selector identifier, e.g:
-/// For nullary selectors, immediately before ']': "[foo release]"
-///
-/// \param WithArgSpace if true the standard location is with a space apart
-/// before arguments: "-(id)first: (int)x second: (int)y;"
-/// If false: "-(id)first:(int)x second:(int)y;"
-SourceLocation getStandardSelectorLoc(unsigned Index,
- Selector Sel,
- bool WithArgSpace,
- ArrayRef<ParmVarDecl *> Args,
- SourceLocation EndLoc);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
deleted file mode 100644
index e48b7dc..0000000
--- a/include/clang/AST/Stmt.h
+++ /dev/null
@@ -1,2196 +0,0 @@
-//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Stmt interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMT_H
-#define LLVM_CLANG_AST_STMT_H
-
-#include "clang/AST/DeclGroup.h"
-#include "clang/AST/StmtIterator.h"
-#include "clang/Basic/CapturedStmt.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <string>
-
-namespace llvm {
- class FoldingSetNodeID;
-}
-
-namespace clang {
- class ASTContext;
- class Attr;
- class CapturedDecl;
- class Decl;
- class Expr;
- class IdentifierInfo;
- class LabelDecl;
- class ParmVarDecl;
- class PrinterHelper;
- struct PrintingPolicy;
- class QualType;
- class RecordDecl;
- class SourceManager;
- class StringLiteral;
- class SwitchStmt;
- class Token;
- class VarDecl;
-
-//===----------------------------------------------------------------------===//
-// AST classes for statements.
-//===----------------------------------------------------------------------===//
-
-/// Stmt - This represents one statement.
-///
-class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt {
-public:
- enum StmtClass {
- NoStmtClass = 0,
-#define STMT(CLASS, PARENT) CLASS##Class,
-#define STMT_RANGE(BASE, FIRST, LAST) \
- first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
-#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
- first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
-#define ABSTRACT_STMT(STMT)
-#include "clang/AST/StmtNodes.inc"
- };
-
- // Make vanilla 'new' and 'delete' illegal for Stmts.
-protected:
- void *operator new(size_t bytes) LLVM_NOEXCEPT {
- llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
- }
- void operator delete(void *data) LLVM_NOEXCEPT {
- llvm_unreachable("Stmts cannot be released with regular 'delete'.");
- }
-
- class StmtBitfields {
- friend class Stmt;
-
- /// \brief The statement class.
- unsigned sClass : 8;
- };
- enum { NumStmtBits = 8 };
-
- class CompoundStmtBitfields {
- friend class CompoundStmt;
- unsigned : NumStmtBits;
-
- unsigned NumStmts : 32 - NumStmtBits;
- };
-
- class ExprBitfields {
- friend class Expr;
- friend class DeclRefExpr; // computeDependence
- friend class InitListExpr; // ctor
- friend class DesignatedInitExpr; // ctor
- friend class BlockDeclRefExpr; // ctor
- friend class ASTStmtReader; // deserialization
- friend class CXXNewExpr; // ctor
- friend class DependentScopeDeclRefExpr; // ctor
- friend class CXXConstructExpr; // ctor
- friend class CallExpr; // ctor
- friend class OffsetOfExpr; // ctor
- friend class ObjCMessageExpr; // ctor
- friend class ObjCArrayLiteral; // ctor
- friend class ObjCDictionaryLiteral; // ctor
- friend class ShuffleVectorExpr; // ctor
- friend class ParenListExpr; // ctor
- friend class CXXUnresolvedConstructExpr; // ctor
- friend class CXXDependentScopeMemberExpr; // ctor
- friend class OverloadExpr; // ctor
- friend class PseudoObjectExpr; // ctor
- friend class AtomicExpr; // ctor
- unsigned : NumStmtBits;
-
- unsigned ValueKind : 2;
- unsigned ObjectKind : 2;
- unsigned TypeDependent : 1;
- unsigned ValueDependent : 1;
- unsigned InstantiationDependent : 1;
- unsigned ContainsUnexpandedParameterPack : 1;
- };
- enum { NumExprBits = 16 };
-
- class CharacterLiteralBitfields {
- friend class CharacterLiteral;
- unsigned : NumExprBits;
-
- unsigned Kind : 2;
- };
-
- enum APFloatSemantics {
- IEEEhalf,
- IEEEsingle,
- IEEEdouble,
- x87DoubleExtended,
- IEEEquad,
- PPCDoubleDouble
- };
-
- class FloatingLiteralBitfields {
- friend class FloatingLiteral;
- unsigned : NumExprBits;
-
- unsigned Semantics : 3; // Provides semantics for APFloat construction
- unsigned IsExact : 1;
- };
-
- class UnaryExprOrTypeTraitExprBitfields {
- friend class UnaryExprOrTypeTraitExpr;
- unsigned : NumExprBits;
-
- unsigned Kind : 2;
- unsigned IsType : 1; // true if operand is a type, false if an expression.
- };
-
- class DeclRefExprBitfields {
- friend class DeclRefExpr;
- friend class ASTStmtReader; // deserialization
- unsigned : NumExprBits;
-
- unsigned HasQualifier : 1;
- unsigned HasTemplateKWAndArgsInfo : 1;
- unsigned HasFoundDecl : 1;
- unsigned HadMultipleCandidates : 1;
- unsigned RefersToEnclosingVariableOrCapture : 1;
- };
-
- class CastExprBitfields {
- friend class CastExpr;
- unsigned : NumExprBits;
-
- unsigned Kind : 6;
- unsigned BasePathSize : 32 - 6 - NumExprBits;
- };
-
- class CallExprBitfields {
- friend class CallExpr;
- unsigned : NumExprBits;
-
- unsigned NumPreArgs : 1;
- };
-
- class ExprWithCleanupsBitfields {
- friend class ExprWithCleanups;
- friend class ASTStmtReader; // deserialization
-
- unsigned : NumExprBits;
-
- unsigned NumObjects : 32 - NumExprBits;
- };
-
- class PseudoObjectExprBitfields {
- friend class PseudoObjectExpr;
- friend class ASTStmtReader; // deserialization
-
- unsigned : NumExprBits;
-
- // These don't need to be particularly wide, because they're
- // strictly limited by the forms of expressions we permit.
- unsigned NumSubExprs : 8;
- unsigned ResultIndex : 32 - 8 - NumExprBits;
- };
-
- class ObjCIndirectCopyRestoreExprBitfields {
- friend class ObjCIndirectCopyRestoreExpr;
- unsigned : NumExprBits;
-
- unsigned ShouldCopy : 1;
- };
-
- class InitListExprBitfields {
- friend class InitListExpr;
-
- unsigned : NumExprBits;
-
- /// Whether this initializer list originally had a GNU array-range
- /// designator in it. This is a temporary marker used by CodeGen.
- unsigned HadArrayRangeDesignator : 1;
- };
-
- class TypeTraitExprBitfields {
- friend class TypeTraitExpr;
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- unsigned : NumExprBits;
-
- /// \brief The kind of type trait, which is a value of a TypeTrait enumerator.
- unsigned Kind : 8;
-
- /// \brief If this expression is not value-dependent, this indicates whether
- /// the trait evaluated true or false.
- unsigned Value : 1;
-
- /// \brief The number of arguments to this type trait.
- unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
- };
-
- union {
- StmtBitfields StmtBits;
- CompoundStmtBitfields CompoundStmtBits;
- ExprBitfields ExprBits;
- CharacterLiteralBitfields CharacterLiteralBits;
- FloatingLiteralBitfields FloatingLiteralBits;
- UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
- DeclRefExprBitfields DeclRefExprBits;
- CastExprBitfields CastExprBits;
- CallExprBitfields CallExprBits;
- ExprWithCleanupsBitfields ExprWithCleanupsBits;
- PseudoObjectExprBitfields PseudoObjectExprBits;
- ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
- InitListExprBitfields InitListExprBits;
- TypeTraitExprBitfields TypeTraitExprBits;
- };
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
-public:
- // Only allow allocation of Stmts using the allocator in ASTContext
- // or by doing a placement new.
- void* operator new(size_t bytes, const ASTContext& C,
- unsigned alignment = 8);
-
- void* operator new(size_t bytes, const ASTContext* C,
- unsigned alignment = 8) {
- return operator new(bytes, *C, alignment);
- }
-
- void *operator new(size_t bytes, void *mem) LLVM_NOEXCEPT { return mem; }
-
- void operator delete(void *, const ASTContext &, unsigned) LLVM_NOEXCEPT {}
- void operator delete(void *, const ASTContext *, unsigned) LLVM_NOEXCEPT {}
- void operator delete(void *, size_t) LLVM_NOEXCEPT {}
- void operator delete(void *, void *) LLVM_NOEXCEPT {}
-
-public:
- /// \brief A placeholder type used to construct an empty shell of a
- /// type, that will be filled in later (e.g., by some
- /// de-serialization).
- struct EmptyShell { };
-
-protected:
- /// Iterator for iterating over Stmt * arrays that contain only Expr *
- ///
- /// This is needed because AST nodes use Stmt* arrays to store
- /// references to children (to be compatible with StmtIterator).
- struct ExprIterator
- : llvm::iterator_adaptor_base<ExprIterator, Stmt **,
- std::random_access_iterator_tag, Expr *> {
- ExprIterator() : iterator_adaptor_base(nullptr) {}
- ExprIterator(Stmt **I) : iterator_adaptor_base(I) {}
-
- reference operator*() const {
- assert((*I)->getStmtClass() >= firstExprConstant &&
- (*I)->getStmtClass() <= lastExprConstant);
- return *reinterpret_cast<Expr **>(I);
- }
- };
-
- /// Const iterator for iterating over Stmt * arrays that contain only Expr *
- struct ConstExprIterator
- : llvm::iterator_adaptor_base<ConstExprIterator, const Stmt *const *,
- std::random_access_iterator_tag,
- const Expr *const> {
- ConstExprIterator() : iterator_adaptor_base(nullptr) {}
- ConstExprIterator(const Stmt *const *I) : iterator_adaptor_base(I) {}
-
- reference operator*() const {
- assert((*I)->getStmtClass() >= firstExprConstant &&
- (*I)->getStmtClass() <= lastExprConstant);
- return *reinterpret_cast<const Expr *const *>(I);
- }
- };
-
-private:
- /// \brief Whether statistic collection is enabled.
- static bool StatisticsEnabled;
-
-protected:
- /// \brief Construct an empty statement.
- explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {}
-
-public:
- Stmt(StmtClass SC) {
- static_assert(sizeof(*this) % llvm::AlignOf<void *>::Alignment == 0,
- "Insufficient alignment!");
- StmtBits.sClass = SC;
- if (StatisticsEnabled) Stmt::addStmtClass(SC);
- }
-
- StmtClass getStmtClass() const {
- return static_cast<StmtClass>(StmtBits.sClass);
- }
- const char *getStmtClassName() const;
-
- /// SourceLocation tokens are not useful in isolation - they are low level
- /// value objects created/interpreted by SourceManager. We assume AST
- /// clients will have a pointer to the respective SourceManager.
- SourceRange getSourceRange() const LLVM_READONLY;
- SourceLocation getLocStart() const LLVM_READONLY;
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- // global temp stats (until we have a per-module visitor)
- static void addStmtClass(const StmtClass s);
- static void EnableStatistics();
- static void PrintStats();
-
- /// \brief Dumps the specified AST fragment and all subtrees to
- /// \c llvm::errs().
- void dump() const;
- void dump(SourceManager &SM) const;
- void dump(raw_ostream &OS, SourceManager &SM) const;
- void dump(raw_ostream &OS) const;
-
- /// dumpColor - same as dump(), but forces color highlighting.
- void dumpColor() const;
-
- /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
- /// back to its original source language syntax.
- void dumpPretty(const ASTContext &Context) const;
- void printPretty(raw_ostream &OS, PrinterHelper *Helper,
- const PrintingPolicy &Policy,
- unsigned Indentation = 0) const;
-
- /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
- /// works on systems with GraphViz (Mac OS X) or dot+gv installed.
- void viewAST() const;
-
- /// Skip past any implicit AST nodes which might surround this
- /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
- Stmt *IgnoreImplicit();
-
- /// \brief Skip no-op (attributed, compound) container stmts and skip captured
- /// stmt at the top, if \a IgnoreCaptured is true.
- Stmt *IgnoreContainers(bool IgnoreCaptured = false);
-
- const Stmt *stripLabelLikeStatements() const;
- Stmt *stripLabelLikeStatements() {
- return const_cast<Stmt*>(
- const_cast<const Stmt*>(this)->stripLabelLikeStatements());
- }
-
- /// Child Iterators: All subclasses must implement 'children'
- /// to permit easy iteration over the substatements/subexpessions of an
- /// AST node. This permits easy iteration over all nodes in the AST.
- typedef StmtIterator child_iterator;
- typedef ConstStmtIterator const_child_iterator;
-
- typedef llvm::iterator_range<child_iterator> child_range;
- typedef llvm::iterator_range<const_child_iterator> const_child_range;
-
- child_range children();
- const_child_range children() const {
- auto Children = const_cast<Stmt *>(this)->children();
- return const_child_range(Children.begin(), Children.end());
- }
-
- child_iterator child_begin() { return children().begin(); }
- child_iterator child_end() { return children().end(); }
-
- const_child_iterator child_begin() const { return children().begin(); }
- const_child_iterator child_end() const { return children().end(); }
-
- /// \brief Produce a unique representation of the given statement.
- ///
- /// \param ID once the profiling operation is complete, will contain
- /// the unique representation of the given statement.
- ///
- /// \param Context the AST context in which the statement resides
- ///
- /// \param Canonical whether the profile should be based on the canonical
- /// representation of this statement (e.g., where non-type template
- /// parameters are identified by index/level rather than their
- /// declaration pointers) or the exact representation of the statement as
- /// written in the source.
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- bool Canonical) const;
-};
-
-/// DeclStmt - Adaptor class for mixing declarations with statements and
-/// expressions. For example, CompoundStmt mixes statements, expressions
-/// and declarations (variables, types). Another example is ForStmt, where
-/// the first statement can be an expression or a declaration.
-///
-class DeclStmt : public Stmt {
- DeclGroupRef DG;
- SourceLocation StartLoc, EndLoc;
-
-public:
- DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
- SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
- StartLoc(startLoc), EndLoc(endLoc) {}
-
- /// \brief Build an empty declaration statement.
- explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
-
- /// isSingleDecl - This method returns true if this DeclStmt refers
- /// to a single Decl.
- bool isSingleDecl() const {
- return DG.isSingleDecl();
- }
-
- const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
- Decl *getSingleDecl() { return DG.getSingleDecl(); }
-
- const DeclGroupRef getDeclGroup() const { return DG; }
- DeclGroupRef getDeclGroup() { return DG; }
- void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
-
- SourceLocation getStartLoc() const { return StartLoc; }
- void setStartLoc(SourceLocation L) { StartLoc = L; }
- SourceLocation getEndLoc() const { return EndLoc; }
- void setEndLoc(SourceLocation L) { EndLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return StartLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclStmtClass;
- }
-
- // Iterators over subexpressions.
- child_range children() {
- return child_range(child_iterator(DG.begin(), DG.end()),
- child_iterator(DG.end(), DG.end()));
- }
-
- typedef DeclGroupRef::iterator decl_iterator;
- typedef DeclGroupRef::const_iterator const_decl_iterator;
- typedef llvm::iterator_range<decl_iterator> decl_range;
- typedef llvm::iterator_range<const_decl_iterator> decl_const_range;
-
- decl_range decls() { return decl_range(decl_begin(), decl_end()); }
- decl_const_range decls() const {
- return decl_const_range(decl_begin(), decl_end());
- }
- decl_iterator decl_begin() { return DG.begin(); }
- decl_iterator decl_end() { return DG.end(); }
- const_decl_iterator decl_begin() const { return DG.begin(); }
- const_decl_iterator decl_end() const { return DG.end(); }
-
- typedef std::reverse_iterator<decl_iterator> reverse_decl_iterator;
- reverse_decl_iterator decl_rbegin() {
- return reverse_decl_iterator(decl_end());
- }
- reverse_decl_iterator decl_rend() {
- return reverse_decl_iterator(decl_begin());
- }
-};
-
-/// NullStmt - This is the null statement ";": C99 6.8.3p3.
-///
-class NullStmt : public Stmt {
- SourceLocation SemiLoc;
-
- /// \brief True if the null statement was preceded by an empty macro, e.g:
- /// @code
- /// #define CALL(x)
- /// CALL(0);
- /// @endcode
- bool HasLeadingEmptyMacro;
-public:
- NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
- : Stmt(NullStmtClass), SemiLoc(L),
- HasLeadingEmptyMacro(hasLeadingEmptyMacro) {}
-
- /// \brief Build an empty null statement.
- explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty),
- HasLeadingEmptyMacro(false) { }
-
- SourceLocation getSemiLoc() const { return SemiLoc; }
- void setSemiLoc(SourceLocation L) { SemiLoc = L; }
-
- bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SemiLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SemiLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == NullStmtClass;
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-};
-
-/// CompoundStmt - This represents a group of statements like { stmt stmt }.
-///
-class CompoundStmt : public Stmt {
- Stmt** Body;
- SourceLocation LBraceLoc, RBraceLoc;
-
- friend class ASTStmtReader;
-
-public:
- CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
- SourceLocation LB, SourceLocation RB);
-
- // \brief Build an empty compound statement with a location.
- explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), Body(nullptr), LBraceLoc(Loc), RBraceLoc(Loc) {
- CompoundStmtBits.NumStmts = 0;
- }
-
- // \brief Build an empty compound statement.
- explicit CompoundStmt(EmptyShell Empty)
- : Stmt(CompoundStmtClass, Empty), Body(nullptr) {
- CompoundStmtBits.NumStmts = 0;
- }
-
- void setStmts(const ASTContext &C, ArrayRef<Stmt *> Stmts);
-
- bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
- unsigned size() const { return CompoundStmtBits.NumStmts; }
-
- typedef Stmt** body_iterator;
- typedef llvm::iterator_range<body_iterator> body_range;
-
- body_range body() { return body_range(body_begin(), body_end()); }
- body_iterator body_begin() { return Body; }
- body_iterator body_end() { return Body + size(); }
- Stmt *body_front() { return !body_empty() ? Body[0] : nullptr; }
- Stmt *body_back() { return !body_empty() ? Body[size()-1] : nullptr; }
-
- void setLastStmt(Stmt *S) {
- assert(!body_empty() && "setLastStmt");
- Body[size()-1] = S;
- }
-
- typedef Stmt* const * const_body_iterator;
- typedef llvm::iterator_range<const_body_iterator> body_const_range;
-
- body_const_range body() const {
- return body_const_range(body_begin(), body_end());
- }
- const_body_iterator body_begin() const { return Body; }
- const_body_iterator body_end() const { return Body + size(); }
- const Stmt *body_front() const {
- return !body_empty() ? Body[0] : nullptr;
- }
- const Stmt *body_back() const {
- return !body_empty() ? Body[size() - 1] : nullptr;
- }
-
- typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
- reverse_body_iterator body_rbegin() {
- return reverse_body_iterator(body_end());
- }
- reverse_body_iterator body_rend() {
- return reverse_body_iterator(body_begin());
- }
-
- typedef std::reverse_iterator<const_body_iterator>
- const_reverse_body_iterator;
-
- const_reverse_body_iterator body_rbegin() const {
- return const_reverse_body_iterator(body_end());
- }
-
- const_reverse_body_iterator body_rend() const {
- return const_reverse_body_iterator(body_begin());
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LBraceLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RBraceLoc; }
-
- SourceLocation getLBracLoc() const { return LBraceLoc; }
- SourceLocation getRBracLoc() const { return RBraceLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CompoundStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(Body, Body + CompoundStmtBits.NumStmts);
- }
-
- const_child_range children() const {
- return const_child_range(child_iterator(Body),
- child_iterator(Body + CompoundStmtBits.NumStmts));
- }
-};
-
-// SwitchCase is the base class for CaseStmt and DefaultStmt,
-class SwitchCase : public Stmt {
-protected:
- // A pointer to the following CaseStmt or DefaultStmt class,
- // used by SwitchStmt.
- SwitchCase *NextSwitchCase;
- SourceLocation KeywordLoc;
- SourceLocation ColonLoc;
-
- SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
- : Stmt(SC), NextSwitchCase(nullptr), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {
- }
-
- SwitchCase(StmtClass SC, EmptyShell)
- : Stmt(SC), NextSwitchCase(nullptr) {}
-
-public:
- const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
-
- SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
-
- void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
-
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
- void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
-
- Stmt *getSubStmt();
- const Stmt *getSubStmt() const {
- return const_cast<SwitchCase*>(this)->getSubStmt();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CaseStmtClass ||
- T->getStmtClass() == DefaultStmtClass;
- }
-};
-
-class CaseStmt : public SwitchCase {
- SourceLocation EllipsisLoc;
- enum { LHS, RHS, SUBSTMT, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
- // GNU "case 1 ... 4" extension
-public:
- CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
- SourceLocation ellipsisLoc, SourceLocation colonLoc)
- : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
- SubExprs[SUBSTMT] = nullptr;
- SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
- SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
- EllipsisLoc = ellipsisLoc;
- }
-
- /// \brief Build an empty switch case statement.
- explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) { }
-
- SourceLocation getCaseLoc() const { return KeywordLoc; }
- void setCaseLoc(SourceLocation L) { KeywordLoc = L; }
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
-
- Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
- Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
- Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
-
- const Expr *getLHS() const {
- return reinterpret_cast<const Expr*>(SubExprs[LHS]);
- }
- const Expr *getRHS() const {
- return reinterpret_cast<const Expr*>(SubExprs[RHS]);
- }
- const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
-
- void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
- void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
- void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- // Handle deeply nested case statements with iteration instead of recursion.
- const CaseStmt *CS = this;
- while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
- CS = CS2;
-
- return CS->getSubStmt()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CaseStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
- }
-};
-
-class DefaultStmt : public SwitchCase {
- Stmt* SubStmt;
-public:
- DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
- SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
-
- /// \brief Build an empty default statement.
- explicit DefaultStmt(EmptyShell Empty)
- : SwitchCase(DefaultStmtClass, Empty) { }
-
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
- void setSubStmt(Stmt *S) { SubStmt = S; }
-
- SourceLocation getDefaultLoc() const { return KeywordLoc; }
- void setDefaultLoc(SourceLocation L) { KeywordLoc = L; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DefaultStmtClass;
- }
-
- // Iterators
- child_range children() { return child_range(&SubStmt, &SubStmt+1); }
-};
-
-inline SourceLocation SwitchCase::getLocEnd() const {
- if (const CaseStmt *CS = dyn_cast<CaseStmt>(this))
- return CS->getLocEnd();
- return cast<DefaultStmt>(this)->getLocEnd();
-}
-
-/// LabelStmt - Represents a label, which has a substatement. For example:
-/// foo: return;
-///
-class LabelStmt : public Stmt {
- SourceLocation IdentLoc;
- LabelDecl *TheDecl;
- Stmt *SubStmt;
-
-public:
- LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
- : Stmt(LabelStmtClass), IdentLoc(IL), TheDecl(D), SubStmt(substmt) {
- static_assert(sizeof(LabelStmt) ==
- 2 * sizeof(SourceLocation) + 2 * sizeof(void *),
- "LabelStmt too big");
- }
-
- // \brief Build an empty label statement.
- explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
-
- SourceLocation getIdentLoc() const { return IdentLoc; }
- LabelDecl *getDecl() const { return TheDecl; }
- void setDecl(LabelDecl *D) { TheDecl = D; }
- const char *getName() const;
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
- void setIdentLoc(SourceLocation L) { IdentLoc = L; }
- void setSubStmt(Stmt *SS) { SubStmt = SS; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return IdentLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- child_range children() { return child_range(&SubStmt, &SubStmt+1); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == LabelStmtClass;
- }
-};
-
-
-/// \brief Represents an attribute applied to a statement.
-///
-/// Represents an attribute applied to a statement. For example:
-/// [[omp::for(...)]] for (...) { ... }
-///
-class AttributedStmt : public Stmt {
- Stmt *SubStmt;
- SourceLocation AttrLoc;
- unsigned NumAttrs;
-
- friend class ASTStmtReader;
-
- AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
- : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
- NumAttrs(Attrs.size()) {
- std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr());
- }
-
- explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
- : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
- std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
- }
-
- const Attr *const *getAttrArrayPtr() const {
- return reinterpret_cast<const Attr *const *>(this + 1);
- }
- const Attr **getAttrArrayPtr() {
- return reinterpret_cast<const Attr **>(this + 1);
- }
-
-public:
- static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
- ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
- // \brief Build an empty attributed statement.
- static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
-
- SourceLocation getAttrLoc() const { return AttrLoc; }
- ArrayRef<const Attr*> getAttrs() const {
- return llvm::makeArrayRef(getAttrArrayPtr(), NumAttrs);
- }
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AttrLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AttributedStmtClass;
- }
-};
-
-
-/// IfStmt - This represents an if/then/else.
-///
-class IfStmt : public Stmt {
- enum { VAR, COND, THEN, ELSE, END_EXPR };
- Stmt* SubExprs[END_EXPR];
-
- SourceLocation IfLoc;
- SourceLocation ElseLoc;
-
-public:
- IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
- Stmt *then, SourceLocation EL = SourceLocation(),
- Stmt *elsev = nullptr);
-
- /// \brief Build an empty if/then/else statement
- explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
-
- /// \brief Retrieve the variable declared in this "if" statement, if any.
- ///
- /// In the following example, "x" is the condition variable.
- /// \code
- /// if (int x = foo()) {
- /// printf("x is %d", x);
- /// }
- /// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
-
- /// If this IfStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
- }
-
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
- const Stmt *getThen() const { return SubExprs[THEN]; }
- void setThen(Stmt *S) { SubExprs[THEN] = S; }
- const Stmt *getElse() const { return SubExprs[ELSE]; }
- void setElse(Stmt *S) { SubExprs[ELSE] = S; }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- Stmt *getThen() { return SubExprs[THEN]; }
- Stmt *getElse() { return SubExprs[ELSE]; }
-
- SourceLocation getIfLoc() const { return IfLoc; }
- void setIfLoc(SourceLocation L) { IfLoc = L; }
- SourceLocation getElseLoc() const { return ElseLoc; }
- void setElseLoc(SourceLocation L) { ElseLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- if (SubExprs[ELSE])
- return SubExprs[ELSE]->getLocEnd();
- else
- return SubExprs[THEN]->getLocEnd();
- }
-
- // Iterators over subexpressions. The iterators will include iterating
- // over the initialization expression referenced by the condition variable.
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IfStmtClass;
- }
-};
-
-/// SwitchStmt - This represents a 'switch' stmt.
-///
-class SwitchStmt : public Stmt {
- SourceLocation SwitchLoc;
- enum { VAR, COND, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- // This points to a linked list of case and default statements and, if the
- // SwitchStmt is a switch on an enum value, records whether all the enum
- // values were covered by CaseStmts. The coverage information value is meant
- // to be a hint for possible clients.
- llvm::PointerIntPair<SwitchCase *, 1, bool> FirstCase;
-
-public:
- SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond);
-
- /// \brief Build a empty switch statement.
- explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
-
- /// \brief Retrieve the variable declared in this "switch" statement, if any.
- ///
- /// In the following example, "x" is the condition variable.
- /// \code
- /// switch (int x = foo()) {
- /// case 0: break;
- /// // ...
- /// }
- /// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
-
- /// If this SwitchStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
- }
-
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- const Stmt *getBody() const { return SubExprs[BODY]; }
- const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
- Stmt *getBody() { return SubExprs[BODY]; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
- SwitchCase *getSwitchCaseList() { return FirstCase.getPointer(); }
-
- /// \brief Set the case list for this switch statement.
- void setSwitchCaseList(SwitchCase *SC) { FirstCase.setPointer(SC); }
-
- SourceLocation getSwitchLoc() const { return SwitchLoc; }
- void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
-
- void setBody(Stmt *S, SourceLocation SL) {
- SubExprs[BODY] = S;
- SwitchLoc = SL;
- }
- void addSwitchCase(SwitchCase *SC) {
- assert(!SC->getNextSwitchCase()
- && "case/default already added to a switch");
- SC->setNextSwitchCase(FirstCase.getPointer());
- FirstCase.setPointer(SC);
- }
-
- /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
- /// switch over an enum value then all cases have been explicitly covered.
- void setAllEnumCasesCovered() { FirstCase.setInt(true); }
-
- /// Returns true if the SwitchStmt is a switch of an enum value and all cases
- /// have been explicitly covered.
- bool isAllEnumCasesCovered() const { return FirstCase.getInt(); }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY] ? SubExprs[BODY]->getLocEnd() : SubExprs[COND]->getLocEnd();
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SwitchStmtClass;
- }
-};
-
-
-/// WhileStmt - This represents a 'while' stmt.
-///
-class WhileStmt : public Stmt {
- SourceLocation WhileLoc;
- enum { VAR, COND, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR];
-public:
- WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
- SourceLocation WL);
-
- /// \brief Build an empty while statement.
- explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
-
- /// \brief Retrieve the variable declared in this "while" statement, if any.
- ///
- /// In the following example, "x" is the condition variable.
- /// \code
- /// while (int x = random()) {
- /// // ...
- /// }
- /// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
-
- /// If this WhileStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
- }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- Stmt *getBody() { return SubExprs[BODY]; }
- const Stmt *getBody() const { return SubExprs[BODY]; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getWhileLoc() const { return WhileLoc; }
- void setWhileLoc(SourceLocation L) { WhileLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == WhileStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// DoStmt - This represents a 'do/while' stmt.
-///
-class DoStmt : public Stmt {
- SourceLocation DoLoc;
- enum { BODY, COND, END_EXPR };
- Stmt* SubExprs[END_EXPR];
- SourceLocation WhileLoc;
- SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
-
-public:
- DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
- SourceLocation RP)
- : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = body;
- }
-
- /// \brief Build an empty do-while statement.
- explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- Stmt *getBody() { return SubExprs[BODY]; }
- const Stmt *getBody() const { return SubExprs[BODY]; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getDoLoc() const { return DoLoc; }
- void setDoLoc(SourceLocation L) { DoLoc = L; }
- SourceLocation getWhileLoc() const { return WhileLoc; }
- void setWhileLoc(SourceLocation L) { WhileLoc = L; }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return DoLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DoStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-
-/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
-/// the init/cond/inc parts of the ForStmt will be null if they were not
-/// specified in the source.
-///
-class ForStmt : public Stmt {
- SourceLocation ForLoc;
- enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
- SourceLocation LParenLoc, RParenLoc;
-
-public:
- ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
- Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
- SourceLocation RP);
-
- /// \brief Build an empty for statement.
- explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
-
- Stmt *getInit() { return SubExprs[INIT]; }
-
- /// \brief Retrieve the variable declared in this "for" statement, if any.
- ///
- /// In the following example, "y" is the condition variable.
- /// \code
- /// for (int x = random(); int y = mangle(x); ++x) {
- /// // ...
- /// }
- /// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
-
- /// If this ForStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
- }
-
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
- Stmt *getBody() { return SubExprs[BODY]; }
-
- const Stmt *getInit() const { return SubExprs[INIT]; }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- void setInit(Stmt *S) { SubExprs[INIT] = S; }
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getForLoc() const { return ForLoc; }
- void setForLoc(SourceLocation L) { ForLoc = L; }
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ForStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
-};
-
-/// GotoStmt - This represents a direct goto.
-///
-class GotoStmt : public Stmt {
- LabelDecl *Label;
- SourceLocation GotoLoc;
- SourceLocation LabelLoc;
-public:
- GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
- : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
-
- /// \brief Build an empty goto statement.
- explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
-
- LabelDecl *getLabel() const { return Label; }
- void setLabel(LabelDecl *D) { Label = D; }
-
- SourceLocation getGotoLoc() const { return GotoLoc; }
- void setGotoLoc(SourceLocation L) { GotoLoc = L; }
- SourceLocation getLabelLoc() const { return LabelLoc; }
- void setLabelLoc(SourceLocation L) { LabelLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GotoStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// IndirectGotoStmt - This represents an indirect goto.
-///
-class IndirectGotoStmt : public Stmt {
- SourceLocation GotoLoc;
- SourceLocation StarLoc;
- Stmt *Target;
-public:
- IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
- Expr *target)
- : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
- Target((Stmt*)target) {}
-
- /// \brief Build an empty indirect goto statement.
- explicit IndirectGotoStmt(EmptyShell Empty)
- : Stmt(IndirectGotoStmtClass, Empty) { }
-
- void setGotoLoc(SourceLocation L) { GotoLoc = L; }
- SourceLocation getGotoLoc() const { return GotoLoc; }
- void setStarLoc(SourceLocation L) { StarLoc = L; }
- SourceLocation getStarLoc() const { return StarLoc; }
-
- Expr *getTarget() { return reinterpret_cast<Expr*>(Target); }
- const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);}
- void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
-
- /// getConstantTarget - Returns the fixed target of this indirect
- /// goto, if one exists.
- LabelDecl *getConstantTarget();
- const LabelDecl *getConstantTarget() const {
- return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Target->getLocEnd(); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IndirectGotoStmtClass;
- }
-
- // Iterators
- child_range children() { return child_range(&Target, &Target+1); }
-};
-
-
-/// ContinueStmt - This represents a continue.
-///
-class ContinueStmt : public Stmt {
- SourceLocation ContinueLoc;
-public:
- ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
-
- /// \brief Build an empty continue statement.
- explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
-
- SourceLocation getContinueLoc() const { return ContinueLoc; }
- void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ContinueLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return ContinueLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ContinueStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// BreakStmt - This represents a break.
-///
-class BreakStmt : public Stmt {
- SourceLocation BreakLoc;
-
-public:
- BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {
- static_assert(sizeof(BreakStmt) == 2 * sizeof(SourceLocation),
- "BreakStmt too large");
- }
-
- /// \brief Build an empty break statement.
- explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
-
- SourceLocation getBreakLoc() const { return BreakLoc; }
- void setBreakLoc(SourceLocation L) { BreakLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return BreakLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return BreakLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BreakStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-
-/// ReturnStmt - This represents a return, optionally of an expression:
-/// return;
-/// return 4;
-///
-/// Note that GCC allows return with no argument in a function declared to
-/// return a value, and it allows returning a value in functions declared to
-/// return void. We explicitly model this in the AST, which means you can't
-/// depend on the return type of the function and the presence of an argument.
-///
-class ReturnStmt : public Stmt {
- SourceLocation RetLoc;
- Stmt *RetExpr;
- const VarDecl *NRVOCandidate;
-
-public:
- explicit ReturnStmt(SourceLocation RL) : ReturnStmt(RL, nullptr, nullptr) {}
-
- ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
- : Stmt(ReturnStmtClass), RetLoc(RL), RetExpr((Stmt *)E),
- NRVOCandidate(NRVOCandidate) {}
-
- /// \brief Build an empty return expression.
- explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
-
- const Expr *getRetValue() const;
- Expr *getRetValue();
- void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
-
- SourceLocation getReturnLoc() const { return RetLoc; }
- void setReturnLoc(SourceLocation L) { RetLoc = L; }
-
- /// \brief Retrieve the variable that might be used for the named return
- /// value optimization.
- ///
- /// The optimization itself can only be performed if the variable is
- /// also marked as an NRVO object.
- const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
- void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return RetExpr ? RetExpr->getLocEnd() : RetLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ReturnStmtClass;
- }
-
- // Iterators
- child_range children() {
- if (RetExpr) return child_range(&RetExpr, &RetExpr+1);
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
-///
-class AsmStmt : public Stmt {
-protected:
- SourceLocation AsmLoc;
- /// \brief True if the assembly statement does not have any input or output
- /// operands.
- bool IsSimple;
-
- /// \brief If true, treat this inline assembly as having side effects.
- /// This assembly statement should not be optimized, deleted or moved.
- bool IsVolatile;
-
- unsigned NumOutputs;
- unsigned NumInputs;
- unsigned NumClobbers;
-
- Stmt **Exprs;
-
- AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
- unsigned numoutputs, unsigned numinputs, unsigned numclobbers) :
- Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
- NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { }
-
- friend class ASTStmtReader;
-
-public:
- /// \brief Build an empty inline-assembly statement.
- explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
- Stmt(SC, Empty), Exprs(nullptr) { }
-
- SourceLocation getAsmLoc() const { return AsmLoc; }
- void setAsmLoc(SourceLocation L) { AsmLoc = L; }
-
- bool isSimple() const { return IsSimple; }
- void setSimple(bool V) { IsSimple = V; }
-
- bool isVolatile() const { return IsVolatile; }
- void setVolatile(bool V) { IsVolatile = V; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
-
- //===--- Asm String Analysis ---===//
-
- /// Assemble final IR asm string.
- std::string generateAsmString(const ASTContext &C) const;
-
- //===--- Output operands ---===//
-
- unsigned getNumOutputs() const { return NumOutputs; }
-
- /// getOutputConstraint - Return the constraint string for the specified
- /// output operand. All output constraints are known to be non-empty (either
- /// '=' or '+').
- StringRef getOutputConstraint(unsigned i) const;
-
- /// isOutputPlusConstraint - Return true if the specified output constraint
- /// is a "+" constraint (which is both an input and an output) or false if it
- /// is an "=" constraint (just an output).
- bool isOutputPlusConstraint(unsigned i) const {
- return getOutputConstraint(i)[0] == '+';
- }
-
- const Expr *getOutputExpr(unsigned i) const;
-
- /// getNumPlusOperands - Return the number of output operands that have a "+"
- /// constraint.
- unsigned getNumPlusOperands() const;
-
- //===--- Input operands ---===//
-
- unsigned getNumInputs() const { return NumInputs; }
-
- /// getInputConstraint - Return the specified input constraint. Unlike output
- /// constraints, these can be empty.
- StringRef getInputConstraint(unsigned i) const;
-
- const Expr *getInputExpr(unsigned i) const;
-
- //===--- Other ---===//
-
- unsigned getNumClobbers() const { return NumClobbers; }
- StringRef getClobber(unsigned i) const;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GCCAsmStmtClass ||
- T->getStmtClass() == MSAsmStmtClass;
- }
-
- // Input expr iterators.
-
- typedef ExprIterator inputs_iterator;
- typedef ConstExprIterator const_inputs_iterator;
- typedef llvm::iterator_range<inputs_iterator> inputs_range;
- typedef llvm::iterator_range<const_inputs_iterator> inputs_const_range;
-
- inputs_iterator begin_inputs() {
- return &Exprs[0] + NumOutputs;
- }
-
- inputs_iterator end_inputs() {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
-
- inputs_range inputs() { return inputs_range(begin_inputs(), end_inputs()); }
-
- const_inputs_iterator begin_inputs() const {
- return &Exprs[0] + NumOutputs;
- }
-
- const_inputs_iterator end_inputs() const {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
-
- inputs_const_range inputs() const {
- return inputs_const_range(begin_inputs(), end_inputs());
- }
-
- // Output expr iterators.
-
- typedef ExprIterator outputs_iterator;
- typedef ConstExprIterator const_outputs_iterator;
- typedef llvm::iterator_range<outputs_iterator> outputs_range;
- typedef llvm::iterator_range<const_outputs_iterator> outputs_const_range;
-
- outputs_iterator begin_outputs() {
- return &Exprs[0];
- }
- outputs_iterator end_outputs() {
- return &Exprs[0] + NumOutputs;
- }
- outputs_range outputs() {
- return outputs_range(begin_outputs(), end_outputs());
- }
-
- const_outputs_iterator begin_outputs() const {
- return &Exprs[0];
- }
- const_outputs_iterator end_outputs() const {
- return &Exprs[0] + NumOutputs;
- }
- outputs_const_range outputs() const {
- return outputs_const_range(begin_outputs(), end_outputs());
- }
-
- child_range children() {
- return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
- }
-};
-
-/// This represents a GCC inline-assembly statement extension.
-///
-class GCCAsmStmt : public AsmStmt {
- SourceLocation RParenLoc;
- StringLiteral *AsmStr;
-
- // FIXME: If we wanted to, we could allocate all of these in one big array.
- StringLiteral **Constraints;
- StringLiteral **Clobbers;
- IdentifierInfo **Names;
-
- friend class ASTStmtReader;
-
-public:
- GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
- bool isvolatile, unsigned numoutputs, unsigned numinputs,
- IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
- StringLiteral *asmstr, unsigned numclobbers,
- StringLiteral **clobbers, SourceLocation rparenloc);
-
- /// \brief Build an empty inline-assembly statement.
- explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
- Constraints(nullptr), Clobbers(nullptr), Names(nullptr) { }
-
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-
- //===--- Asm String Analysis ---===//
-
- const StringLiteral *getAsmString() const { return AsmStr; }
- StringLiteral *getAsmString() { return AsmStr; }
- void setAsmString(StringLiteral *E) { AsmStr = E; }
-
- /// AsmStringPiece - this is part of a decomposed asm string specification
- /// (for use with the AnalyzeAsmString function below). An asm string is
- /// considered to be a concatenation of these parts.
- class AsmStringPiece {
- public:
- enum Kind {
- String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
- Operand // Operand reference, with optional modifier %c4.
- };
- private:
- Kind MyKind;
- std::string Str;
- unsigned OperandNo;
-
- // Source range for operand references.
- CharSourceRange Range;
- public:
- AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
- AsmStringPiece(unsigned OpNo, const std::string &S, SourceLocation Begin,
- SourceLocation End)
- : MyKind(Operand), Str(S), OperandNo(OpNo),
- Range(CharSourceRange::getCharRange(Begin, End)) {
- }
-
- bool isString() const { return MyKind == String; }
- bool isOperand() const { return MyKind == Operand; }
-
- const std::string &getString() const {
- return Str;
- }
-
- unsigned getOperandNo() const {
- assert(isOperand());
- return OperandNo;
- }
-
- CharSourceRange getRange() const {
- assert(isOperand() && "Range is currently used only for Operands.");
- return Range;
- }
-
- /// getModifier - Get the modifier for this operand, if present. This
- /// returns '\0' if there was no modifier.
- char getModifier() const;
- };
-
- /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
- /// it into pieces. If the asm string is erroneous, emit errors and return
- /// true, otherwise return false. This handles canonicalization and
- /// translation of strings from GCC syntax to LLVM IR syntax, and handles
- //// flattening of named references like %[foo] to Operand AsmStringPiece's.
- unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces,
- const ASTContext &C, unsigned &DiagOffs) const;
-
- /// Assemble final IR asm string.
- std::string generateAsmString(const ASTContext &C) const;
-
- //===--- Output operands ---===//
-
- IdentifierInfo *getOutputIdentifier(unsigned i) const {
- return Names[i];
- }
-
- StringRef getOutputName(unsigned i) const {
- if (IdentifierInfo *II = getOutputIdentifier(i))
- return II->getName();
-
- return StringRef();
- }
-
- StringRef getOutputConstraint(unsigned i) const;
-
- const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
- return Constraints[i];
- }
- StringLiteral *getOutputConstraintLiteral(unsigned i) {
- return Constraints[i];
- }
-
- Expr *getOutputExpr(unsigned i);
-
- const Expr *getOutputExpr(unsigned i) const {
- return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
- }
-
- //===--- Input operands ---===//
-
- IdentifierInfo *getInputIdentifier(unsigned i) const {
- return Names[i + NumOutputs];
- }
-
- StringRef getInputName(unsigned i) const {
- if (IdentifierInfo *II = getInputIdentifier(i))
- return II->getName();
-
- return StringRef();
- }
-
- StringRef getInputConstraint(unsigned i) const;
-
- const StringLiteral *getInputConstraintLiteral(unsigned i) const {
- return Constraints[i + NumOutputs];
- }
- StringLiteral *getInputConstraintLiteral(unsigned i) {
- return Constraints[i + NumOutputs];
- }
-
- Expr *getInputExpr(unsigned i);
- void setInputExpr(unsigned i, Expr *E);
-
- const Expr *getInputExpr(unsigned i) const {
- return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
- }
-
-private:
- void setOutputsAndInputsAndClobbers(const ASTContext &C,
- IdentifierInfo **Names,
- StringLiteral **Constraints,
- Stmt **Exprs,
- unsigned NumOutputs,
- unsigned NumInputs,
- StringLiteral **Clobbers,
- unsigned NumClobbers);
-public:
-
- //===--- Other ---===//
-
- /// getNamedOperand - Given a symbolic operand reference like %[foo],
- /// translate this into a numeric value needed to reference the same operand.
- /// This returns -1 if the operand name is invalid.
- int getNamedOperand(StringRef SymbolicName) const;
-
- StringRef getClobber(unsigned i) const;
- StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
- const StringLiteral *getClobberStringLiteral(unsigned i) const {
- return Clobbers[i];
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GCCAsmStmtClass;
- }
-};
-
-/// This represents a Microsoft inline-assembly statement extension.
-///
-class MSAsmStmt : public AsmStmt {
- SourceLocation LBraceLoc, EndLoc;
- StringRef AsmStr;
-
- unsigned NumAsmToks;
-
- Token *AsmToks;
- StringRef *Constraints;
- StringRef *Clobbers;
-
- friend class ASTStmtReader;
-
-public:
- MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
- SourceLocation lbraceloc, bool issimple, bool isvolatile,
- ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs,
- ArrayRef<StringRef> constraints,
- ArrayRef<Expr*> exprs, StringRef asmstr,
- ArrayRef<StringRef> clobbers, SourceLocation endloc);
-
- /// \brief Build an empty MS-style inline-assembly statement.
- explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
- NumAsmToks(0), AsmToks(nullptr), Constraints(nullptr), Clobbers(nullptr) { }
-
- SourceLocation getLBraceLoc() const { return LBraceLoc; }
- void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
- SourceLocation getEndLoc() const { return EndLoc; }
- void setEndLoc(SourceLocation L) { EndLoc = L; }
-
- bool hasBraces() const { return LBraceLoc.isValid(); }
-
- unsigned getNumAsmToks() { return NumAsmToks; }
- Token *getAsmToks() { return AsmToks; }
-
- //===--- Asm String Analysis ---===//
- StringRef getAsmString() const { return AsmStr; }
-
- /// Assemble final IR asm string.
- std::string generateAsmString(const ASTContext &C) const;
-
- //===--- Output operands ---===//
-
- StringRef getOutputConstraint(unsigned i) const {
- assert(i < NumOutputs);
- return Constraints[i];
- }
-
- Expr *getOutputExpr(unsigned i);
-
- const Expr *getOutputExpr(unsigned i) const {
- return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
- }
-
- //===--- Input operands ---===//
-
- StringRef getInputConstraint(unsigned i) const {
- assert(i < NumInputs);
- return Constraints[i + NumOutputs];
- }
-
- Expr *getInputExpr(unsigned i);
- void setInputExpr(unsigned i, Expr *E);
-
- const Expr *getInputExpr(unsigned i) const {
- return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
- }
-
- //===--- Other ---===//
-
- ArrayRef<StringRef> getAllConstraints() const {
- return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
- }
- ArrayRef<StringRef> getClobbers() const {
- return llvm::makeArrayRef(Clobbers, NumClobbers);
- }
- ArrayRef<Expr*> getAllExprs() const {
- return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
- NumInputs + NumOutputs);
- }
-
- StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
-
-private:
- void initialize(const ASTContext &C, StringRef AsmString,
- ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints,
- ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);
-public:
-
- SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSAsmStmtClass;
- }
-
- child_range children() {
- return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
- }
-};
-
-class SEHExceptStmt : public Stmt {
- SourceLocation Loc;
- Stmt *Children[2];
-
- enum { FILTER_EXPR, BLOCK };
-
- SEHExceptStmt(SourceLocation Loc,
- Expr *FilterExpr,
- Stmt *Block);
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { }
-
-public:
- static SEHExceptStmt* Create(const ASTContext &C,
- SourceLocation ExceptLoc,
- Expr *FilterExpr,
- Stmt *Block);
-
- SourceLocation getLocStart() const LLVM_READONLY { return getExceptLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- SourceLocation getExceptLoc() const { return Loc; }
- SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); }
-
- Expr *getFilterExpr() const {
- return reinterpret_cast<Expr*>(Children[FILTER_EXPR]);
- }
-
- CompoundStmt *getBlock() const {
- return cast<CompoundStmt>(Children[BLOCK]);
- }
-
- child_range children() {
- return child_range(Children,Children+2);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHExceptStmtClass;
- }
-
-};
-
-class SEHFinallyStmt : public Stmt {
- SourceLocation Loc;
- Stmt *Block;
-
- SEHFinallyStmt(SourceLocation Loc,
- Stmt *Block);
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { }
-
-public:
- static SEHFinallyStmt* Create(const ASTContext &C,
- SourceLocation FinallyLoc,
- Stmt *Block);
-
- SourceLocation getLocStart() const LLVM_READONLY { return getFinallyLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- SourceLocation getFinallyLoc() const { return Loc; }
- SourceLocation getEndLoc() const { return Block->getLocEnd(); }
-
- CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }
-
- child_range children() {
- return child_range(&Block,&Block+1);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHFinallyStmtClass;
- }
-
-};
-
-class SEHTryStmt : public Stmt {
- bool IsCXXTry;
- SourceLocation TryLoc;
- Stmt *Children[2];
-
- enum { TRY = 0, HANDLER = 1 };
-
- SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
- SourceLocation TryLoc,
- Stmt *TryBlock,
- Stmt *Handler);
-
- friend class ASTReader;
- friend class ASTStmtReader;
- explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { }
-
-public:
- static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry,
- SourceLocation TryLoc, Stmt *TryBlock,
- Stmt *Handler);
-
- SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- SourceLocation getTryLoc() const { return TryLoc; }
- SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); }
-
- bool getIsCXXTry() const { return IsCXXTry; }
-
- CompoundStmt* getTryBlock() const {
- return cast<CompoundStmt>(Children[TRY]);
- }
-
- Stmt *getHandler() const { return Children[HANDLER]; }
-
- /// Returns 0 if not defined
- SEHExceptStmt *getExceptHandler() const;
- SEHFinallyStmt *getFinallyHandler() const;
-
- child_range children() {
- return child_range(Children,Children+2);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHTryStmtClass;
- }
-};
-
-/// Represents a __leave statement.
-///
-class SEHLeaveStmt : public Stmt {
- SourceLocation LeaveLoc;
-public:
- explicit SEHLeaveStmt(SourceLocation LL)
- : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
-
- /// \brief Build an empty __leave statement.
- explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) { }
-
- SourceLocation getLeaveLoc() const { return LeaveLoc; }
- void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return LeaveLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return LeaveLoc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHLeaveStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-};
-
-/// \brief This captures a statement into a function. For example, the following
-/// pragma annotated compound statement can be represented as a CapturedStmt,
-/// and this compound statement is the body of an anonymous outlined function.
-/// @code
-/// #pragma omp parallel
-/// {
-/// compute();
-/// }
-/// @endcode
-class CapturedStmt : public Stmt {
-public:
- /// \brief The different capture forms: by 'this', by reference, capture for
- /// variable-length array type etc.
- enum VariableCaptureKind {
- VCK_This,
- VCK_ByRef,
- VCK_ByCopy,
- VCK_VLAType,
- };
-
- /// \brief Describes the capture of either a variable, or 'this', or
- /// variable-length array type.
- class Capture {
- llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
- SourceLocation Loc;
-
- public:
- /// \brief Create a new capture.
- ///
- /// \param Loc The source location associated with this capture.
- ///
- /// \param Kind The kind of capture (this, ByRef, ...).
- ///
- /// \param Var The variable being captured, or null if capturing this.
- ///
- Capture(SourceLocation Loc, VariableCaptureKind Kind,
- VarDecl *Var = nullptr);
-
- /// \brief Determine the kind of capture.
- VariableCaptureKind getCaptureKind() const;
-
- /// \brief Retrieve the source location at which the variable or 'this' was
- /// first used.
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Determine whether this capture handles the C++ 'this' pointer.
- bool capturesThis() const { return getCaptureKind() == VCK_This; }
-
- /// \brief Determine whether this capture handles a variable (by reference).
- bool capturesVariable() const { return getCaptureKind() == VCK_ByRef; }
-
- /// \brief Determine whether this capture handles a variable by copy.
- bool capturesVariableByCopy() const {
- return getCaptureKind() == VCK_ByCopy;
- }
-
- /// \brief Determine whether this capture handles a variable-length array
- /// type.
- bool capturesVariableArrayType() const {
- return getCaptureKind() == VCK_VLAType;
- }
-
- /// \brief Retrieve the declaration of the variable being captured.
- ///
- /// This operation is only valid if this capture captures a variable.
- VarDecl *getCapturedVar() const;
-
- friend class ASTStmtReader;
- };
-
-private:
- /// \brief The number of variable captured, including 'this'.
- unsigned NumCaptures;
-
- /// \brief The pointer part is the implicit the outlined function and the
- /// int part is the captured region kind, 'CR_Default' etc.
- llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind;
-
- /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl.
- RecordDecl *TheRecordDecl;
-
- /// \brief Construct a captured statement.
- CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
- ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);
-
- /// \brief Construct an empty captured statement.
- CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
-
- Stmt **getStoredStmts() { return reinterpret_cast<Stmt **>(this + 1); }
-
- Stmt *const *getStoredStmts() const {
- return reinterpret_cast<Stmt *const *>(this + 1);
- }
-
- Capture *getStoredCaptures() const;
-
- void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }
-
-public:
- static CapturedStmt *Create(const ASTContext &Context, Stmt *S,
- CapturedRegionKind Kind,
- ArrayRef<Capture> Captures,
- ArrayRef<Expr *> CaptureInits,
- CapturedDecl *CD, RecordDecl *RD);
-
- static CapturedStmt *CreateDeserialized(const ASTContext &Context,
- unsigned NumCaptures);
-
- /// \brief Retrieve the statement being captured.
- Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
- const Stmt *getCapturedStmt() const { return getStoredStmts()[NumCaptures]; }
-
- /// \brief Retrieve the outlined function declaration.
- CapturedDecl *getCapturedDecl();
- const CapturedDecl *getCapturedDecl() const;
-
- /// \brief Set the outlined function declaration.
- void setCapturedDecl(CapturedDecl *D);
-
- /// \brief Retrieve the captured region kind.
- CapturedRegionKind getCapturedRegionKind() const;
-
- /// \brief Set the captured region kind.
- void setCapturedRegionKind(CapturedRegionKind Kind);
-
- /// \brief Retrieve the record declaration for captured variables.
- const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
-
- /// \brief Set the record declaration for captured variables.
- void setCapturedRecordDecl(RecordDecl *D) {
- assert(D && "null RecordDecl");
- TheRecordDecl = D;
- }
-
- /// \brief True if this variable has been captured.
- bool capturesVariable(const VarDecl *Var) const;
-
- /// \brief An iterator that walks over the captures.
- typedef Capture *capture_iterator;
- typedef const Capture *const_capture_iterator;
- typedef llvm::iterator_range<capture_iterator> capture_range;
- typedef llvm::iterator_range<const_capture_iterator> capture_const_range;
-
- capture_range captures() {
- return capture_range(capture_begin(), capture_end());
- }
- capture_const_range captures() const {
- return capture_const_range(capture_begin(), capture_end());
- }
-
- /// \brief Retrieve an iterator pointing to the first capture.
- capture_iterator capture_begin() { return getStoredCaptures(); }
- const_capture_iterator capture_begin() const { return getStoredCaptures(); }
-
- /// \brief Retrieve an iterator pointing past the end of the sequence of
- /// captures.
- capture_iterator capture_end() const {
- return getStoredCaptures() + NumCaptures;
- }
-
- /// \brief Retrieve the number of captures, including 'this'.
- unsigned capture_size() const { return NumCaptures; }
-
- /// \brief Iterator that walks over the capture initialization arguments.
- typedef Expr **capture_init_iterator;
- typedef llvm::iterator_range<capture_init_iterator> capture_init_range;
-
- /// \brief Const iterator that walks over the capture initialization
- /// arguments.
- typedef Expr *const *const_capture_init_iterator;
- typedef llvm::iterator_range<const_capture_init_iterator>
- const_capture_init_range;
-
- capture_init_range capture_inits() {
- return capture_init_range(capture_init_begin(), capture_init_end());
- }
-
- const_capture_init_range capture_inits() const {
- return const_capture_init_range(capture_init_begin(), capture_init_end());
- }
-
- /// \brief Retrieve the first initialization argument.
- capture_init_iterator capture_init_begin() {
- return reinterpret_cast<Expr **>(getStoredStmts());
- }
-
- const_capture_init_iterator capture_init_begin() const {
- return reinterpret_cast<Expr *const *>(getStoredStmts());
- }
-
- /// \brief Retrieve the iterator pointing one past the last initialization
- /// argument.
- capture_init_iterator capture_init_end() {
- return capture_init_begin() + NumCaptures;
- }
-
- const_capture_init_iterator capture_init_end() const {
- return capture_init_begin() + NumCaptures;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getCapturedStmt()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getCapturedStmt()->getLocEnd();
- }
- SourceRange getSourceRange() const LLVM_READONLY {
- return getCapturedStmt()->getSourceRange();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CapturedStmtClass;
- }
-
- child_range children();
-
- friend class ASTStmtReader;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
deleted file mode 100644
index 1ca73e2..0000000
--- a/include/clang/AST/StmtCXX.h
+++ /dev/null
@@ -1,417 +0,0 @@
-//===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the C++ statement AST node classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTCXX_H
-#define LLVM_CLANG_AST_STMTCXX_H
-
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Stmt.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-class VarDecl;
-
-/// CXXCatchStmt - This represents a C++ catch block.
-///
-class CXXCatchStmt : public Stmt {
- SourceLocation CatchLoc;
- /// The exception-declaration of the type.
- VarDecl *ExceptionDecl;
- /// The handler block.
- Stmt *HandlerBlock;
-
-public:
- CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
- : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
- HandlerBlock(handlerBlock) {}
-
- CXXCatchStmt(EmptyShell Empty)
- : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
-
- SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return HandlerBlock->getLocEnd();
- }
-
- SourceLocation getCatchLoc() const { return CatchLoc; }
- VarDecl *getExceptionDecl() const { return ExceptionDecl; }
- QualType getCaughtType() const;
- Stmt *getHandlerBlock() const { return HandlerBlock; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXCatchStmtClass;
- }
-
- child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
-
- friend class ASTStmtReader;
-};
-
-/// CXXTryStmt - A C++ try block, including all handlers.
-///
-class CXXTryStmt : public Stmt {
- SourceLocation TryLoc;
- unsigned NumHandlers;
-
- CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
-
- CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
- : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
-
- Stmt const * const *getStmts() const {
- return reinterpret_cast<Stmt const * const*>(this + 1);
- }
- Stmt **getStmts() {
- return reinterpret_cast<Stmt **>(this + 1);
- }
-
-public:
- static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
- Stmt *tryBlock, ArrayRef<Stmt*> handlers);
-
- static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
- unsigned numHandlers);
-
- SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- SourceLocation getTryLoc() const { return TryLoc; }
- SourceLocation getEndLoc() const {
- return getStmts()[NumHandlers]->getLocEnd();
- }
-
- CompoundStmt *getTryBlock() {
- return cast<CompoundStmt>(getStmts()[0]);
- }
- const CompoundStmt *getTryBlock() const {
- return cast<CompoundStmt>(getStmts()[0]);
- }
-
- unsigned getNumHandlers() const { return NumHandlers; }
- CXXCatchStmt *getHandler(unsigned i) {
- return cast<CXXCatchStmt>(getStmts()[i + 1]);
- }
- const CXXCatchStmt *getHandler(unsigned i) const {
- return cast<CXXCatchStmt>(getStmts()[i + 1]);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTryStmtClass;
- }
-
- child_range children() {
- return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
- }
-
- friend class ASTStmtReader;
-};
-
-/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
-/// statement, represented as 'for (range-declarator : range-expression)'.
-///
-/// This is stored in a partially-desugared form to allow full semantic
-/// analysis of the constituent components. The original syntactic components
-/// can be extracted using getLoopVariable and getRangeInit.
-class CXXForRangeStmt : public Stmt {
- SourceLocation ForLoc;
- enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END };
- // SubExprs[RANGE] is an expression or declstmt.
- // SubExprs[COND] and SubExprs[INC] are expressions.
- Stmt *SubExprs[END];
- SourceLocation CoawaitLoc;
- SourceLocation ColonLoc;
- SourceLocation RParenLoc;
-
- friend class ASTStmtReader;
-public:
- CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd,
- Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
- SourceLocation FL, SourceLocation CAL, SourceLocation CL,
- SourceLocation RPL);
- CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
-
-
- VarDecl *getLoopVariable();
- Expr *getRangeInit();
-
- const VarDecl *getLoopVariable() const;
- const Expr *getRangeInit() const;
-
-
- DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
- DeclStmt *getBeginEndStmt() {
- return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
- }
- Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
- Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
- DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
- Stmt *getBody() { return SubExprs[BODY]; }
-
- const DeclStmt *getRangeStmt() const {
- return cast<DeclStmt>(SubExprs[RANGE]);
- }
- const DeclStmt *getBeginEndStmt() const {
- return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
- }
- const Expr *getCond() const {
- return cast_or_null<Expr>(SubExprs[COND]);
- }
- const Expr *getInc() const {
- return cast_or_null<Expr>(SubExprs[INC]);
- }
- const DeclStmt *getLoopVarStmt() const {
- return cast<DeclStmt>(SubExprs[LOOPVAR]);
- }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
- void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
- void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; }
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
- void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getForLoc() const { return ForLoc; }
- SourceLocation getCoawaitLoc() const { return CoawaitLoc; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXForRangeStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[END]);
- }
-};
-
-/// \brief Representation of a Microsoft __if_exists or __if_not_exists
-/// statement with a dependent name.
-///
-/// The __if_exists statement can be used to include a sequence of statements
-/// in the program only when a particular dependent name does not exist. For
-/// example:
-///
-/// \code
-/// template<typename T>
-/// void call_foo(T &t) {
-/// __if_exists (T::foo) {
-/// t.foo(); // okay: only called when T::foo exists.
-/// }
-/// }
-/// \endcode
-///
-/// Similarly, the __if_not_exists statement can be used to include the
-/// statements when a particular name does not exist.
-///
-/// Note that this statement only captures __if_exists and __if_not_exists
-/// statements whose name is dependent. All non-dependent cases are handled
-/// directly in the parser, so that they don't introduce a new scope. Clang
-/// introduces scopes in the dependent case to keep names inside the compound
-/// statement from leaking out into the surround statements, which would
-/// compromise the template instantiation model. This behavior differs from
-/// Visual C++ (which never introduces a scope), but is a fairly reasonable
-/// approximation of the VC++ behavior.
-class MSDependentExistsStmt : public Stmt {
- SourceLocation KeywordLoc;
- bool IsIfExists;
- NestedNameSpecifierLoc QualifierLoc;
- DeclarationNameInfo NameInfo;
- Stmt *SubStmt;
-
- friend class ASTReader;
- friend class ASTStmtReader;
-
-public:
- MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists,
- NestedNameSpecifierLoc QualifierLoc,
- DeclarationNameInfo NameInfo,
- CompoundStmt *SubStmt)
- : Stmt(MSDependentExistsStmtClass),
- KeywordLoc(KeywordLoc), IsIfExists(IsIfExists),
- QualifierLoc(QualifierLoc), NameInfo(NameInfo),
- SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { }
-
- /// \brief Retrieve the location of the __if_exists or __if_not_exists
- /// keyword.
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
-
- /// \brief Determine whether this is an __if_exists statement.
- bool isIfExists() const { return IsIfExists; }
-
- /// \brief Determine whether this is an __if_exists statement.
- bool isIfNotExists() const { return !IsIfExists; }
-
- /// \brief Retrieve the nested-name-specifier that qualifies this name, if
- /// any.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
-
- /// \brief Retrieve the name of the entity we're testing for, along with
- /// location information
- DeclarationNameInfo getNameInfo() const { return NameInfo; }
-
- /// \brief Retrieve the compound statement that will be included in the
- /// program only if the existence of the symbol matches the initial keyword.
- CompoundStmt *getSubStmt() const {
- return reinterpret_cast<CompoundStmt *>(SubStmt);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- child_range children() {
- return child_range(&SubStmt, &SubStmt+1);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSDependentExistsStmtClass;
- }
-};
-
-/// \brief Represents the body of a coroutine. This wraps the normal function
-/// body and holds the additional semantic context required to set up and tear
-/// down the coroutine frame.
-class CoroutineBodyStmt : public Stmt {
- enum SubStmt {
- Body, ///< The body of the coroutine.
- Promise, ///< The promise statement.
- InitSuspend, ///< The initial suspend statement, run before the body.
- FinalSuspend, ///< The final suspend statement, run after the body.
- OnException, ///< Handler for exceptions thrown in the body.
- OnFallthrough, ///< Handler for control flow falling off the body.
- ReturnValue, ///< Return value for thunk function.
- FirstParamMove ///< First offset for move construction of parameter copies.
- };
- Stmt *SubStmts[SubStmt::FirstParamMove];
-
- friend class ASTStmtReader;
-public:
- CoroutineBodyStmt(Stmt *Body, Stmt *Promise, Stmt *InitSuspend,
- Stmt *FinalSuspend, Stmt *OnException, Stmt *OnFallthrough,
- Expr *ReturnValue, ArrayRef<Expr *> ParamMoves)
- : Stmt(CoroutineBodyStmtClass) {
- SubStmts[CoroutineBodyStmt::Body] = Body;
- SubStmts[CoroutineBodyStmt::Promise] = Promise;
- SubStmts[CoroutineBodyStmt::InitSuspend] = InitSuspend;
- SubStmts[CoroutineBodyStmt::FinalSuspend] = FinalSuspend;
- SubStmts[CoroutineBodyStmt::OnException] = OnException;
- SubStmts[CoroutineBodyStmt::OnFallthrough] = OnFallthrough;
- SubStmts[CoroutineBodyStmt::ReturnValue] = ReturnValue;
- // FIXME: Tail-allocate space for parameter move expressions and store them.
- assert(ParamMoves.empty() && "not implemented yet");
- }
-
- /// \brief Retrieve the body of the coroutine as written. This will be either
- /// a CompoundStmt or a TryStmt.
- Stmt *getBody() const {
- return SubStmts[SubStmt::Body];
- }
-
- Stmt *getPromiseDeclStmt() const { return SubStmts[SubStmt::Promise]; }
- VarDecl *getPromiseDecl() const {
- return cast<VarDecl>(cast<DeclStmt>(getPromiseDeclStmt())->getSingleDecl());
- }
-
- Stmt *getInitSuspendStmt() const { return SubStmts[SubStmt::InitSuspend]; }
- Stmt *getFinalSuspendStmt() const { return SubStmts[SubStmt::FinalSuspend]; }
-
- Stmt *getExceptionHandler() const { return SubStmts[SubStmt::OnException]; }
- Stmt *getFallthroughHandler() const {
- return SubStmts[SubStmt::OnFallthrough];
- }
-
- Expr *getReturnValueInit() const {
- return cast<Expr>(SubStmts[SubStmt::ReturnValue]);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY {
- return getBody()->getLocStart();
- }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getBody()->getLocEnd();
- }
-
- child_range children() {
- return child_range(SubStmts, SubStmts + SubStmt::FirstParamMove);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoroutineBodyStmtClass;
- }
-};
-
-/// \brief Represents a 'co_return' statement in the C++ Coroutines TS.
-///
-/// This statament models the initialization of the coroutine promise
-/// (encapsulating the eventual notional return value) from an expression
-/// (or braced-init-list), followed by termination of the coroutine.
-///
-/// This initialization is modeled by the evaluation of the operand
-/// followed by a call to one of:
-/// <promise>.return_value(<operand>)
-/// <promise>.return_void()
-/// which we name the "promise call".
-class CoreturnStmt : public Stmt {
- SourceLocation CoreturnLoc;
-
- enum SubStmt { Operand, PromiseCall, Count };
- Stmt *SubStmts[SubStmt::Count];
-
- friend class ASTStmtReader;
-public:
- CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall)
- : Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc) {
- SubStmts[SubStmt::Operand] = Operand;
- SubStmts[SubStmt::PromiseCall] = PromiseCall;
- }
-
- SourceLocation getKeywordLoc() const { return CoreturnLoc; }
-
- /// \brief Retrieve the operand of the 'co_return' statement. Will be nullptr
- /// if none was specified.
- Expr *getOperand() const { return static_cast<Expr*>(SubStmts[Operand]); }
-
- /// \brief Retrieve the promise call that results from this 'co_return'
- /// statement. Will be nullptr if either the coroutine has not yet been
- /// finalized or the coroutine has no eventual return type.
- Expr *getPromiseCall() const {
- return static_cast<Expr*>(SubStmts[PromiseCall]);
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return CoreturnLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getOperand()->getLocEnd();
- }
-
- child_range children() {
- return child_range(SubStmts, SubStmts + SubStmt::Count);
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoreturnStmtClass;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
deleted file mode 100644
index ab636a5..0000000
--- a/include/clang/AST/StmtGraphTraits.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===--- StmtGraphTraits.h - Graph Traits for the class Stmt ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a template specialization of llvm::GraphTraits to
-// treat ASTs (Stmt*) as graphs
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTGRAPHTRAITS_H
-#define LLVM_CLANG_AST_STMTGRAPHTRAITS_H
-
-#include "clang/AST/Stmt.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/ADT/GraphTraits.h"
-
-namespace llvm {
-
-//template <typename T> struct GraphTraits;
-
-
-template <> struct GraphTraits<clang::Stmt*> {
- typedef clang::Stmt NodeType;
- typedef clang::Stmt::child_iterator ChildIteratorType;
- typedef llvm::df_iterator<clang::Stmt*> nodes_iterator;
-
- static NodeType* getEntryNode(clang::Stmt* S) { return S; }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- if (N) return N->child_begin();
- else return ChildIteratorType();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- if (N) return N->child_end();
- else return ChildIteratorType();
- }
-
- static nodes_iterator nodes_begin(clang::Stmt* S) {
- return df_begin(S);
- }
-
- static nodes_iterator nodes_end(clang::Stmt* S) {
- return df_end(S);
- }
-};
-
-
-template <> struct GraphTraits<const clang::Stmt*> {
- typedef const clang::Stmt NodeType;
- typedef clang::Stmt::const_child_iterator ChildIteratorType;
- typedef llvm::df_iterator<const clang::Stmt*> nodes_iterator;
-
- static NodeType* getEntryNode(const clang::Stmt* S) { return S; }
-
- static inline ChildIteratorType child_begin(NodeType* N) {
- if (N) return N->child_begin();
- else return ChildIteratorType();
- }
-
- static inline ChildIteratorType child_end(NodeType* N) {
- if (N) return N->child_end();
- else return ChildIteratorType();
- }
-
- static nodes_iterator nodes_begin(const clang::Stmt* S) {
- return df_begin(S);
- }
-
- static nodes_iterator nodes_end(const clang::Stmt* S) {
- return df_end(S);
- }
-};
-
-
-} // end namespace llvm
-
-#endif
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
deleted file mode 100644
index 81f8ad43..0000000
--- a/include/clang/AST/StmtIterator.h
+++ /dev/null
@@ -1,144 +0,0 @@
-//===--- StmtIterator.h - Iterators for Statements --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the StmtIterator and ConstStmtIterator classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTITERATOR_H
-#define LLVM_CLANG_AST_STMTITERATOR_H
-
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
-#include <cassert>
-#include <cstddef>
-#include <iterator>
-#include <utility>
-
-namespace clang {
-
-class Stmt;
-class Decl;
-class VariableArrayType;
-
-class StmtIteratorBase {
-protected:
- enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2,
- Flags = 0x3 };
-
- union {
- Stmt **stmt;
- Decl **DGI;
- };
- uintptr_t RawVAPtr;
- Decl **DGE;
-
- bool inDeclGroup() const {
- return (RawVAPtr & Flags) == DeclGroupMode;
- }
-
- bool inSizeOfTypeVA() const {
- return (RawVAPtr & Flags) == SizeOfTypeVAMode;
- }
-
- bool inStmt() const {
- return (RawVAPtr & Flags) == StmtMode;
- }
-
- const VariableArrayType *getVAPtr() const {
- return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags);
- }
-
- void setVAPtr(const VariableArrayType *P) {
- assert (inDeclGroup() || inSizeOfTypeVA());
- RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
- }
-
- void NextDecl(bool ImmediateAdvance = true);
- bool HandleDecl(Decl* D);
- void NextVA();
-
- Stmt*& GetDeclExpr() const;
-
- StmtIteratorBase(Stmt **s) : stmt(s), RawVAPtr(0) {}
- StmtIteratorBase(const VariableArrayType *t);
- StmtIteratorBase(Decl **dgi, Decl **dge);
- StmtIteratorBase() : stmt(nullptr), RawVAPtr(0) {}
-};
-
-
-template <typename DERIVED, typename REFERENCE>
-class StmtIteratorImpl : public StmtIteratorBase,
- public std::iterator<std::forward_iterator_tag,
- REFERENCE, ptrdiff_t,
- REFERENCE, REFERENCE> {
-protected:
- StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
-public:
- StmtIteratorImpl() {}
- StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
- StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
- StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
-
- DERIVED& operator++() {
- if (inStmt())
- ++stmt;
- else if (getVAPtr())
- NextVA();
- else
- NextDecl();
-
- return static_cast<DERIVED&>(*this);
- }
-
- DERIVED operator++(int) {
- DERIVED tmp = static_cast<DERIVED&>(*this);
- operator++();
- return tmp;
- }
-
- bool operator==(const DERIVED& RHS) const {
- return stmt == RHS.stmt && DGI == RHS.DGI && RawVAPtr == RHS.RawVAPtr;
- }
-
- bool operator!=(const DERIVED& RHS) const {
- return stmt != RHS.stmt || DGI != RHS.DGI || RawVAPtr != RHS.RawVAPtr;
- }
-
- REFERENCE operator*() const {
- return inStmt() ? *stmt : GetDeclExpr();
- }
-
- REFERENCE operator->() const { return operator*(); }
-};
-
-struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
- explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
-
- StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
-
- StmtIterator(Decl** dgi, Decl** dge)
- : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
-
- StmtIterator(const VariableArrayType *t)
- : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
-};
-
-struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
- const Stmt*> {
- explicit ConstStmtIterator() :
- StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
-
- ConstStmtIterator(const StmtIterator& RHS) :
- StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
deleted file mode 100644
index 68fe3ef..0000000
--- a/include/clang/AST/StmtObjC.h
+++ /dev/null
@@ -1,375 +0,0 @@
-//===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-/// \file
-/// \brief Defines the Objective-C statement AST node classes.
-
-#ifndef LLVM_CLANG_AST_STMTOBJC_H
-#define LLVM_CLANG_AST_STMTOBJC_H
-
-#include "clang/AST/Stmt.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-
-/// \brief Represents Objective-C's collection statement.
-///
-/// This is represented as 'for (element 'in' collection-expression)' stmt.
-class ObjCForCollectionStmt : public Stmt {
- enum { ELEM, COLLECTION, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
- SourceLocation ForLoc;
- SourceLocation RParenLoc;
-public:
- ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
- SourceLocation FCL, SourceLocation RPL);
- explicit ObjCForCollectionStmt(EmptyShell Empty) :
- Stmt(ObjCForCollectionStmtClass, Empty) { }
-
- Stmt *getElement() { return SubExprs[ELEM]; }
- Expr *getCollection() {
- return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
- }
- Stmt *getBody() { return SubExprs[BODY]; }
-
- const Stmt *getElement() const { return SubExprs[ELEM]; }
- const Expr *getCollection() const {
- return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
- }
- const Stmt *getBody() const { return SubExprs[BODY]; }
-
- void setElement(Stmt *S) { SubExprs[ELEM] = S; }
- void setCollection(Expr *E) {
- SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E);
- }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
-
- SourceLocation getForLoc() const { return ForLoc; }
- void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return SubExprs[BODY]->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCForCollectionStmtClass;
- }
-
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
- }
-};
-
-/// \brief Represents Objective-C's \@catch statement.
-class ObjCAtCatchStmt : public Stmt {
-private:
- VarDecl *ExceptionDecl;
- Stmt *Body;
- SourceLocation AtCatchLoc, RParenLoc;
-
-public:
- ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
- VarDecl *catchVarDecl,
- Stmt *atCatchStmt)
- : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl),
- Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { }
-
- explicit ObjCAtCatchStmt(EmptyShell Empty) :
- Stmt(ObjCAtCatchStmtClass, Empty) { }
-
- const Stmt *getCatchBody() const { return Body; }
- Stmt *getCatchBody() { return Body; }
- void setCatchBody(Stmt *S) { Body = S; }
-
- const VarDecl *getCatchParamDecl() const {
- return ExceptionDecl;
- }
- VarDecl *getCatchParamDecl() {
- return ExceptionDecl;
- }
- void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; }
-
- SourceLocation getAtCatchLoc() const { return AtCatchLoc; }
- void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtCatchLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return Body->getLocEnd(); }
-
- bool hasEllipsis() const { return getCatchParamDecl() == nullptr; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtCatchStmtClass;
- }
-
- child_range children() { return child_range(&Body, &Body + 1); }
-};
-
-/// \brief Represents Objective-C's \@finally statement
-class ObjCAtFinallyStmt : public Stmt {
- SourceLocation AtFinallyLoc;
- Stmt *AtFinallyStmt;
-
-public:
- ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
- : Stmt(ObjCAtFinallyStmtClass), AtFinallyLoc(atFinallyLoc),
- AtFinallyStmt(atFinallyStmt) {}
-
- explicit ObjCAtFinallyStmt(EmptyShell Empty) :
- Stmt(ObjCAtFinallyStmtClass, Empty) { }
-
- const Stmt *getFinallyBody() const { return AtFinallyStmt; }
- Stmt *getFinallyBody() { return AtFinallyStmt; }
- void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtFinallyLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return AtFinallyStmt->getLocEnd();
- }
-
- SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
- void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtFinallyStmtClass;
- }
-
- child_range children() {
- return child_range(&AtFinallyStmt, &AtFinallyStmt+1);
- }
-};
-
-/// \brief Represents Objective-C's \@try ... \@catch ... \@finally statement.
-class ObjCAtTryStmt : public Stmt {
-private:
- // The location of the @ in the \@try.
- SourceLocation AtTryLoc;
-
- // The number of catch blocks in this statement.
- unsigned NumCatchStmts : 16;
-
- // Whether this statement has a \@finally statement.
- bool HasFinally : 1;
-
- /// \brief Retrieve the statements that are stored after this \@try statement.
- ///
- /// The order of the statements in memory follows the order in the source,
- /// with the \@try body first, followed by the \@catch statements (if any)
- /// and, finally, the \@finally (if it exists).
- Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
- const Stmt* const *getStmts() const {
- return reinterpret_cast<const Stmt * const*> (this + 1);
- }
-
- ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
- Stmt **CatchStmts, unsigned NumCatchStmts,
- Stmt *atFinallyStmt);
-
- explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts,
- bool HasFinally)
- : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
- HasFinally(HasFinally) { }
-
-public:
- static ObjCAtTryStmt *Create(const ASTContext &Context,
- SourceLocation atTryLoc, Stmt *atTryStmt,
- Stmt **CatchStmts, unsigned NumCatchStmts,
- Stmt *atFinallyStmt);
- static ObjCAtTryStmt *CreateEmpty(const ASTContext &Context,
- unsigned NumCatchStmts, bool HasFinally);
-
- /// \brief Retrieve the location of the @ in the \@try.
- SourceLocation getAtTryLoc() const { return AtTryLoc; }
- void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
-
- /// \brief Retrieve the \@try body.
- const Stmt *getTryBody() const { return getStmts()[0]; }
- Stmt *getTryBody() { return getStmts()[0]; }
- void setTryBody(Stmt *S) { getStmts()[0] = S; }
-
- /// \brief Retrieve the number of \@catch statements in this try-catch-finally
- /// block.
- unsigned getNumCatchStmts() const { return NumCatchStmts; }
-
- /// \brief Retrieve a \@catch statement.
- const ObjCAtCatchStmt *getCatchStmt(unsigned I) const {
- assert(I < NumCatchStmts && "Out-of-bounds @catch index");
- return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
- }
-
- /// \brief Retrieve a \@catch statement.
- ObjCAtCatchStmt *getCatchStmt(unsigned I) {
- assert(I < NumCatchStmts && "Out-of-bounds @catch index");
- return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
- }
-
- /// \brief Set a particular catch statement.
- void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) {
- assert(I < NumCatchStmts && "Out-of-bounds @catch index");
- getStmts()[I + 1] = S;
- }
-
- /// \brief Retrieve the \@finally statement, if any.
- const ObjCAtFinallyStmt *getFinallyStmt() const {
- if (!HasFinally)
- return nullptr;
-
- return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
- }
- ObjCAtFinallyStmt *getFinallyStmt() {
- if (!HasFinally)
- return nullptr;
-
- return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
- }
- void setFinallyStmt(Stmt *S) {
- assert(HasFinally && "@try does not have a @finally slot!");
- getStmts()[1 + NumCatchStmts] = S;
- }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtTryLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY;
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtTryStmtClass;
- }
-
- child_range children() {
- return child_range(getStmts(),
- getStmts() + 1 + NumCatchStmts + HasFinally);
- }
-};
-
-/// \brief Represents Objective-C's \@synchronized statement.
-///
-/// Example:
-/// \code
-/// @synchronized (sem) {
-/// do-something;
-/// }
-/// \endcode
-class ObjCAtSynchronizedStmt : public Stmt {
-private:
- SourceLocation AtSynchronizedLoc;
- enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
- Stmt* SubStmts[END_EXPR];
-
-public:
- ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
- Stmt *synchBody)
- : Stmt(ObjCAtSynchronizedStmtClass) {
- SubStmts[SYNC_EXPR] = synchExpr;
- SubStmts[SYNC_BODY] = synchBody;
- AtSynchronizedLoc = atSynchronizedLoc;
- }
- explicit ObjCAtSynchronizedStmt(EmptyShell Empty) :
- Stmt(ObjCAtSynchronizedStmtClass, Empty) { }
-
- SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
- void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; }
-
- const CompoundStmt *getSynchBody() const {
- return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
- }
- CompoundStmt *getSynchBody() {
- return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
- }
- void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; }
-
- const Expr *getSynchExpr() const {
- return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
- }
- Expr *getSynchExpr() {
- return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
- }
- void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtSynchronizedLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return getSynchBody()->getLocEnd();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
- }
-
- child_range children() {
- return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR);
- }
-};
-
-/// \brief Represents Objective-C's \@throw statement.
-class ObjCAtThrowStmt : public Stmt {
- SourceLocation AtThrowLoc;
- Stmt *Throw;
-
-public:
- ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
- : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
- AtThrowLoc = atThrowLoc;
- }
- explicit ObjCAtThrowStmt(EmptyShell Empty) :
- Stmt(ObjCAtThrowStmtClass, Empty) { }
-
- const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
- Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
- void setThrowExpr(Stmt *S) { Throw = S; }
-
- SourceLocation getThrowLoc() { return AtThrowLoc; }
- void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return Throw ? Throw->getLocEnd() : AtThrowLoc;
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAtThrowStmtClass;
- }
-
- child_range children() { return child_range(&Throw, &Throw+1); }
-};
-
-/// \brief Represents Objective-C's \@autoreleasepool Statement
-class ObjCAutoreleasePoolStmt : public Stmt {
- SourceLocation AtLoc;
- Stmt *SubStmt;
-
-public:
- ObjCAutoreleasePoolStmt(SourceLocation atLoc, Stmt *subStmt)
- : Stmt(ObjCAutoreleasePoolStmtClass), AtLoc(atLoc), SubStmt(subStmt) {}
-
- explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
- Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }
-
- const Stmt *getSubStmt() const { return SubStmt; }
- Stmt *getSubStmt() { return SubStmt; }
- void setSubStmt(Stmt *S) { SubStmt = S; }
-
- SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
-
- SourceLocation getAtLoc() const { return AtLoc; }
- void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
- }
-
- child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
deleted file mode 100644
index 1ba859c..0000000
--- a/include/clang/AST/StmtOpenMP.h
+++ /dev/null
@@ -1,2422 +0,0 @@
-//===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// \brief This file defines OpenMP AST classes for executable directives and
-/// clauses.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTOPENMP_H
-#define LLVM_CLANG_AST_STMTOPENMP_H
-
-#include "clang/AST/Expr.h"
-#include "clang/AST/OpenMPClause.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Basic/OpenMPKinds.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-// AST classes for directives.
-//===----------------------------------------------------------------------===//
-
-/// \brief This is a basic class for representing single OpenMP executable
-/// directive.
-///
-class OMPExecutableDirective : public Stmt {
- friend class ASTStmtReader;
- /// \brief Kind of the directive.
- OpenMPDirectiveKind Kind;
- /// \brief Starting location of the directive (directive keyword).
- SourceLocation StartLoc;
- /// \brief Ending location of the directive.
- SourceLocation EndLoc;
- /// \brief Numbers of clauses.
- const unsigned NumClauses;
- /// \brief Number of child expressions/stmts.
- const unsigned NumChildren;
- /// \brief Offset from this to the start of clauses.
- /// There are NumClauses pointers to clauses, they are followed by
- /// NumChildren pointers to child stmts/exprs (if the directive type
- /// requires an associated stmt, then it has to be the first of them).
- const unsigned ClausesOffset;
-
- /// \brief Get the clauses storage.
- MutableArrayRef<OMPClause *> getClauses() {
- OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
- reinterpret_cast<char *>(this) + ClausesOffset);
- return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
- }
-
-protected:
- /// \brief Build instance of directive of class \a K.
- ///
- /// \param SC Statement class.
- /// \param K Kind of OpenMP directive.
- /// \param StartLoc Starting location of the directive (directive keyword).
- /// \param EndLoc Ending location of the directive.
- ///
- template <typename T>
- OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
- SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses, unsigned NumChildren)
- : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
- EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
- NumChildren(NumChildren),
- ClausesOffset(llvm::RoundUpToAlignment(sizeof(T),
- llvm::alignOf<OMPClause *>())) {}
-
- /// \brief Sets the list of variables for this clause.
- ///
- /// \param Clauses The list of clauses for the directive.
- ///
- void setClauses(ArrayRef<OMPClause *> Clauses);
-
- /// \brief Set the associated statement for the directive.
- ///
- /// /param S Associated statement.
- ///
- void setAssociatedStmt(Stmt *S) {
- assert(hasAssociatedStmt() && "no associated statement.");
- *child_begin() = S;
- }
-
-public:
- /// \brief Iterates over a filtered subrange of clauses applied to a
- /// directive.
- ///
- /// This iterator visits only clauses of type SpecificClause.
- template <typename SpecificClause>
- class specific_clause_iterator
- : public llvm::iterator_adaptor_base<
- specific_clause_iterator<SpecificClause>,
- ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
- const SpecificClause *, ptrdiff_t, const SpecificClause *,
- const SpecificClause *> {
- ArrayRef<OMPClause *>::const_iterator End;
-
- void SkipToNextClause() {
- while (this->I != End && !isa<SpecificClause>(*this->I))
- ++this->I;
- }
-
- public:
- explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
- : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
- End(Clauses.end()) {
- SkipToNextClause();
- }
-
- const SpecificClause *operator*() const {
- return cast<SpecificClause>(*this->I);
- }
- const SpecificClause *operator->() const { return **this; }
-
- specific_clause_iterator &operator++() {
- ++this->I;
- SkipToNextClause();
- return *this;
- }
- };
-
- template <typename SpecificClause>
- static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
- getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
- return {specific_clause_iterator<SpecificClause>(Clauses),
- specific_clause_iterator<SpecificClause>(
- llvm::makeArrayRef(Clauses.end(), 0))};
- }
-
- template <typename SpecificClause>
- llvm::iterator_range<specific_clause_iterator<SpecificClause>>
- getClausesOfKind() const {
- return getClausesOfKind<SpecificClause>(clauses());
- }
-
- /// Gets a single clause of the specified kind associated with the
- /// current directive iff there is only one clause of this kind (and assertion
- /// is fired if there is more than one clause is associated with the
- /// directive). Returns nullptr if no clause of this kind is associated with
- /// the directive.
- template <typename SpecificClause>
- const SpecificClause *getSingleClause() const {
- auto Clauses = getClausesOfKind<SpecificClause>();
-
- if (Clauses.begin() != Clauses.end()) {
- assert(std::next(Clauses.begin()) == Clauses.end() &&
- "There are at least 2 clauses of the specified kind");
- return *Clauses.begin();
- }
- return nullptr;
- }
-
- /// Returns true if the current directive has one or more clauses of a
- /// specific kind.
- template <typename SpecificClause>
- bool hasClausesOfKind() const {
- auto Clauses = getClausesOfKind<SpecificClause>();
- return Clauses.begin() != Clauses.end();
- }
-
- /// \brief Returns starting location of directive kind.
- SourceLocation getLocStart() const { return StartLoc; }
- /// \brief Returns ending location of directive.
- SourceLocation getLocEnd() const { return EndLoc; }
-
- /// \brief Set starting location of directive kind.
- ///
- /// \param Loc New starting location of directive.
- ///
- void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
- /// \brief Set ending location of directive.
- ///
- /// \param Loc New ending location of directive.
- ///
- void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
-
- /// \brief Get number of clauses.
- unsigned getNumClauses() const { return NumClauses; }
-
- /// \brief Returns specified clause.
- ///
- /// \param i Number of clause.
- ///
- OMPClause *getClause(unsigned i) const { return clauses()[i]; }
-
- /// \brief Returns true if directive has associated statement.
- bool hasAssociatedStmt() const { return NumChildren > 0; }
-
- /// \brief Returns statement associated with the directive.
- Stmt *getAssociatedStmt() const {
- assert(hasAssociatedStmt() && "no associated statement.");
- return const_cast<Stmt *>(*child_begin());
- }
-
- OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
-
- static bool classof(const Stmt *S) {
- return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
- S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
- }
-
- child_range children() {
- if (!hasAssociatedStmt())
- return child_range(child_iterator(), child_iterator());
- Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
- return child_range(ChildStorage, ChildStorage + NumChildren);
- }
-
- ArrayRef<OMPClause *> clauses() { return getClauses(); }
-
- ArrayRef<OMPClause *> clauses() const {
- return const_cast<OMPExecutableDirective *>(this)->getClauses();
- }
-};
-
-/// \brief This represents '#pragma omp parallel' directive.
-///
-/// \code
-/// #pragma omp parallel private(a,b) reduction(+: c,d)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clauses 'private'
-/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
-/// variables 'c' and 'd'.
-///
-class OMPParallelDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief true if the construct has inner cancel directive.
- bool HasCancel;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive (directive keyword).
- /// \param EndLoc Ending Location of the directive.
- ///
- OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
- StartLoc, EndLoc, NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPParallelDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief 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 Clauses List of clauses.
- /// \param AssociatedStmt Statement associated with the directive.
- /// \param HasCancel true if this directive has inner cancel directive.
- ///
- static OMPParallelDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
-
- /// \brief Creates an empty directive with the place for \a N clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPParallelDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPParallelDirectiveClass;
- }
-};
-
-/// \brief This is a common base class for loop directives ('omp simd', 'omp
-/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
-///
-class OMPLoopDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Number of collapsed loops as specified by 'collapse' clause.
- unsigned CollapsedNum;
-
- /// \brief Offsets to the stored exprs.
- /// This enumeration contains offsets to all the pointers to children
- /// expressions stored in OMPLoopDirective.
- /// The first 9 children are nesessary for all the loop directives, and
- /// the next 7 are specific to the worksharing ones.
- /// After the fixed children, three arrays of length CollapsedNum are
- /// allocated: loop counters, their updates and final values.
- ///
- enum {
- AssociatedStmtOffset = 0,
- IterationVariableOffset = 1,
- LastIterationOffset = 2,
- CalcLastIterationOffset = 3,
- PreConditionOffset = 4,
- CondOffset = 5,
- InitOffset = 6,
- IncOffset = 7,
- // 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).
- DefaultEnd = 8,
- // The following 7 exprs are used by worksharing loops only.
- IsLastIterVariableOffset = 8,
- LowerBoundVariableOffset = 9,
- UpperBoundVariableOffset = 10,
- StrideVariableOffset = 11,
- EnsureUpperBoundOffset = 12,
- NextLowerBoundOffset = 13,
- NextUpperBoundOffset = 14,
- // Offset to the end (and start of the following counters/updates/finals
- // arrays) for worksharing loop directives.
- WorksharingEnd = 15,
- };
-
- /// \brief Get the counters storage.
- MutableArrayRef<Expr *> getCounters() {
- Expr **Storage = reinterpret_cast<Expr **>(
- &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
- return MutableArrayRef<Expr *>(Storage, CollapsedNum);
- }
-
- /// \brief Get the private counters storage.
- MutableArrayRef<Expr *> getPrivateCounters() {
- Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
- child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
- return MutableArrayRef<Expr *>(Storage, CollapsedNum);
- }
-
- /// \brief Get the updates storage.
- MutableArrayRef<Expr *> getInits() {
- Expr **Storage = reinterpret_cast<Expr **>(
- &*std::next(child_begin(),
- getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
- return MutableArrayRef<Expr *>(Storage, CollapsedNum);
- }
-
- /// \brief Get the updates storage.
- MutableArrayRef<Expr *> getUpdates() {
- Expr **Storage = reinterpret_cast<Expr **>(
- &*std::next(child_begin(),
- getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
- return MutableArrayRef<Expr *>(Storage, CollapsedNum);
- }
-
- /// \brief Get the final counter updates storage.
- MutableArrayRef<Expr *> getFinals() {
- Expr **Storage = reinterpret_cast<Expr **>(
- &*std::next(child_begin(),
- getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
- return MutableArrayRef<Expr *>(Storage, CollapsedNum);
- }
-
-protected:
- /// \brief Build instance of loop directive of class \a Kind.
- ///
- /// \param SC Statement class.
- /// \param Kind Kind of OpenMP directive.
- /// \param StartLoc Starting location of the directive (directive keyword).
- /// \param EndLoc Ending location of the directive.
- /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
- /// \param NumClauses Number of clauses.
- /// \param NumSpecialChildren Number of additional directive-specific stmts.
- ///
- template <typename T>
- OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
- SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses,
- unsigned NumSpecialChildren = 0)
- : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
- numLoopChildren(CollapsedNum, Kind) +
- NumSpecialChildren),
- CollapsedNum(CollapsedNum) {}
-
- /// \brief Offset to the start of children expression arrays.
- static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
- return (isOpenMPWorksharingDirective(Kind) ||
- isOpenMPTaskLoopDirective(Kind) ||
- isOpenMPDistributeDirective(Kind))
- ? WorksharingEnd
- : DefaultEnd;
- }
-
- /// \brief Children number.
- static unsigned numLoopChildren(unsigned CollapsedNum,
- OpenMPDirectiveKind Kind) {
- return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
- // PrivateCounters, Inits,
- // Updates and Finals
- }
-
- void setIterationVariable(Expr *IV) {
- *std::next(child_begin(), IterationVariableOffset) = IV;
- }
- void setLastIteration(Expr *LI) {
- *std::next(child_begin(), LastIterationOffset) = LI;
- }
- void setCalcLastIteration(Expr *CLI) {
- *std::next(child_begin(), CalcLastIterationOffset) = CLI;
- }
- void setPreCond(Expr *PC) {
- *std::next(child_begin(), PreConditionOffset) = PC;
- }
- void setCond(Expr *Cond) {
- *std::next(child_begin(), CondOffset) = Cond;
- }
- void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
- void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
- void setIsLastIterVariable(Expr *IL) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), IsLastIterVariableOffset) = IL;
- }
- void setLowerBoundVariable(Expr *LB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), LowerBoundVariableOffset) = LB;
- }
- void setUpperBoundVariable(Expr *UB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), UpperBoundVariableOffset) = UB;
- }
- void setStrideVariable(Expr *ST) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), StrideVariableOffset) = ST;
- }
- void setEnsureUpperBound(Expr *EUB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
- }
- void setNextLowerBound(Expr *NLB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), NextLowerBoundOffset) = NLB;
- }
- void setNextUpperBound(Expr *NUB) {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
- isOpenMPDistributeDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- *std::next(child_begin(), NextUpperBoundOffset) = NUB;
- }
- void setCounters(ArrayRef<Expr *> A);
- void setPrivateCounters(ArrayRef<Expr *> A);
- void setInits(ArrayRef<Expr *> A);
- void setUpdates(ArrayRef<Expr *> A);
- void setFinals(ArrayRef<Expr *> A);
-
-public:
- /// \brief The expressions built for the OpenMP loop CodeGen for the
- /// whole collapsed loop nest.
- struct HelperExprs {
- /// \brief Loop iteration variable.
- Expr *IterationVarRef;
- /// \brief Loop last iteration number.
- Expr *LastIteration;
- /// \brief Loop number of iterations.
- Expr *NumIterations;
- /// \brief Calculation of last iteration.
- Expr *CalcLastIteration;
- /// \brief Loop pre-condition.
- Expr *PreCond;
- /// \brief Loop condition.
- Expr *Cond;
- /// \brief Loop iteration variable init.
- Expr *Init;
- /// \brief Loop increment.
- Expr *Inc;
- /// \brief IsLastIteration - local flag variable passed to runtime.
- Expr *IL;
- /// \brief LowerBound - local variable passed to runtime.
- Expr *LB;
- /// \brief UpperBound - local variable passed to runtime.
- Expr *UB;
- /// \brief Stride - local variable passed to runtime.
- Expr *ST;
- /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
- Expr *EUB;
- /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
- Expr *NLB;
- /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
- Expr *NUB;
- /// \brief Counters Loop counters.
- SmallVector<Expr *, 4> Counters;
- /// \brief PrivateCounters Loop counters.
- SmallVector<Expr *, 4> PrivateCounters;
- /// \brief Expressions for loop counters inits for CodeGen.
- SmallVector<Expr *, 4> Inits;
- /// \brief Expressions for loop counters update for CodeGen.
- SmallVector<Expr *, 4> Updates;
- /// \brief Final loop counter values for GodeGen.
- SmallVector<Expr *, 4> Finals;
-
- /// \brief Check if all the expressions are built (does not check the
- /// worksharing ones).
- bool builtAll() {
- return IterationVarRef != nullptr && LastIteration != nullptr &&
- NumIterations != nullptr && PreCond != nullptr &&
- Cond != nullptr && Init != nullptr && Inc != nullptr;
- }
-
- /// \brief Initialize all the fields to null.
- /// \param Size Number of elements in the counters/finals/updates arrays.
- void clear(unsigned Size) {
- IterationVarRef = nullptr;
- LastIteration = nullptr;
- CalcLastIteration = nullptr;
- PreCond = nullptr;
- Cond = nullptr;
- Init = nullptr;
- Inc = nullptr;
- IL = nullptr;
- LB = nullptr;
- UB = nullptr;
- ST = nullptr;
- EUB = nullptr;
- NLB = nullptr;
- NUB = nullptr;
- Counters.resize(Size);
- PrivateCounters.resize(Size);
- Inits.resize(Size);
- Updates.resize(Size);
- Finals.resize(Size);
- for (unsigned i = 0; i < Size; ++i) {
- Counters[i] = nullptr;
- PrivateCounters[i] = nullptr;
- Inits[i] = nullptr;
- Updates[i] = nullptr;
- Finals[i] = nullptr;
- }
- }
- };
-
- /// \brief Get number of collapsed loops.
- unsigned getCollapsedNumber() const { return CollapsedNum; }
-
- Expr *getIterationVariable() const {
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), IterationVariableOffset)));
- }
- Expr *getLastIteration() const {
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), LastIterationOffset)));
- }
- Expr *getCalcLastIteration() const {
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), CalcLastIterationOffset)));
- }
- Expr *getPreCond() const {
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), PreConditionOffset)));
- }
- Expr *getCond() const {
- return const_cast<Expr *>(
- reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
- }
- Expr *getInit() const {
- return const_cast<Expr *>(
- reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
- }
- Expr *getInc() const {
- return const_cast<Expr *>(
- reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
- }
- Expr *getIsLastIterVariable() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), IsLastIterVariableOffset)));
- }
- Expr *getLowerBoundVariable() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), LowerBoundVariableOffset)));
- }
- Expr *getUpperBoundVariable() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), UpperBoundVariableOffset)));
- }
- Expr *getStrideVariable() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), StrideVariableOffset)));
- }
- Expr *getEnsureUpperBound() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), EnsureUpperBoundOffset)));
- }
- Expr *getNextLowerBound() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), NextLowerBoundOffset)));
- }
- Expr *getNextUpperBound() const {
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
- isOpenMPTaskLoopDirective(getDirectiveKind())) &&
- "expected worksharing loop directive");
- return const_cast<Expr *>(reinterpret_cast<const Expr *>(
- *std::next(child_begin(), NextUpperBoundOffset)));
- }
- const Stmt *getBody() const {
- // This relies on the loop form is already checked by Sema.
- Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
- Body = cast<ForStmt>(Body)->getBody();
- for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
- Body = Body->IgnoreContainers();
- Body = cast<ForStmt>(Body)->getBody();
- }
- return Body;
- }
-
- ArrayRef<Expr *> counters() { return getCounters(); }
-
- ArrayRef<Expr *> counters() const {
- return const_cast<OMPLoopDirective *>(this)->getCounters();
- }
-
- ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
-
- ArrayRef<Expr *> private_counters() const {
- return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
- }
-
- ArrayRef<Expr *> inits() { return getInits(); }
-
- ArrayRef<Expr *> inits() const {
- return const_cast<OMPLoopDirective *>(this)->getInits();
- }
-
- ArrayRef<Expr *> updates() { return getUpdates(); }
-
- ArrayRef<Expr *> updates() const {
- return const_cast<OMPLoopDirective *>(this)->getUpdates();
- }
-
- ArrayRef<Expr *> finals() { return getFinals(); }
-
- ArrayRef<Expr *> finals() const {
- return const_cast<OMPLoopDirective *>(this)->getFinals();
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSimdDirectiveClass ||
- T->getStmtClass() == OMPForDirectiveClass ||
- T->getStmtClass() == OMPForSimdDirectiveClass ||
- T->getStmtClass() == OMPParallelForDirectiveClass ||
- T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
- T->getStmtClass() == OMPTaskLoopDirectiveClass ||
- T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
- T->getStmtClass() == OMPDistributeDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp simd' directive.
-///
-/// \code
-/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp simd' has clauses 'private'
-/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
-/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
-///
-class OMPSimdDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief 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.
- ///
- OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
- EndLoc, CollapsedNum, NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses) {}
-
-public:
- /// \brief 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 OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt,
- const HelperExprs &Exprs);
-
- /// \brief 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 OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSimdDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp for' directive.
-///
-/// \code
-/// #pragma omp for private(a,b) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp for' has clauses 'private' with the
-/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
-/// and 'd'.
-///
-class OMPForDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief 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.
- ///
- OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
- CollapsedNum, NumClauses),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief 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.
- /// \param HasCancel true if current directive has inner cancel directive.
- ///
- static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned CollapsedNum,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs,
- bool HasCancel);
-
- /// \brief 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 OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPForDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp for simd' directive.
-///
-/// \code
-/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp for simd' has clauses 'private'
-/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
-/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
-///
-class OMPForSimdDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief 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.
- ///
- OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
- StartLoc, EndLoc, CollapsedNum, NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses) {}
-
-public:
- /// \brief 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 OMPForSimdDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief 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 OMPForSimdDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPForSimdDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp sections' directive.
-///
-/// \code
-/// #pragma omp sections private(a,b) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp sections' has clauses 'private' with
-/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
-/// 'c' and 'd'.
-///
-class OMPSectionsDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
- StartLoc, EndLoc, NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPSectionsDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief 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 Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param HasCancel true if current directive has inner directive.
- ///
- static OMPSectionsDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSectionsDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp section' directive.
-///
-/// \code
-/// #pragma omp section
-/// \endcode
-///
-class OMPSectionDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
- StartLoc, EndLoc, 0, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPSectionDirective()
- : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
- SourceLocation(), SourceLocation(), 0, 1),
- HasCancel(false) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param HasCancel true if current directive has inner directive.
- ///
- static OMPSectionDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt, bool HasCancel);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSectionDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp single' directive.
-///
-/// \code
-/// #pragma omp single private(a,b) copyprivate(c,d)
-/// \endcode
-/// In this example directive '#pragma omp single' has clauses 'private' with
-/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
-///
-class OMPSingleDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
- StartLoc, EndLoc, NumClauses, 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPSingleDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
- SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
-
-public:
- /// \brief 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 Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPSingleDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPSingleDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPSingleDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp master' directive.
-///
-/// \code
-/// #pragma omp master
-/// \endcode
-///
-class OMPMasterDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
- StartLoc, EndLoc, 0, 1) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPMasterDirective()
- : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
- SourceLocation(), SourceLocation(), 0, 1) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPMasterDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPMasterDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp critical' directive.
-///
-/// \code
-/// #pragma omp critical
-/// \endcode
-///
-class OMPCriticalDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Name of the directive.
- DeclarationNameInfo DirName;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param Name Name of the directive.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- /// \param NumClauses Number of clauses.
- ///
- OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
- SourceLocation EndLoc, unsigned NumClauses)
- : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
- StartLoc, EndLoc, NumClauses, 1),
- DirName(Name) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPCriticalDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- DirName() {}
-
- /// \brief Set name of the directive.
- ///
- /// \param Name Name of the directive.
- ///
- void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param Name Name of the directive.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPCriticalDirective *
- Create(const ASTContext &C, const DeclarationNameInfo &Name,
- SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief Return name of the directive.
- ///
- DeclarationNameInfo getDirectiveName() const { return DirName; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPCriticalDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp parallel for' directive.
-///
-/// \code
-/// #pragma omp parallel for private(a,b) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp parallel for' has clauses 'private'
-/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
-/// variables 'c' and 'd'.
-///
-class OMPParallelForDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current region has inner cancel directive.
- bool HasCancel;
-
- /// \brief 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.
- ///
- OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
- StartLoc, EndLoc, CollapsedNum, NumClauses),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief 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.
- /// \param HasCancel true if current directive has inner cancel directive.
- ///
- static OMPParallelForDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
-
- /// \brief 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 OMPParallelForDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum,
- EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPParallelForDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp parallel for simd' directive.
-///
-/// \code
-/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp parallel for simd' has clauses
-/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
-/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
-/// 'd'.
-///
-class OMPParallelForSimdDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief 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.
- ///
- OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
- OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
- NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
- unsigned NumClauses)
- : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
- OMPD_parallel_for_simd, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses) {}
-
-public:
- /// \brief 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 OMPParallelForSimdDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief 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 OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum,
- EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp parallel sections' directive.
-///
-/// \code
-/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
-/// \endcode
-/// In this example directive '#pragma omp parallel sections' has clauses
-/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
-/// and variables 'c' and 'd'.
-///
-class OMPParallelSectionsDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
-
- /// \brief true if current directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
- OMPD_parallel_sections, StartLoc, EndLoc,
- NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPParallelSectionsDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
- OMPD_parallel_sections, SourceLocation(),
- SourceLocation(), NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief 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 Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param HasCancel true if current directive has inner cancel directive.
- ///
- static OMPParallelSectionsDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPParallelSectionsDirective *
- CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp task' directive.
-///
-/// \code
-/// #pragma omp task private(a,b) final(d)
-/// \endcode
-/// In this example directive '#pragma omp task' has clauses 'private' with the
-/// variables 'a' and 'b' and 'final' with condition 'd'.
-///
-class OMPTaskDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief true if this directive has inner cancel directive.
- bool HasCancel;
-
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
- EndLoc, NumClauses, 1),
- HasCancel(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTaskDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
- SourceLocation(), SourceLocation(), NumClauses,
- 1),
- HasCancel(false) {}
-
- /// \brief Set cancel state.
- void setHasCancel(bool Has) { HasCancel = Has; }
-
-public:
- /// \brief 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 Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param HasCancel true, if current directive has inner cancel directive.
- ///
- static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, bool HasCancel);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
- EmptyShell);
-
- /// \brief Return true if current directive has inner cancel directive.
- bool hasCancel() const { return HasCancel; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskyield' directive.
-///
-/// \code
-/// #pragma omp taskyield
-/// \endcode
-///
-class OMPTaskyieldDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
- StartLoc, EndLoc, 0, 0) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPTaskyieldDirective()
- : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
- SourceLocation(), SourceLocation(), 0, 0) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- ///
- static OMPTaskyieldDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskyieldDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp barrier' directive.
-///
-/// \code
-/// #pragma omp barrier
-/// \endcode
-///
-class OMPBarrierDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
- StartLoc, EndLoc, 0, 0) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPBarrierDirective()
- : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
- SourceLocation(), SourceLocation(), 0, 0) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- ///
- static OMPBarrierDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPBarrierDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskwait' directive.
-///
-/// \code
-/// #pragma omp taskwait
-/// \endcode
-///
-class OMPTaskwaitDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
- StartLoc, EndLoc, 0, 0) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPTaskwaitDirective()
- : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
- SourceLocation(), SourceLocation(), 0, 0) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- ///
- static OMPTaskwaitDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskwaitDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskgroup' directive.
-///
-/// \code
-/// #pragma omp taskgroup
-/// \endcode
-///
-class OMPTaskgroupDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
- StartLoc, EndLoc, 0, 1) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPTaskgroupDirective()
- : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
- SourceLocation(), SourceLocation(), 0, 1) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPTaskgroupDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskgroupDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp flush' directive.
-///
-/// \code
-/// #pragma omp flush(a,b)
-/// \endcode
-/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
-/// and 'b'.
-/// 'omp flush' directive does not have clauses but have an optional list of
-/// variables to flush. This list of variables is stored within some fake clause
-/// FlushClause.
-class OMPFlushDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
- StartLoc, EndLoc, NumClauses, 0) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPFlushDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
- SourceLocation(), SourceLocation(), NumClauses,
- 0) {}
-
-public:
- /// \brief 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 Clauses List of clauses (only single OMPFlushClause clause is
- /// allowed).
- ///
- static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPFlushDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPFlushDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp ordered' directive.
-///
-/// \code
-/// #pragma omp ordered
-/// \endcode
-///
-class OMPOrderedDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
- StartLoc, EndLoc, NumClauses, 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPOrderedDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
- SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPOrderedDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPOrderedDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp atomic' directive.
-///
-/// \code
-/// #pragma omp atomic capture
-/// \endcode
-/// In this example directive '#pragma omp atomic' has clause 'capture'.
-///
-class OMPAtomicDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
- /// have atomic expressions of forms
- /// \code
- /// x = x binop expr;
- /// x = expr binop x;
- /// \endcode
- /// This field is true for the first form of the expression and false for the
- /// second. Required for correct codegen of non-associative operations (like
- /// << or >>).
- bool IsXLHSInRHSPart;
- /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
- /// have atomic expressions of forms
- /// \code
- /// v = x; <update x>;
- /// <update x>; v = x;
- /// \endcode
- /// This field is true for the first(postfix) form of the expression and false
- /// otherwise.
- bool IsPostfixUpdate;
-
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
- StartLoc, EndLoc, NumClauses, 5),
- IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPAtomicDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
- SourceLocation(), SourceLocation(), NumClauses,
- 5),
- IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
-
- /// \brief Set 'x' part of the associated expression/statement.
- void setX(Expr *X) { *std::next(child_begin()) = X; }
- /// \brief Set helper expression of the form
- /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
- /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
- /// \brief Set 'v' part of the associated expression/statement.
- void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
- /// \brief Set 'expr' part of the associated expression/statement.
- void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
-
-public:
- /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
- /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
- /// detailed description of 'x', 'v' and 'expr').
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- /// \param X 'x' part of the associated expression/statement.
- /// \param V 'v' part of the associated expression/statement.
- /// \param E 'expr' part of the associated expression/statement.
- /// \param UE Helper expression of the form
- /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
- /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
- /// second.
- /// \param IsPostfixUpdate true if original value of 'x' must be stored in
- /// 'v', not an updated one.
- static OMPAtomicDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
- Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief Get 'x' part of the associated expression/statement.
- Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
- const Expr *getX() const {
- return cast_or_null<Expr>(*std::next(child_begin()));
- }
- /// \brief Get helper expression of the form
- /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
- /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- Expr *getUpdateExpr() {
- return cast_or_null<Expr>(*std::next(child_begin(), 2));
- }
- const Expr *getUpdateExpr() const {
- return cast_or_null<Expr>(*std::next(child_begin(), 2));
- }
- /// \brief Return true if helper update expression has form
- /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
- /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
- /// \brief Return true if 'v' expression must be updated to original value of
- /// 'x', false if 'v' must be updated to the new value of 'x'.
- bool isPostfixUpdate() const { return IsPostfixUpdate; }
- /// \brief Get 'v' part of the associated expression/statement.
- Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
- const Expr *getV() const {
- return cast_or_null<Expr>(*std::next(child_begin(), 3));
- }
- /// \brief Get 'expr' part of the associated expression/statement.
- Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
- const Expr *getExpr() const {
- return cast_or_null<Expr>(*std::next(child_begin(), 4));
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPAtomicDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp target' directive.
-///
-/// \code
-/// #pragma omp target if(a)
-/// \endcode
-/// In this example directive '#pragma omp target' has clause 'if' with
-/// condition 'a'.
-///
-class OMPTargetDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
- StartLoc, EndLoc, NumClauses, 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTargetDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
- SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
-
-public:
- /// \brief 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 Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPTargetDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPTargetDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTargetDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp target data' directive.
-///
-/// \code
-/// #pragma omp target data device(0) if(a) map(b[:])
-/// \endcode
-/// In this example directive '#pragma omp target data' has clauses 'device'
-/// with the value '0', 'if' with condition 'a' and 'map' with array
-/// section 'b[:]'.
-///
-class OMPTargetDataDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief 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 NumClauses The number of clauses.
- ///
- OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
- OMPD_target_data, StartLoc, EndLoc, NumClauses,
- 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTargetDataDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
- OMPD_target_data, SourceLocation(),
- SourceLocation(), NumClauses, 1) {}
-
-public:
- /// \brief 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 Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPTargetDataDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive with the place for \a N clauses.
- ///
- /// \param C AST context.
- /// \param N The number of clauses.
- ///
- static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
- EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTargetDataDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp teams' directive.
-///
-/// \code
-/// #pragma omp teams if(a)
-/// \endcode
-/// In this example directive '#pragma omp teams' has clause 'if' with
-/// condition 'a'.
-///
-class OMPTeamsDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
- StartLoc, EndLoc, NumClauses, 1) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTeamsDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
- SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
-
-public:
- /// \brief 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 Clauses List of clauses.
- /// \param AssociatedStmt Statement, associated with the directive.
- ///
- static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
-
- /// \brief Creates an empty directive with the place for \a NumClauses
- /// clauses.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTeamsDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp cancellation point' directive.
-///
-/// \code
-/// #pragma omp cancellation point for
-/// \endcode
-///
-/// In this example a cancellation point is created for innermost 'for' region.
-class OMPCancellationPointDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- OpenMPDirectiveKind CancelRegion;
- /// \brief Build directive with the given start and end location.
- ///
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending location of the directive.
- ///
- OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
- OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
- CancelRegion(OMPD_unknown) {}
-
- /// \brief Build an empty directive.
- ///
- explicit OMPCancellationPointDirective()
- : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
- OMPD_cancellation_point, SourceLocation(),
- SourceLocation(), 0, 0),
- CancelRegion(OMPD_unknown) {}
-
- /// \brief Set cancel region for current cancellation point.
- /// \param CR Cancellation region.
- void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- ///
- static OMPCancellationPointDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- OpenMPDirectiveKind CancelRegion);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- ///
- static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
- EmptyShell);
-
- /// \brief Get cancellation region for the current cancellation point.
- OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPCancellationPointDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp cancel' directive.
-///
-/// \code
-/// #pragma omp cancel for
-/// \endcode
-///
-/// In this example a cancel is created for innermost 'for' region.
-class OMPCancelDirective : public OMPExecutableDirective {
- friend class ASTStmtReader;
- OpenMPDirectiveKind CancelRegion;
- /// \brief 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 NumClauses Number of clauses.
- ///
- OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned NumClauses)
- : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
- StartLoc, EndLoc, NumClauses, 0),
- CancelRegion(OMPD_unknown) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param NumClauses Number of clauses.
- explicit OMPCancelDirective(unsigned NumClauses)
- : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
- SourceLocation(), SourceLocation(), NumClauses,
- 0),
- CancelRegion(OMPD_unknown) {}
-
- /// \brief Set cancel region for current cancellation point.
- /// \param CR Cancellation region.
- void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
-
-public:
- /// \brief Creates directive.
- ///
- /// \param C AST context.
- /// \param StartLoc Starting location of the directive kind.
- /// \param EndLoc Ending Location of the directive.
- /// \param Clauses List of clauses.
- ///
- static OMPCancelDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
-
- /// \brief Creates an empty directive.
- ///
- /// \param C AST context.
- /// \param NumClauses Number of clauses.
- ///
- static OMPCancelDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses, EmptyShell);
-
- /// \brief Get cancellation region for the current cancellation point.
- OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPCancelDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskloop' directive.
-///
-/// \code
-/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
-/// \endcode
-/// In this example directive '#pragma omp taskloop' has clauses 'private'
-/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
-/// 'num_tasks' with expression 'num'.
-///
-class OMPTaskLoopDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief 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.
- ///
- OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
- StartLoc, EndLoc, CollapsedNum, NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses) {}
-
-public:
- /// \brief 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 OMPTaskLoopDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief 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 OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskLoopDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp taskloop simd' directive.
-///
-/// \code
-/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
-/// \endcode
-/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
-/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
-/// 'num_tasks' with expression 'num'.
-///
-class OMPTaskLoopSimdDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
- /// \brief 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.
- ///
- OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
- OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
- NumClauses) {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
- OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
- CollapsedNum, NumClauses) {}
-
-public:
- /// \brief 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 OMPTaskLoopSimdDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief 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 OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum,
- EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
- }
-};
-
-/// \brief This represents '#pragma omp distribute' directive.
-///
-/// \code
-/// #pragma omp distribute private(a,b)
-/// \endcode
-/// In this example directive '#pragma omp distribute' has clauses 'private'
-/// with the variables 'a' and 'b'
-///
-class OMPDistributeDirective : public OMPLoopDirective {
- friend class ASTStmtReader;
-
- /// \brief 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.
- ///
- OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
- StartLoc, EndLoc, CollapsedNum, NumClauses)
- {}
-
- /// \brief Build an empty directive.
- ///
- /// \param CollapsedNum Number of collapsed nested loops.
- /// \param NumClauses Number of clauses.
- ///
- explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
- : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
- SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses)
- {}
-
-public:
- /// \brief 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 OMPDistributeDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
-
- /// \brief 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 OMPDistributeDirective *CreateEmpty(const ASTContext &C,
- unsigned NumClauses,
- unsigned CollapsedNum, EmptyShell);
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == OMPDistributeDirectiveClass;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
deleted file mode 100644
index df4a2d8..0000000
--- a/include/clang/AST/StmtVisitor.h
+++ /dev/null
@@ -1,227 +0,0 @@
-//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the StmtVisitor and ConstStmtVisitor interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_STMTVISITOR_H
-#define LLVM_CLANG_AST_STMTVISITOR_H
-
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExprOpenMP.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
-#include "clang/AST/StmtOpenMP.h"
-
-namespace clang {
-
-template <typename T> struct make_ptr { typedef T *type; };
-template <typename T> struct make_const_ptr { typedef const T *type; };
-
-/// StmtVisitorBase - This class implements a simple visitor for Stmt
-/// subclasses. Since Expr derives from Stmt, this also includes support for
-/// visiting Exprs.
-template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
-class StmtVisitorBase {
-public:
-
-#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S))
-
- RetTy Visit(PTR(Stmt) S) {
-
- // If we have a binary expr, dispatch to the subcode of the binop. A smart
- // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
- // below.
- if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) {
- switch (BinOp->getOpcode()) {
- case BO_PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator);
- case BO_PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator);
- case BO_Mul: DISPATCH(BinMul, BinaryOperator);
- case BO_Div: DISPATCH(BinDiv, BinaryOperator);
- case BO_Rem: DISPATCH(BinRem, BinaryOperator);
- case BO_Add: DISPATCH(BinAdd, BinaryOperator);
- case BO_Sub: DISPATCH(BinSub, BinaryOperator);
- case BO_Shl: DISPATCH(BinShl, BinaryOperator);
- case BO_Shr: DISPATCH(BinShr, BinaryOperator);
-
- case BO_LT: DISPATCH(BinLT, BinaryOperator);
- case BO_GT: DISPATCH(BinGT, BinaryOperator);
- case BO_LE: DISPATCH(BinLE, BinaryOperator);
- case BO_GE: DISPATCH(BinGE, BinaryOperator);
- case BO_EQ: DISPATCH(BinEQ, BinaryOperator);
- case BO_NE: DISPATCH(BinNE, BinaryOperator);
-
- case BO_And: DISPATCH(BinAnd, BinaryOperator);
- case BO_Xor: DISPATCH(BinXor, BinaryOperator);
- case BO_Or : DISPATCH(BinOr, BinaryOperator);
- case BO_LAnd: DISPATCH(BinLAnd, BinaryOperator);
- case BO_LOr : DISPATCH(BinLOr, BinaryOperator);
- case BO_Assign: DISPATCH(BinAssign, BinaryOperator);
- case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator);
- case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator);
- case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator);
- case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator);
- case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator);
- case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator);
- case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator);
- case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator);
- case BO_OrAssign: DISPATCH(BinOrAssign, CompoundAssignOperator);
- case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator);
- case BO_Comma: DISPATCH(BinComma, BinaryOperator);
- }
- } else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) {
- switch (UnOp->getOpcode()) {
- case UO_PostInc: DISPATCH(UnaryPostInc, UnaryOperator);
- case UO_PostDec: DISPATCH(UnaryPostDec, UnaryOperator);
- case UO_PreInc: DISPATCH(UnaryPreInc, UnaryOperator);
- case UO_PreDec: DISPATCH(UnaryPreDec, UnaryOperator);
- case UO_AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator);
- case UO_Deref: DISPATCH(UnaryDeref, UnaryOperator);
- case UO_Plus: DISPATCH(UnaryPlus, UnaryOperator);
- case UO_Minus: DISPATCH(UnaryMinus, UnaryOperator);
- case UO_Not: DISPATCH(UnaryNot, UnaryOperator);
- case UO_LNot: DISPATCH(UnaryLNot, UnaryOperator);
- case UO_Real: DISPATCH(UnaryReal, UnaryOperator);
- case UO_Imag: DISPATCH(UnaryImag, UnaryOperator);
- case UO_Extension: DISPATCH(UnaryExtension, UnaryOperator);
- case UO_Coawait: DISPATCH(UnaryCoawait, UnaryOperator);
- }
- }
-
- // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
- switch (S->getStmtClass()) {
- default: llvm_unreachable("Unknown stmt kind!");
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
-#include "clang/AST/StmtNodes.inc"
- }
- }
-
- // If the implementation chooses not to implement a certain visit method, fall
- // back on VisitExpr or whatever else is the superclass.
-#define STMT(CLASS, PARENT) \
- RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); }
-#include "clang/AST/StmtNodes.inc"
-
- // If the implementation doesn't implement binary operator methods, fall back
- // on VisitBinaryOperator.
-#define BINOP_FALLBACK(NAME) \
- RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \
- DISPATCH(BinaryOperator, BinaryOperator); \
- }
- BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
- BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem)
- BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl)
- BINOP_FALLBACK(Shr)
-
- BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
- BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
- BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
- BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
-
- BINOP_FALLBACK(Assign)
- BINOP_FALLBACK(Comma)
-#undef BINOP_FALLBACK
-
- // If the implementation doesn't implement compound assignment operator
- // methods, fall back on VisitCompoundAssignOperator.
-#define CAO_FALLBACK(NAME) \
- RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \
- DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
- }
- CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
- CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
- CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
- CAO_FALLBACK(XorAssign)
-#undef CAO_FALLBACK
-
- // If the implementation doesn't implement unary operator methods, fall back
- // on VisitUnaryOperator.
-#define UNARYOP_FALLBACK(NAME) \
- RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \
- DISPATCH(UnaryOperator, UnaryOperator); \
- }
- UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
- UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec)
- UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref)
-
- UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus)
- UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot)
- UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag)
- UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(Coawait)
-#undef UNARYOP_FALLBACK
-
- // Base case, ignore it. :)
- RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); }
-
-#undef PTR
-#undef DISPATCH
-};
-
-/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
-/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
-///
-/// This class does not preserve constness of Stmt pointers (see also
-/// ConstStmtVisitor).
-template<typename ImplClass, typename RetTy=void>
-class StmtVisitor
- : public StmtVisitorBase<make_ptr, ImplClass, RetTy> {};
-
-/// ConstStmtVisitor - This class implements a simple visitor for Stmt
-/// subclasses. Since Expr derives from Stmt, this also includes support for
-/// visiting Exprs.
-///
-/// This class preserves constness of Stmt pointers (see also StmtVisitor).
-template<typename ImplClass, typename RetTy=void>
-class ConstStmtVisitor
- : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {};
-
-/// \brief This class implements a simple visitor for OMPClause
-/// subclasses.
-template<class ImplClass, template <typename> class Ptr, typename RetTy>
-class OMPClauseVisitorBase {
-public:
-#define PTR(CLASS) typename Ptr<CLASS>::type
-#define DISPATCH(CLASS) \
- return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
-
-#define OPENMP_CLAUSE(Name, Class) \
- RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
-#include "clang/Basic/OpenMPKinds.def"
-
- RetTy Visit(PTR(OMPClause) S) {
- // Top switch clause: visit each OMPClause.
- switch (S->getClauseKind()) {
- default: llvm_unreachable("Unknown clause kind!");
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S));
-#include "clang/Basic/OpenMPKinds.def"
- }
- }
- // Base case, ignore it. :)
- RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); }
-#undef PTR
-#undef DISPATCH
-};
-
-template<class ImplClass, typename RetTy = void>
-class OMPClauseVisitor :
- public OMPClauseVisitorBase <ImplClass, make_ptr, RetTy> {};
-template<class ImplClass, typename RetTy = void>
-class ConstOMPClauseVisitor :
- public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
deleted file mode 100644
index f87171a..0000000
--- a/include/clang/AST/TemplateBase.h
+++ /dev/null
@@ -1,661 +0,0 @@
-//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides definitions which are common for all kinds of
-// template representation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
-#define LLVM_CLANG_AST_TEMPLATEBASE_H
-
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/TrailingObjects.h"
-
-namespace llvm {
- class FoldingSetNodeID;
-}
-
-namespace clang {
-
-class DiagnosticBuilder;
-class Expr;
-struct PrintingPolicy;
-class TypeSourceInfo;
-class ValueDecl;
-
-/// \brief Represents a template argument.
-class TemplateArgument {
-public:
- /// \brief The kind of template argument we're storing.
- enum ArgKind {
- /// \brief Represents an empty template argument, e.g., one that has not
- /// been deduced.
- Null = 0,
- /// The template argument is a type.
- Type,
- /// The template argument is a declaration that was provided for a pointer,
- /// reference, or pointer to member non-type template parameter.
- Declaration,
- /// The template argument is a null pointer or null pointer to member that
- /// was provided for a non-type template parameter.
- NullPtr,
- /// The template argument is an integral value stored in an llvm::APSInt
- /// that was provided for an integral non-type template parameter.
- Integral,
- /// The template argument is a template name that was provided for a
- /// template template parameter.
- Template,
- /// The template argument is a pack expansion of a template name that was
- /// provided for a template template parameter.
- TemplateExpansion,
- /// The template argument is an expression, and we've not resolved it to one
- /// of the other forms yet, either because it's dependent or because we're
- /// representing a non-canonical template argument (for instance, in a
- /// TemplateSpecializationType). Also used to represent a non-dependent
- /// __uuidof expression (a Microsoft extension).
- Expression,
- /// The template argument is actually a parameter pack. Arguments are stored
- /// in the Args struct.
- Pack
- };
-
-private:
- /// \brief The kind of template argument we're storing.
-
- struct DA {
- unsigned Kind;
- void *QT;
- ValueDecl *D;
- };
- struct I {
- unsigned Kind;
- // We store a decomposed APSInt with the data allocated by ASTContext if
- // BitWidth > 64. The memory may be shared between multiple
- // TemplateArgument instances.
- unsigned BitWidth : 31;
- unsigned IsUnsigned : 1;
- union {
- uint64_t VAL; ///< Used to store the <= 64 bits integer value.
- const uint64_t *pVal; ///< Used to store the >64 bits integer value.
- };
- void *Type;
- };
- struct A {
- unsigned Kind;
- unsigned NumArgs;
- const TemplateArgument *Args;
- };
- struct TA {
- unsigned Kind;
- unsigned NumExpansions;
- void *Name;
- };
- struct TV {
- unsigned Kind;
- uintptr_t V;
- };
- union {
- struct DA DeclArg;
- struct I Integer;
- struct A Args;
- struct TA TemplateArg;
- struct TV TypeOrValue;
- };
-
- TemplateArgument(TemplateName, bool) = delete;
-
-public:
- /// \brief Construct an empty, invalid template argument.
- TemplateArgument() {
- TypeOrValue.Kind = Null;
- TypeOrValue.V = 0;
- }
-
- /// \brief Construct a template type argument.
- TemplateArgument(QualType T, bool isNullPtr = false) {
- TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
- TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
- }
-
- /// \brief Construct a template argument that refers to a
- /// declaration, which is either an external declaration or a
- /// template declaration.
- TemplateArgument(ValueDecl *D, QualType QT) {
- assert(D && "Expected decl");
- DeclArg.Kind = Declaration;
- DeclArg.QT = QT.getAsOpaquePtr();
- DeclArg.D = D;
- }
-
- /// \brief Construct an integral constant template argument. The memory to
- /// store the value is allocated with Ctx.
- TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
-
- /// \brief Construct an integral constant template argument with the same
- /// value as Other but a different type.
- TemplateArgument(const TemplateArgument &Other, QualType Type) {
- Integer = Other.Integer;
- Integer.Type = Type.getAsOpaquePtr();
- }
-
- /// \brief Construct a template argument that is a template.
- ///
- /// This form of template argument is generally used for template template
- /// parameters. However, the template name could be a dependent template
- /// name that ends up being instantiated to a function template whose address
- /// is taken.
- ///
- /// \param Name The template name.
- TemplateArgument(TemplateName Name) {
- TemplateArg.Kind = Template;
- TemplateArg.Name = Name.getAsVoidPointer();
- TemplateArg.NumExpansions = 0;
- }
-
- /// \brief Construct a template argument that is a template pack expansion.
- ///
- /// This form of template argument is generally used for template template
- /// parameters. However, the template name could be a dependent template
- /// name that ends up being instantiated to a function template whose address
- /// is taken.
- ///
- /// \param Name The template name.
- ///
- /// \param NumExpansions The number of expansions that will be generated by
- /// instantiating
- TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
- TemplateArg.Kind = TemplateExpansion;
- TemplateArg.Name = Name.getAsVoidPointer();
- if (NumExpansions)
- TemplateArg.NumExpansions = *NumExpansions + 1;
- else
- TemplateArg.NumExpansions = 0;
- }
-
- /// \brief Construct a template argument that is an expression.
- ///
- /// This form of template argument only occurs in template argument
- /// lists used for dependent types and for expression; it will not
- /// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E) {
- TypeOrValue.Kind = Expression;
- TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
- }
-
- /// \brief Construct a template argument that is a template argument pack.
- ///
- /// We assume that storage for the template arguments provided
- /// outlives the TemplateArgument itself.
- explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
- this->Args.Kind = Pack;
- this->Args.Args = Args.data();
- this->Args.NumArgs = Args.size();
- }
-
- static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
-
- /// \brief Create a new template argument pack by copying the given set of
- /// template arguments.
- static TemplateArgument CreatePackCopy(ASTContext &Context,
- ArrayRef<TemplateArgument> Args);
-
- /// \brief Return the kind of stored template argument.
- ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
-
- /// \brief Determine whether this template argument has no value.
- bool isNull() const { return getKind() == Null; }
-
- /// \brief Whether this template argument is dependent on a template
- /// parameter such that its result can change from one instantiation to
- /// another.
- bool isDependent() const;
-
- /// \brief Whether this template argument is dependent on a template
- /// parameter.
- bool isInstantiationDependent() const;
-
- /// \brief Whether this template argument contains an unexpanded
- /// parameter pack.
- bool containsUnexpandedParameterPack() const;
-
- /// \brief Determine whether this template argument is a pack expansion.
- bool isPackExpansion() const;
-
- /// \brief Retrieve the type for a type template argument.
- QualType getAsType() const {
- assert(getKind() == Type && "Unexpected kind");
- return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
- }
-
- /// \brief Retrieve the declaration for a declaration non-type
- /// template argument.
- ValueDecl *getAsDecl() const {
- assert(getKind() == Declaration && "Unexpected kind");
- return DeclArg.D;
- }
-
- QualType getParamTypeForDecl() const {
- assert(getKind() == Declaration && "Unexpected kind");
- return QualType::getFromOpaquePtr(DeclArg.QT);
- }
-
- /// \brief Retrieve the type for null non-type template argument.
- QualType getNullPtrType() const {
- assert(getKind() == NullPtr && "Unexpected kind");
- return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
- }
-
- /// \brief Retrieve the template name for a template name argument.
- TemplateName getAsTemplate() const {
- assert(getKind() == Template && "Unexpected kind");
- return TemplateName::getFromVoidPointer(TemplateArg.Name);
- }
-
- /// \brief Retrieve the template argument as a template name; if the argument
- /// is a pack expansion, return the pattern as a template name.
- TemplateName getAsTemplateOrTemplatePattern() const {
- assert((getKind() == Template || getKind() == TemplateExpansion) &&
- "Unexpected kind");
-
- return TemplateName::getFromVoidPointer(TemplateArg.Name);
- }
-
- /// \brief Retrieve the number of expansions that a template template argument
- /// expansion will produce, if known.
- Optional<unsigned> getNumTemplateExpansions() const;
-
- /// \brief Retrieve the template argument as an integral value.
- // FIXME: Provide a way to read the integral data without copying the value.
- llvm::APSInt getAsIntegral() const {
- assert(getKind() == Integral && "Unexpected kind");
- using namespace llvm;
- if (Integer.BitWidth <= 64)
- return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
-
- unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
- return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
- Integer.IsUnsigned);
- }
-
- /// \brief Retrieve the type of the integral value.
- QualType getIntegralType() const {
- assert(getKind() == Integral && "Unexpected kind");
- return QualType::getFromOpaquePtr(Integer.Type);
- }
-
- void setIntegralType(QualType T) {
- assert(getKind() == Integral && "Unexpected kind");
- Integer.Type = T.getAsOpaquePtr();
- }
-
- /// \brief Retrieve the template argument as an expression.
- Expr *getAsExpr() const {
- assert(getKind() == Expression && "Unexpected kind");
- return reinterpret_cast<Expr *>(TypeOrValue.V);
- }
-
- /// \brief Iterator that traverses the elements of a template argument pack.
- typedef const TemplateArgument * pack_iterator;
-
- /// \brief Iterator referencing the first argument of a template argument
- /// pack.
- pack_iterator pack_begin() const {
- assert(getKind() == Pack);
- return Args.Args;
- }
-
- /// \brief Iterator referencing one past the last argument of a template
- /// argument pack.
- pack_iterator pack_end() const {
- assert(getKind() == Pack);
- return Args.Args + Args.NumArgs;
- }
-
- /// \brief Iterator range referencing all of the elements of a template
- /// argument pack.
- llvm::iterator_range<pack_iterator> pack_elements() const {
- return llvm::make_range(pack_begin(), pack_end());
- }
-
- /// \brief The number of template arguments in the given template argument
- /// pack.
- unsigned pack_size() const {
- assert(getKind() == Pack);
- return Args.NumArgs;
- }
-
- /// \brief Return the array of arguments in this template argument pack.
- ArrayRef<TemplateArgument> getPackAsArray() const {
- assert(getKind() == Pack);
- return llvm::makeArrayRef(Args.Args, Args.NumArgs);
- }
-
- /// \brief Determines whether two template arguments are superficially the
- /// same.
- bool structurallyEquals(const TemplateArgument &Other) const;
-
- /// \brief When the template argument is a pack expansion, returns
- /// the pattern of the pack expansion.
- TemplateArgument getPackExpansionPattern() const;
-
- /// \brief Print this template argument to the given output stream.
- void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
-
- /// \brief Used to insert TemplateArguments into FoldingSets.
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
-};
-
-/// Location information for a TemplateArgument.
-struct TemplateArgumentLocInfo {
-private:
-
- struct T {
- // FIXME: We'd like to just use the qualifier in the TemplateName,
- // but template arguments get canonicalized too quickly.
- NestedNameSpecifier *Qualifier;
- void *QualifierLocData;
- unsigned TemplateNameLoc;
- unsigned EllipsisLoc;
- };
-
- union {
- struct T Template;
- Expr *Expression;
- TypeSourceInfo *Declarator;
- };
-
-public:
- TemplateArgumentLocInfo();
-
- TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
-
- TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
-
- TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateNameLoc,
- SourceLocation EllipsisLoc)
- {
- Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
- Template.QualifierLocData = QualifierLoc.getOpaqueData();
- Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
- Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
- }
-
- TypeSourceInfo *getAsTypeSourceInfo() const {
- return Declarator;
- }
-
- Expr *getAsExpr() const {
- return Expression;
- }
-
- NestedNameSpecifierLoc getTemplateQualifierLoc() const {
- return NestedNameSpecifierLoc(Template.Qualifier,
- Template.QualifierLocData);
- }
-
- SourceLocation getTemplateNameLoc() const {
- return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
- }
-
- SourceLocation getTemplateEllipsisLoc() const {
- return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
- }
-};
-
-/// Location wrapper for a TemplateArgument. TemplateArgument is to
-/// TemplateArgumentLoc as Type is to TypeLoc.
-class TemplateArgumentLoc {
- TemplateArgument Argument;
- TemplateArgumentLocInfo LocInfo;
-
-public:
- TemplateArgumentLoc() {}
-
- TemplateArgumentLoc(const TemplateArgument &Argument,
- TemplateArgumentLocInfo Opaque)
- : Argument(Argument), LocInfo(Opaque) {
- }
-
- TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
- : Argument(Argument), LocInfo(TInfo) {
- assert(Argument.getKind() == TemplateArgument::Type);
- }
-
- TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
- : Argument(Argument), LocInfo(E) {
- assert(Argument.getKind() == TemplateArgument::Expression);
- }
-
- TemplateArgumentLoc(const TemplateArgument &Argument,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateNameLoc,
- SourceLocation EllipsisLoc = SourceLocation())
- : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
- }
-
- /// \brief - Fetches the primary location of the argument.
- SourceLocation getLocation() const {
- if (Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion)
- return getTemplateNameLoc();
-
- return getSourceRange().getBegin();
- }
-
- /// \brief - Fetches the full source range of the argument.
- SourceRange getSourceRange() const LLVM_READONLY;
-
- const TemplateArgument &getArgument() const {
- return Argument;
- }
-
- TemplateArgumentLocInfo getLocInfo() const {
- return LocInfo;
- }
-
- TypeSourceInfo *getTypeSourceInfo() const {
- assert(Argument.getKind() == TemplateArgument::Type);
- return LocInfo.getAsTypeSourceInfo();
- }
-
- Expr *getSourceExpression() const {
- assert(Argument.getKind() == TemplateArgument::Expression);
- return LocInfo.getAsExpr();
- }
-
- Expr *getSourceDeclExpression() const {
- assert(Argument.getKind() == TemplateArgument::Declaration);
- return LocInfo.getAsExpr();
- }
-
- Expr *getSourceNullPtrExpression() const {
- assert(Argument.getKind() == TemplateArgument::NullPtr);
- return LocInfo.getAsExpr();
- }
-
- Expr *getSourceIntegralExpression() const {
- assert(Argument.getKind() == TemplateArgument::Integral);
- return LocInfo.getAsExpr();
- }
-
- NestedNameSpecifierLoc getTemplateQualifierLoc() const {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
- return LocInfo.getTemplateQualifierLoc();
- }
-
- SourceLocation getTemplateNameLoc() const {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
- return LocInfo.getTemplateNameLoc();
- }
-
- SourceLocation getTemplateEllipsisLoc() const {
- assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
- return LocInfo.getTemplateEllipsisLoc();
- }
-};
-
-/// A convenient class for passing around template argument
-/// information. Designed to be passed by reference.
-class TemplateArgumentListInfo {
- SmallVector<TemplateArgumentLoc, 8> Arguments;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
-
- // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
- // instead.
- void *operator new(size_t bytes, ASTContext &C) = delete;
-
-public:
- TemplateArgumentListInfo() {}
-
- TemplateArgumentListInfo(SourceLocation LAngleLoc,
- SourceLocation RAngleLoc)
- : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
-
- SourceLocation getLAngleLoc() const { return LAngleLoc; }
- SourceLocation getRAngleLoc() const { return RAngleLoc; }
-
- void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
- void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
-
- unsigned size() const { return Arguments.size(); }
-
- const TemplateArgumentLoc *getArgumentArray() const {
- return Arguments.data();
- }
-
- llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
- return Arguments;
- }
-
- const TemplateArgumentLoc &operator[](unsigned I) const {
- return Arguments[I];
- }
-
- TemplateArgumentLoc &operator[](unsigned I) {
- return Arguments[I];
- }
-
- void addArgument(const TemplateArgumentLoc &Loc) {
- Arguments.push_back(Loc);
- }
-};
-
-/// \brief Represents an explicit template argument list in C++, e.g.,
-/// the "<int>" in "sort<int>".
-/// This is safe to be used inside an AST node, in contrast with
-/// TemplateArgumentListInfo.
-struct ASTTemplateArgumentListInfo final
- : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
- TemplateArgumentLoc> {
-private:
- friend TrailingObjects;
-
- ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
-
-public:
- /// \brief The source location of the left angle bracket ('<').
- SourceLocation LAngleLoc;
-
- /// \brief The source location of the right angle bracket ('>').
- SourceLocation RAngleLoc;
-
- /// \brief The number of template arguments in TemplateArgs.
- unsigned NumTemplateArgs;
-
- /// \brief Retrieve the template arguments
- const TemplateArgumentLoc *getTemplateArgs() const {
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- const TemplateArgumentLoc &operator[](unsigned I) const {
- return getTemplateArgs()[I];
- }
-
- static const ASTTemplateArgumentListInfo *
- Create(ASTContext &C, const TemplateArgumentListInfo &List);
-};
-
-/// \brief Represents an explicit template argument list in C++, e.g.,
-/// the "<int>" in "sort<int>".
-///
-/// It is intended to be used as a trailing object on AST nodes, and
-/// as such, doesn't contain the array of TemplateArgumentLoc itself,
-/// but expects the containing object to also provide storage for
-/// that.
-struct LLVM_ALIGNAS(LLVM_PTR_SIZE) ASTTemplateKWAndArgsInfo {
- /// \brief The source location of the left angle bracket ('<').
- SourceLocation LAngleLoc;
-
- /// \brief The source location of the right angle bracket ('>').
- SourceLocation RAngleLoc;
-
- /// \brief The source location of the template keyword; this is used
- /// as part of the representation of qualified identifiers, such as
- /// S<T>::template apply<T>. Will be empty if this expression does
- /// not have a template keyword.
- SourceLocation TemplateKWLoc;
-
- /// \brief The number of template arguments in TemplateArgs.
- unsigned NumTemplateArgs;
-
- void initializeFrom(SourceLocation TemplateKWLoc,
- const TemplateArgumentListInfo &List,
- TemplateArgumentLoc *OutArgArray);
- void initializeFrom(SourceLocation TemplateKWLoc,
- const TemplateArgumentListInfo &List,
- TemplateArgumentLoc *OutArgArray, bool &Dependent,
- bool &InstantiationDependent,
- bool &ContainsUnexpandedParameterPack);
- void initializeFrom(SourceLocation TemplateKWLoc);
-
- void copyInto(const TemplateArgumentLoc *ArgArray,
- TemplateArgumentListInfo &List) const;
-};
-
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const TemplateArgument &Arg);
-
-inline TemplateSpecializationType::iterator
- TemplateSpecializationType::end() const {
- return getArgs() + getNumArgs();
-}
-
-inline DependentTemplateSpecializationType::iterator
- DependentTemplateSpecializationType::end() const {
- return getArgs() + getNumArgs();
-}
-
-inline const TemplateArgument &
- TemplateSpecializationType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
-inline const TemplateArgument &
- DependentTemplateSpecializationType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
deleted file mode 100644
index 3e10d2f..0000000
--- a/include/clang/AST/TemplateName.h
+++ /dev/null
@@ -1,533 +0,0 @@
-//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TemplateName interface and subclasses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
-#define LLVM_CLANG_AST_TEMPLATENAME_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/PointerUnion.h"
-
-namespace clang {
-
-class ASTContext;
-class DependentTemplateName;
-class DiagnosticBuilder;
-class IdentifierInfo;
-class NamedDecl;
-class NestedNameSpecifier;
-enum OverloadedOperatorKind : int;
-class OverloadedTemplateStorage;
-struct PrintingPolicy;
-class QualifiedTemplateName;
-class SubstTemplateTemplateParmPackStorage;
-class SubstTemplateTemplateParmStorage;
-class TemplateArgument;
-class TemplateDecl;
-class TemplateTemplateParmDecl;
-
-/// \brief Implementation class used to describe either a set of overloaded
-/// template names or an already-substituted template template parameter pack.
-class UncommonTemplateNameStorage {
-protected:
- enum Kind {
- Overloaded,
- SubstTemplateTemplateParm,
- SubstTemplateTemplateParmPack
- };
-
- struct BitsTag {
- /// \brief A Kind.
- unsigned Kind : 2;
-
- /// \brief The number of stored templates or template arguments,
- /// depending on which subclass we have.
- unsigned Size : 30;
- };
-
- union {
- struct BitsTag Bits;
- void *PointerAlignment;
- };
-
- UncommonTemplateNameStorage(Kind kind, unsigned size) {
- Bits.Kind = kind;
- Bits.Size = size;
- }
-
-public:
- unsigned size() const { return Bits.Size; }
-
- OverloadedTemplateStorage *getAsOverloadedStorage() {
- return Bits.Kind == Overloaded
- ? reinterpret_cast<OverloadedTemplateStorage *>(this)
- : nullptr;
- }
-
- SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
- return Bits.Kind == SubstTemplateTemplateParm
- ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
- : nullptr;
- }
-
- SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
- return Bits.Kind == SubstTemplateTemplateParmPack
- ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
- : nullptr;
- }
-};
-
-/// \brief A structure for storing the information associated with an
-/// overloaded template name.
-class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
- friend class ASTContext;
-
- OverloadedTemplateStorage(unsigned size)
- : UncommonTemplateNameStorage(Overloaded, size) { }
-
- NamedDecl **getStorage() {
- return reinterpret_cast<NamedDecl **>(this + 1);
- }
- NamedDecl * const *getStorage() const {
- return reinterpret_cast<NamedDecl *const *>(this + 1);
- }
-
-public:
- typedef NamedDecl *const *iterator;
-
- iterator begin() const { return getStorage(); }
- iterator end() const { return getStorage() + size(); }
-};
-
-/// \brief A structure for storing an already-substituted template template
-/// parameter pack.
-///
-/// This kind of template names occurs when the parameter pack has been
-/// provided with a template template argument pack in a context where its
-/// enclosing pack expansion could not be fully expanded.
-class SubstTemplateTemplateParmPackStorage
- : public UncommonTemplateNameStorage, public llvm::FoldingSetNode
-{
- TemplateTemplateParmDecl *Parameter;
- const TemplateArgument *Arguments;
-
-public:
- SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
- unsigned Size,
- const TemplateArgument *Arguments)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
- Parameter(Parameter), Arguments(Arguments) { }
-
- /// \brief Retrieve the template template parameter pack being substituted.
- TemplateTemplateParmDecl *getParameterPack() const {
- return Parameter;
- }
-
- /// \brief Retrieve the template template argument pack with which this
- /// parameter was substituted.
- TemplateArgument getArgumentPack() const;
-
- void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- ASTContext &Context,
- TemplateTemplateParmDecl *Parameter,
- const TemplateArgument &ArgPack);
-};
-
-/// \brief Represents a C++ template name within the type system.
-///
-/// A C++ template name refers to a template within the C++ type
-/// system. In most cases, a template name is simply a reference to a
-/// class template, e.g.
-///
-/// \code
-/// template<typename T> class X { };
-///
-/// X<int> xi;
-/// \endcode
-///
-/// Here, the 'X' in \c X<int> is a template name that refers to the
-/// declaration of the class template X, above. Template names can
-/// also refer to function templates, C++0x template aliases, etc.
-///
-/// Some template names are dependent. For example, consider:
-///
-/// \code
-/// template<typename MetaFun, typename T1, typename T2> struct apply2 {
-/// typedef typename MetaFun::template apply<T1, T2>::type type;
-/// };
-/// \endcode
-///
-/// Here, "apply" is treated as a template name within the typename
-/// specifier in the typedef. "apply" is a nested template, and can
-/// only be understood in the context of
-class TemplateName {
- typedef llvm::PointerUnion4<TemplateDecl *,
- UncommonTemplateNameStorage *,
- QualifiedTemplateName *,
- DependentTemplateName *> StorageType;
-
- StorageType Storage;
-
- explicit TemplateName(void *Ptr);
-
-public:
- // \brief Kind of name that is actually stored.
- enum NameKind {
- /// \brief A single template declaration.
- Template,
- /// \brief A set of overloaded template declarations.
- OverloadedTemplate,
- /// \brief A qualified template name, where the qualification is kept
- /// to describe the source code as written.
- QualifiedTemplate,
- /// \brief A dependent template name that has not been resolved to a
- /// template (or set of templates).
- DependentTemplate,
- /// \brief A template template parameter that has been substituted
- /// for some other template name.
- SubstTemplateTemplateParm,
- /// \brief A template template parameter pack that has been substituted for
- /// a template template argument pack, but has not yet been expanded into
- /// individual arguments.
- SubstTemplateTemplateParmPack
- };
-
- TemplateName() : Storage() { }
- explicit TemplateName(TemplateDecl *Template);
- explicit TemplateName(OverloadedTemplateStorage *Storage);
- explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
- explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage);
- explicit TemplateName(QualifiedTemplateName *Qual);
- explicit TemplateName(DependentTemplateName *Dep);
-
- /// \brief Determine whether this template name is NULL.
- bool isNull() const;
-
- // \brief Get the kind of name that is actually stored.
- NameKind getKind() const;
-
- /// \brief Retrieve the underlying template declaration that
- /// this template name refers to, if known.
- ///
- /// \returns The template declaration that this template name refers
- /// to, if any. If the template name does not refer to a specific
- /// declaration because it is a dependent name, or if it refers to a
- /// set of function templates, returns NULL.
- TemplateDecl *getAsTemplateDecl() const;
-
- /// \brief Retrieve the underlying, overloaded function template
- // declarations that this template name refers to, if known.
- ///
- /// \returns The set of overloaded function templates that this template
- /// name refers to, if known. If the template name does not refer to a
- /// specific set of function templates because it is a dependent name or
- /// refers to a single template, returns NULL.
- OverloadedTemplateStorage *getAsOverloadedTemplate() const;
-
- /// \brief Retrieve the substituted template template parameter, if
- /// known.
- ///
- /// \returns The storage for the substituted template template parameter,
- /// if known. Otherwise, returns NULL.
- SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const;
-
- /// \brief Retrieve the substituted template template parameter pack, if
- /// known.
- ///
- /// \returns The storage for the substituted template template parameter pack,
- /// if known. Otherwise, returns NULL.
- SubstTemplateTemplateParmPackStorage *
- getAsSubstTemplateTemplateParmPack() const;
-
- /// \brief Retrieve the underlying qualified template name
- /// structure, if any.
- QualifiedTemplateName *getAsQualifiedTemplateName() const;
-
- /// \brief Retrieve the underlying dependent template name
- /// structure, if any.
- DependentTemplateName *getAsDependentTemplateName() const;
-
- TemplateName getUnderlying() const;
-
- /// \brief Determines whether this is a dependent template name.
- bool isDependent() const;
-
- /// \brief Determines whether this is a template name that somehow
- /// depends on a template parameter.
- bool isInstantiationDependent() const;
-
- /// \brief Determines whether this template name contains an
- /// unexpanded parameter pack (for C++0x variadic templates).
- bool containsUnexpandedParameterPack() const;
-
- /// \brief Print the template name.
- ///
- /// \param OS the output stream to which the template name will be
- /// printed.
- ///
- /// \param SuppressNNS if true, don't print the
- /// nested-name-specifier that precedes the template name (if it has
- /// one).
- void print(raw_ostream &OS, const PrintingPolicy &Policy,
- bool SuppressNNS = false) const;
-
- /// \brief Debugging aid that dumps the template name.
- void dump(raw_ostream &OS) const;
-
- /// \brief Debugging aid that dumps the template name to standard
- /// error.
- void dump() const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- ID.AddPointer(Storage.getOpaqueValue());
- }
-
- /// \brief Retrieve the template name as a void pointer.
- void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
-
- /// \brief Build a template name from a void pointer.
- static TemplateName getFromVoidPointer(void *Ptr) {
- return TemplateName(Ptr);
- }
-};
-
-/// Insertion operator for diagnostics. This allows sending TemplateName's
-/// into a diagnostic with <<.
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- TemplateName N);
-
-/// \brief A structure for storing the information associated with a
-/// substituted template template parameter.
-class SubstTemplateTemplateParmStorage
- : public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
- friend class ASTContext;
-
- TemplateTemplateParmDecl *Parameter;
- TemplateName Replacement;
-
- SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
- TemplateName replacement)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
- Parameter(parameter), Replacement(replacement) {}
-
-public:
- TemplateTemplateParmDecl *getParameter() const { return Parameter; }
- TemplateName getReplacement() const { return Replacement; }
-
- void Profile(llvm::FoldingSetNodeID &ID);
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- TemplateTemplateParmDecl *parameter,
- TemplateName replacement);
-};
-
-inline TemplateName TemplateName::getUnderlying() const {
- if (SubstTemplateTemplateParmStorage *subst
- = getAsSubstTemplateTemplateParm())
- return subst->getReplacement().getUnderlying();
- return *this;
-}
-
-/// \brief Represents a template name that was expressed as a
-/// qualified name.
-///
-/// This kind of template name refers to a template name that was
-/// preceded by a nested name specifier, e.g., \c std::vector. Here,
-/// the nested name specifier is "std::" and the template name is the
-/// declaration for "vector". The QualifiedTemplateName class is only
-/// used to provide "sugar" for template names that were expressed
-/// with a qualified name, and has no semantic meaning. In this
-/// manner, it is to TemplateName what ElaboratedType is to Type,
-/// providing extra syntactic sugar for downstream clients.
-class QualifiedTemplateName : public llvm::FoldingSetNode {
- /// \brief The nested name specifier that qualifies the template name.
- ///
- /// The bit is used to indicate whether the "template" keyword was
- /// present before the template name itself. Note that the
- /// "template" keyword is always redundant in this case (otherwise,
- /// the template name would be a dependent name and we would express
- /// this name with DependentTemplateName).
- llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
-
- /// \brief The template declaration or set of overloaded function templates
- /// that this qualified name refers to.
- TemplateDecl *Template;
-
- friend class ASTContext;
-
- QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
- TemplateDecl *Template)
- : Qualifier(NNS, TemplateKeyword? 1 : 0),
- Template(Template) { }
-
-public:
- /// \brief Return the nested name specifier that qualifies this name.
- NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
-
- /// \brief Whether the template name was prefixed by the "template"
- /// keyword.
- bool hasTemplateKeyword() const { return Qualifier.getInt(); }
-
- /// \brief The template declaration that this qualified name refers
- /// to.
- TemplateDecl *getDecl() const { return Template; }
-
- /// \brief The template declaration to which this qualified name
- /// refers.
- TemplateDecl *getTemplateDecl() const { return Template; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- bool TemplateKeyword, TemplateDecl *Template) {
- ID.AddPointer(NNS);
- ID.AddBoolean(TemplateKeyword);
- ID.AddPointer(Template);
- }
-};
-
-/// \brief Represents a dependent template name that cannot be
-/// resolved prior to template instantiation.
-///
-/// This kind of template name refers to a dependent template name,
-/// including its nested name specifier (if any). For example,
-/// DependentTemplateName can refer to "MetaFun::template apply",
-/// where "MetaFun::" is the nested name specifier and "apply" is the
-/// template name referenced. The "template" keyword is implied.
-class DependentTemplateName : public llvm::FoldingSetNode {
- /// \brief The nested name specifier that qualifies the template
- /// name.
- ///
- /// The bit stored in this qualifier describes whether the \c Name field
- /// is interpreted as an IdentifierInfo pointer (when clear) or as an
- /// overloaded operator kind (when set).
- llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
-
- /// \brief The dependent template name.
- union {
- /// \brief The identifier template name.
- ///
- /// Only valid when the bit on \c Qualifier is clear.
- const IdentifierInfo *Identifier;
-
- /// \brief The overloaded operator name.
- ///
- /// Only valid when the bit on \c Qualifier is set.
- OverloadedOperatorKind Operator;
- };
-
- /// \brief The canonical template name to which this dependent
- /// template name refers.
- ///
- /// The canonical template name for a dependent template name is
- /// another dependent template name whose nested name specifier is
- /// canonical.
- TemplateName CanonicalTemplateName;
-
- friend class ASTContext;
-
- DependentTemplateName(NestedNameSpecifier *Qualifier,
- const IdentifierInfo *Identifier)
- : Qualifier(Qualifier, false), Identifier(Identifier),
- CanonicalTemplateName(this) { }
-
- DependentTemplateName(NestedNameSpecifier *Qualifier,
- const IdentifierInfo *Identifier,
- TemplateName Canon)
- : Qualifier(Qualifier, false), Identifier(Identifier),
- CanonicalTemplateName(Canon) { }
-
- DependentTemplateName(NestedNameSpecifier *Qualifier,
- OverloadedOperatorKind Operator)
- : Qualifier(Qualifier, true), Operator(Operator),
- CanonicalTemplateName(this) { }
-
- DependentTemplateName(NestedNameSpecifier *Qualifier,
- OverloadedOperatorKind Operator,
- TemplateName Canon)
- : Qualifier(Qualifier, true), Operator(Operator),
- CanonicalTemplateName(Canon) { }
-
-public:
- /// \brief Return the nested name specifier that qualifies this name.
- NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
-
- /// \brief Determine whether this template name refers to an identifier.
- bool isIdentifier() const { return !Qualifier.getInt(); }
-
- /// \brief Returns the identifier to which this template name refers.
- const IdentifierInfo *getIdentifier() const {
- assert(isIdentifier() && "Template name isn't an identifier?");
- return Identifier;
- }
-
- /// \brief Determine whether this template name refers to an overloaded
- /// operator.
- bool isOverloadedOperator() const { return Qualifier.getInt(); }
-
- /// \brief Return the overloaded operator to which this template name refers.
- OverloadedOperatorKind getOperator() const {
- assert(isOverloadedOperator() &&
- "Template name isn't an overloaded operator?");
- return Operator;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- if (isIdentifier())
- Profile(ID, getQualifier(), getIdentifier());
- else
- Profile(ID, getQualifier(), getOperator());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- const IdentifierInfo *Identifier) {
- ID.AddPointer(NNS);
- ID.AddBoolean(false);
- ID.AddPointer(Identifier);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- OverloadedOperatorKind Operator) {
- ID.AddPointer(NNS);
- ID.AddBoolean(true);
- ID.AddInteger(Operator);
- }
-};
-
-} // end namespace clang.
-
-namespace llvm {
-
-/// \brief The clang::TemplateName class is effectively a pointer.
-template<>
-class PointerLikeTypeTraits<clang::TemplateName> {
-public:
- static inline void *getAsVoidPointer(clang::TemplateName TN) {
- return TN.getAsVoidPointer();
- }
-
- static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
- return clang::TemplateName::getFromVoidPointer(Ptr);
- }
-
- // No bits are available!
- enum { NumLowBitsAvailable = 0 };
-};
-
-} // end namespace llvm.
-
-#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
deleted file mode 100644
index 0c08130..0000000
--- a/include/clang/AST/Type.h
+++ /dev/null
@@ -1,5683 +0,0 @@
-//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// \brief C Language Family Type Representation
-///
-/// This file defines the clang::Type interface and subclasses, used to
-/// represent types for languages in the C family.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TYPE_H
-#define LLVM_CLANG_AST_TYPE_H
-
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/ExceptionSpecificationType.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Linkage.h"
-#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/Visibility.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
- enum {
- TypeAlignmentInBits = 4,
- TypeAlignment = 1 << TypeAlignmentInBits
- };
- class Type;
- class ExtQuals;
- class QualType;
-}
-
-namespace llvm {
- template <typename T>
- class PointerLikeTypeTraits;
- template<>
- class PointerLikeTypeTraits< ::clang::Type*> {
- public:
- static inline void *getAsVoidPointer(::clang::Type *P) { return P; }
- static inline ::clang::Type *getFromVoidPointer(void *P) {
- return static_cast< ::clang::Type*>(P);
- }
- enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
- };
- template<>
- class PointerLikeTypeTraits< ::clang::ExtQuals*> {
- public:
- static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; }
- static inline ::clang::ExtQuals *getFromVoidPointer(void *P) {
- return static_cast< ::clang::ExtQuals*>(P);
- }
- enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
- };
-
- template <>
- struct isPodLike<clang::QualType> { static const bool value = true; };
-}
-
-namespace clang {
- class ASTContext;
- class TypedefNameDecl;
- class TemplateDecl;
- class TemplateTypeParmDecl;
- class NonTypeTemplateParmDecl;
- class TemplateTemplateParmDecl;
- class TagDecl;
- class RecordDecl;
- class CXXRecordDecl;
- class EnumDecl;
- class FieldDecl;
- class FunctionDecl;
- class ObjCInterfaceDecl;
- class ObjCProtocolDecl;
- class ObjCMethodDecl;
- class UnresolvedUsingTypenameDecl;
- class Expr;
- class Stmt;
- class SourceLocation;
- class StmtIteratorBase;
- class TemplateArgument;
- class TemplateArgumentLoc;
- class TemplateArgumentListInfo;
- class ElaboratedType;
- class ExtQuals;
- class ExtQualsTypeCommonBase;
- struct PrintingPolicy;
-
- template <typename> class CanQual;
- typedef CanQual<Type> CanQualType;
-
- // Provide forward declarations for all of the *Type classes
-#define TYPE(Class, Base) class Class##Type;
-#include "clang/AST/TypeNodes.def"
-
-/// The collection of all-type qualifiers we support.
-/// Clang supports five independent qualifiers:
-/// * C99: const, volatile, and restrict
-/// * Embedded C (TR18037): address spaces
-/// * Objective C: the GC attributes (none, weak, or strong)
-class Qualifiers {
-public:
- enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
- Const = 0x1,
- Restrict = 0x2,
- Volatile = 0x4,
- CVRMask = Const | Volatile | Restrict
- };
-
- enum GC {
- GCNone = 0,
- Weak,
- Strong
- };
-
- enum ObjCLifetime {
- /// There is no lifetime qualification on this type.
- OCL_None,
-
- /// This object can be modified without requiring retains or
- /// releases.
- OCL_ExplicitNone,
-
- /// Assigning into this object requires the old value to be
- /// released and the new value to be retained. The timing of the
- /// release of the old value is inexact: it may be moved to
- /// immediately after the last known point where the value is
- /// live.
- OCL_Strong,
-
- /// Reading or writing from this object requires a barrier call.
- OCL_Weak,
-
- /// Assigning into this object requires a lifetime extension.
- OCL_Autoreleasing
- };
-
- enum {
- /// The maximum supported address space number.
- /// 24 bits should be enough for anyone.
- MaxAddressSpace = 0xffffffu,
-
- /// The width of the "fast" qualifier mask.
- FastWidth = 3,
-
- /// The fast qualifier mask.
- FastMask = (1 << FastWidth) - 1
- };
-
- Qualifiers() : Mask(0) {}
-
- /// Returns the common set of qualifiers while removing them from
- /// the given sets.
- static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) {
- // If both are only CVR-qualified, bit operations are sufficient.
- if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) {
- Qualifiers Q;
- Q.Mask = L.Mask & R.Mask;
- L.Mask &= ~Q.Mask;
- R.Mask &= ~Q.Mask;
- return Q;
- }
-
- Qualifiers Q;
- unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers();
- Q.addCVRQualifiers(CommonCRV);
- L.removeCVRQualifiers(CommonCRV);
- R.removeCVRQualifiers(CommonCRV);
-
- if (L.getObjCGCAttr() == R.getObjCGCAttr()) {
- Q.setObjCGCAttr(L.getObjCGCAttr());
- L.removeObjCGCAttr();
- R.removeObjCGCAttr();
- }
-
- if (L.getObjCLifetime() == R.getObjCLifetime()) {
- Q.setObjCLifetime(L.getObjCLifetime());
- L.removeObjCLifetime();
- R.removeObjCLifetime();
- }
-
- if (L.getAddressSpace() == R.getAddressSpace()) {
- Q.setAddressSpace(L.getAddressSpace());
- L.removeAddressSpace();
- R.removeAddressSpace();
- }
- return Q;
- }
-
- static Qualifiers fromFastMask(unsigned Mask) {
- Qualifiers Qs;
- Qs.addFastQualifiers(Mask);
- return Qs;
- }
-
- static Qualifiers fromCVRMask(unsigned CVR) {
- Qualifiers Qs;
- Qs.addCVRQualifiers(CVR);
- return Qs;
- }
-
- // Deserialize qualifiers from an opaque representation.
- static Qualifiers fromOpaqueValue(unsigned opaque) {
- Qualifiers Qs;
- Qs.Mask = opaque;
- return Qs;
- }
-
- // Serialize these qualifiers into an opaque representation.
- unsigned getAsOpaqueValue() const {
- return Mask;
- }
-
- bool hasConst() const { return Mask & Const; }
- void setConst(bool flag) {
- Mask = (Mask & ~Const) | (flag ? Const : 0);
- }
- void removeConst() { Mask &= ~Const; }
- void addConst() { Mask |= Const; }
-
- bool hasVolatile() const { return Mask & Volatile; }
- void setVolatile(bool flag) {
- Mask = (Mask & ~Volatile) | (flag ? Volatile : 0);
- }
- void removeVolatile() { Mask &= ~Volatile; }
- void addVolatile() { Mask |= Volatile; }
-
- bool hasRestrict() const { return Mask & Restrict; }
- void setRestrict(bool flag) {
- Mask = (Mask & ~Restrict) | (flag ? Restrict : 0);
- }
- void removeRestrict() { Mask &= ~Restrict; }
- void addRestrict() { Mask |= Restrict; }
-
- bool hasCVRQualifiers() const { return getCVRQualifiers(); }
- unsigned getCVRQualifiers() const { return Mask & CVRMask; }
- void setCVRQualifiers(unsigned mask) {
- assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
- Mask = (Mask & ~CVRMask) | mask;
- }
- void removeCVRQualifiers(unsigned mask) {
- assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
- Mask &= ~mask;
- }
- void removeCVRQualifiers() {
- removeCVRQualifiers(CVRMask);
- }
- void addCVRQualifiers(unsigned mask) {
- assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
- Mask |= mask;
- }
-
- bool hasObjCGCAttr() const { return Mask & GCAttrMask; }
- GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); }
- void setObjCGCAttr(GC type) {
- Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift);
- }
- void removeObjCGCAttr() { setObjCGCAttr(GCNone); }
- void addObjCGCAttr(GC type) {
- assert(type);
- setObjCGCAttr(type);
- }
- Qualifiers withoutObjCGCAttr() const {
- Qualifiers qs = *this;
- qs.removeObjCGCAttr();
- return qs;
- }
- Qualifiers withoutObjCLifetime() const {
- Qualifiers qs = *this;
- qs.removeObjCLifetime();
- return qs;
- }
-
- bool hasObjCLifetime() const { return Mask & LifetimeMask; }
- ObjCLifetime getObjCLifetime() const {
- return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift);
- }
- void setObjCLifetime(ObjCLifetime type) {
- Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift);
- }
- void removeObjCLifetime() { setObjCLifetime(OCL_None); }
- void addObjCLifetime(ObjCLifetime type) {
- assert(type);
- assert(!hasObjCLifetime());
- Mask |= (type << LifetimeShift);
- }
-
- /// True if the lifetime is neither None or ExplicitNone.
- bool hasNonTrivialObjCLifetime() const {
- ObjCLifetime lifetime = getObjCLifetime();
- return (lifetime > OCL_ExplicitNone);
- }
-
- /// True if the lifetime is either strong or weak.
- bool hasStrongOrWeakObjCLifetime() const {
- ObjCLifetime lifetime = getObjCLifetime();
- return (lifetime == OCL_Strong || lifetime == OCL_Weak);
- }
-
- bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
- unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
- void setAddressSpace(unsigned space) {
- assert(space <= MaxAddressSpace);
- Mask = (Mask & ~AddressSpaceMask)
- | (((uint32_t) space) << AddressSpaceShift);
- }
- void removeAddressSpace() { setAddressSpace(0); }
- void addAddressSpace(unsigned space) {
- assert(space);
- setAddressSpace(space);
- }
-
- // Fast qualifiers are those that can be allocated directly
- // on a QualType object.
- bool hasFastQualifiers() const { return getFastQualifiers(); }
- unsigned getFastQualifiers() const { return Mask & FastMask; }
- void setFastQualifiers(unsigned mask) {
- assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
- Mask = (Mask & ~FastMask) | mask;
- }
- void removeFastQualifiers(unsigned mask) {
- assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
- Mask &= ~mask;
- }
- void removeFastQualifiers() {
- removeFastQualifiers(FastMask);
- }
- void addFastQualifiers(unsigned mask) {
- assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
- Mask |= mask;
- }
-
- /// Return true if the set contains any qualifiers which require an ExtQuals
- /// node to be allocated.
- bool hasNonFastQualifiers() const { return Mask & ~FastMask; }
- Qualifiers getNonFastQualifiers() const {
- Qualifiers Quals = *this;
- Quals.setFastQualifiers(0);
- return Quals;
- }
-
- /// Return true if the set contains any qualifiers.
- bool hasQualifiers() const { return Mask; }
- bool empty() const { return !Mask; }
-
- /// Add the qualifiers from the given set to this set.
- void addQualifiers(Qualifiers Q) {
- // If the other set doesn't have any non-boolean qualifiers, just
- // bit-or it in.
- if (!(Q.Mask & ~CVRMask))
- Mask |= Q.Mask;
- else {
- Mask |= (Q.Mask & CVRMask);
- if (Q.hasAddressSpace())
- addAddressSpace(Q.getAddressSpace());
- if (Q.hasObjCGCAttr())
- addObjCGCAttr(Q.getObjCGCAttr());
- if (Q.hasObjCLifetime())
- addObjCLifetime(Q.getObjCLifetime());
- }
- }
-
- /// \brief Remove the qualifiers from the given set from this set.
- void removeQualifiers(Qualifiers Q) {
- // If the other set doesn't have any non-boolean qualifiers, just
- // bit-and the inverse in.
- if (!(Q.Mask & ~CVRMask))
- Mask &= ~Q.Mask;
- else {
- Mask &= ~(Q.Mask & CVRMask);
- if (getObjCGCAttr() == Q.getObjCGCAttr())
- removeObjCGCAttr();
- if (getObjCLifetime() == Q.getObjCLifetime())
- removeObjCLifetime();
- if (getAddressSpace() == Q.getAddressSpace())
- removeAddressSpace();
- }
- }
-
- /// Add the qualifiers from the given set to this set, given that
- /// they don't conflict.
- void addConsistentQualifiers(Qualifiers qs) {
- assert(getAddressSpace() == qs.getAddressSpace() ||
- !hasAddressSpace() || !qs.hasAddressSpace());
- assert(getObjCGCAttr() == qs.getObjCGCAttr() ||
- !hasObjCGCAttr() || !qs.hasObjCGCAttr());
- assert(getObjCLifetime() == qs.getObjCLifetime() ||
- !hasObjCLifetime() || !qs.hasObjCLifetime());
- Mask |= qs.Mask;
- }
-
- /// Returns true if this address space is a superset of the other one.
- /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of
- /// overlapping address spaces.
- /// CL1.1 or CL1.2:
- /// every address space is a superset of itself.
- /// CL2.0 adds:
- /// __generic is a superset of any address space except for __constant.
- bool isAddressSpaceSupersetOf(Qualifiers other) const {
- return
- // Address spaces must match exactly.
- getAddressSpace() == other.getAddressSpace() ||
- // Otherwise in OpenCLC v2.0 s6.5.5: every address space except
- // for __constant can be used as __generic.
- (getAddressSpace() == LangAS::opencl_generic &&
- other.getAddressSpace() != LangAS::opencl_constant);
- }
-
- /// Determines if these qualifiers compatibly include another set.
- /// Generally this answers the question of whether an object with the other
- /// qualifiers can be safely used as an object with these qualifiers.
- bool compatiblyIncludes(Qualifiers other) const {
- return isAddressSpaceSupersetOf(other) &&
- // ObjC GC qualifiers can match, be added, or be removed, but can't
- // be changed.
- (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() ||
- !other.hasObjCGCAttr()) &&
- // ObjC lifetime qualifiers must match exactly.
- getObjCLifetime() == other.getObjCLifetime() &&
- // CVR qualifiers may subset.
- (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
- }
-
- /// \brief Determines if these qualifiers compatibly include another set of
- /// qualifiers from the narrow perspective of Objective-C ARC lifetime.
- ///
- /// One set of Objective-C lifetime qualifiers compatibly includes the other
- /// if the lifetime qualifiers match, or if both are non-__weak and the
- /// including set also contains the 'const' qualifier, or both are non-__weak
- /// and one is None (which can only happen in non-ARC modes).
- bool compatiblyIncludesObjCLifetime(Qualifiers other) const {
- if (getObjCLifetime() == other.getObjCLifetime())
- return true;
-
- if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak)
- return false;
-
- if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None)
- return true;
-
- return hasConst();
- }
-
- /// \brief Determine whether this set of qualifiers is a strict superset of
- /// another set of qualifiers, not considering qualifier compatibility.
- bool isStrictSupersetOf(Qualifiers Other) const;
-
- bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
- bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
-
- explicit operator bool() const { return hasQualifiers(); }
-
- Qualifiers &operator+=(Qualifiers R) {
- addQualifiers(R);
- return *this;
- }
-
- // Union two qualifier sets. If an enumerated qualifier appears
- // in both sets, use the one from the right.
- friend Qualifiers operator+(Qualifiers L, Qualifiers R) {
- L += R;
- return L;
- }
-
- Qualifiers &operator-=(Qualifiers R) {
- removeQualifiers(R);
- return *this;
- }
-
- /// \brief Compute the difference between two qualifier sets.
- friend Qualifiers operator-(Qualifiers L, Qualifiers R) {
- L -= R;
- return L;
- }
-
- std::string getAsString() const;
- std::string getAsString(const PrintingPolicy &Policy) const;
-
- bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const;
- void print(raw_ostream &OS, const PrintingPolicy &Policy,
- bool appendSpaceIfNonEmpty = false) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger(Mask);
- }
-
-private:
-
- // bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31|
- // |C R V|GCAttr|Lifetime|AddressSpace|
- uint32_t Mask;
-
- static const uint32_t GCAttrMask = 0x18;
- static const uint32_t GCAttrShift = 3;
- static const uint32_t LifetimeMask = 0xE0;
- static const uint32_t LifetimeShift = 5;
- static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask);
- static const uint32_t AddressSpaceShift = 8;
-};
-
-/// A std::pair-like structure for storing a qualified type split
-/// into its local qualifiers and its locally-unqualified type.
-struct SplitQualType {
- /// The locally-unqualified type.
- const Type *Ty;
-
- /// The local qualifiers.
- Qualifiers Quals;
-
- SplitQualType() : Ty(nullptr), Quals() {}
- SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
-
- SplitQualType getSingleStepDesugaredType() const; // end of this file
-
- // Make std::tie work.
- std::pair<const Type *,Qualifiers> asPair() const {
- return std::pair<const Type *, Qualifiers>(Ty, Quals);
- }
-
- friend bool operator==(SplitQualType a, SplitQualType b) {
- return a.Ty == b.Ty && a.Quals == b.Quals;
- }
- friend bool operator!=(SplitQualType a, SplitQualType b) {
- return a.Ty != b.Ty || a.Quals != b.Quals;
- }
-};
-
-/// The kind of type we are substituting Objective-C type arguments into.
-///
-/// The kind of substitution affects the replacement of type parameters when
-/// no concrete type information is provided, e.g., when dealing with an
-/// unspecialized type.
-enum class ObjCSubstitutionContext {
- /// An ordinary type.
- Ordinary,
- /// The result type of a method or function.
- Result,
- /// The parameter type of a method or function.
- Parameter,
- /// The type of a property.
- Property,
- /// The superclass of a type.
- Superclass,
-};
-
-/// A (possibly-)qualified type.
-///
-/// For efficiency, we don't store CV-qualified types as nodes on their
-/// own: instead each reference to a type stores the qualifiers. This
-/// greatly reduces the number of nodes we need to allocate for types (for
-/// example we only need one for 'int', 'const int', 'volatile int',
-/// 'const volatile int', etc).
-///
-/// As an added efficiency bonus, instead of making this a pair, we
-/// just store the two bits we care about in the low bits of the
-/// pointer. To handle the packing/unpacking, we make QualType be a
-/// simple wrapper class that acts like a smart pointer. A third bit
-/// indicates whether there are extended qualifiers present, in which
-/// case the pointer points to a special structure.
-class QualType {
- // Thankfully, these are efficiently composable.
- llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
- Qualifiers::FastWidth> Value;
-
- const ExtQuals *getExtQualsUnsafe() const {
- return Value.getPointer().get<const ExtQuals*>();
- }
-
- const Type *getTypePtrUnsafe() const {
- return Value.getPointer().get<const Type*>();
- }
-
- const ExtQualsTypeCommonBase *getCommonPtr() const {
- assert(!isNull() && "Cannot retrieve a NULL type pointer");
- uintptr_t CommonPtrVal
- = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
- CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1);
- return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal);
- }
-
- friend class QualifierCollector;
-public:
- QualType() {}
-
- QualType(const Type *Ptr, unsigned Quals)
- : Value(Ptr, Quals) {}
- QualType(const ExtQuals *Ptr, unsigned Quals)
- : Value(Ptr, Quals) {}
-
- unsigned getLocalFastQualifiers() const { return Value.getInt(); }
- void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
-
- /// Retrieves a pointer to the underlying (unqualified) type.
- ///
- /// This function requires that the type not be NULL. If the type might be
- /// NULL, use the (slightly less efficient) \c getTypePtrOrNull().
- const Type *getTypePtr() const;
-
- const Type *getTypePtrOrNull() const;
-
- /// Retrieves a pointer to the name of the base type.
- const IdentifierInfo *getBaseTypeIdentifier() const;
-
- /// Divides a QualType into its unqualified type and a set of local
- /// qualifiers.
- SplitQualType split() const;
-
- void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
- static QualType getFromOpaquePtr(const void *Ptr) {
- QualType T;
- T.Value.setFromOpaqueValue(const_cast<void*>(Ptr));
- return T;
- }
-
- const Type &operator*() const {
- return *getTypePtr();
- }
-
- const Type *operator->() const {
- return getTypePtr();
- }
-
- bool isCanonical() const;
- bool isCanonicalAsParam() const;
-
- /// Return true if this QualType doesn't point to a type yet.
- bool isNull() const {
- return Value.getPointer().isNull();
- }
-
- /// \brief Determine whether this particular QualType instance has the
- /// "const" qualifier set, without looking through typedefs that may have
- /// added "const" at a different level.
- bool isLocalConstQualified() const {
- return (getLocalFastQualifiers() & Qualifiers::Const);
- }
-
- /// \brief Determine whether this type is const-qualified.
- bool isConstQualified() const;
-
- /// \brief Determine whether this particular QualType instance has the
- /// "restrict" qualifier set, without looking through typedefs that may have
- /// added "restrict" at a different level.
- bool isLocalRestrictQualified() const {
- return (getLocalFastQualifiers() & Qualifiers::Restrict);
- }
-
- /// \brief Determine whether this type is restrict-qualified.
- bool isRestrictQualified() const;
-
- /// \brief Determine whether this particular QualType instance has the
- /// "volatile" qualifier set, without looking through typedefs that may have
- /// added "volatile" at a different level.
- bool isLocalVolatileQualified() const {
- return (getLocalFastQualifiers() & Qualifiers::Volatile);
- }
-
- /// \brief Determine whether this type is volatile-qualified.
- bool isVolatileQualified() const;
-
- /// \brief Determine whether this particular QualType instance has any
- /// qualifiers, without looking through any typedefs that might add
- /// qualifiers at a different level.
- bool hasLocalQualifiers() const {
- return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
- }
-
- /// \brief Determine whether this type has any qualifiers.
- bool hasQualifiers() const;
-
- /// \brief Determine whether this particular QualType instance has any
- /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
- /// instance.
- bool hasLocalNonFastQualifiers() const {
- return Value.getPointer().is<const ExtQuals*>();
- }
-
- /// \brief Retrieve the set of qualifiers local to this particular QualType
- /// instance, not including any qualifiers acquired through typedefs or
- /// other sugar.
- Qualifiers getLocalQualifiers() const;
-
- /// \brief Retrieve the set of qualifiers applied to this type.
- Qualifiers getQualifiers() const;
-
- /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
- /// local to this particular QualType instance, not including any qualifiers
- /// acquired through typedefs or other sugar.
- unsigned getLocalCVRQualifiers() const {
- return getLocalFastQualifiers();
- }
-
- /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
- /// applied to this type.
- unsigned getCVRQualifiers() const;
-
- bool isConstant(ASTContext& Ctx) const {
- return QualType::isConstant(*this, Ctx);
- }
-
- /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
- bool isPODType(ASTContext &Context) const;
-
- /// Return true if this is a POD type according to the rules of the C++98
- /// standard, regardless of the current compilation's language.
- bool isCXX98PODType(ASTContext &Context) const;
-
- /// Return true if this is a POD type according to the more relaxed rules
- /// of the C++11 standard, regardless of the current compilation's language.
- /// (C++0x [basic.types]p9)
- bool isCXX11PODType(ASTContext &Context) const;
-
- /// Return true if this is a trivial type per (C++0x [basic.types]p9)
- bool isTrivialType(ASTContext &Context) const;
-
- /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
- bool isTriviallyCopyableType(ASTContext &Context) const;
-
- // Don't promise in the API that anything besides 'const' can be
- // easily added.
-
- /// Add the `const` type qualifier to this QualType.
- void addConst() {
- addFastQualifiers(Qualifiers::Const);
- }
- QualType withConst() const {
- return withFastQualifiers(Qualifiers::Const);
- }
-
- /// Add the `volatile` type qualifier to this QualType.
- void addVolatile() {
- addFastQualifiers(Qualifiers::Volatile);
- }
- QualType withVolatile() const {
- return withFastQualifiers(Qualifiers::Volatile);
- }
-
- /// Add the `restrict` qualifier to this QualType.
- void addRestrict() {
- addFastQualifiers(Qualifiers::Restrict);
- }
- QualType withRestrict() const {
- return withFastQualifiers(Qualifiers::Restrict);
- }
-
- QualType withCVRQualifiers(unsigned CVR) const {
- return withFastQualifiers(CVR);
- }
-
- void addFastQualifiers(unsigned TQs) {
- assert(!(TQs & ~Qualifiers::FastMask)
- && "non-fast qualifier bits set in mask!");
- Value.setInt(Value.getInt() | TQs);
- }
-
- void removeLocalConst();
- void removeLocalVolatile();
- void removeLocalRestrict();
- void removeLocalCVRQualifiers(unsigned Mask);
-
- void removeLocalFastQualifiers() { Value.setInt(0); }
- void removeLocalFastQualifiers(unsigned Mask) {
- assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers");
- Value.setInt(Value.getInt() & ~Mask);
- }
-
- // Creates a type with the given qualifiers in addition to any
- // qualifiers already on this type.
- QualType withFastQualifiers(unsigned TQs) const {
- QualType T = *this;
- T.addFastQualifiers(TQs);
- return T;
- }
-
- // Creates a type with exactly the given fast qualifiers, removing
- // any existing fast qualifiers.
- QualType withExactLocalFastQualifiers(unsigned TQs) const {
- return withoutLocalFastQualifiers().withFastQualifiers(TQs);
- }
-
- // Removes fast qualifiers, but leaves any extended qualifiers in place.
- QualType withoutLocalFastQualifiers() const {
- QualType T = *this;
- T.removeLocalFastQualifiers();
- return T;
- }
-
- QualType getCanonicalType() const;
-
- /// \brief Return this type with all of the instance-specific qualifiers
- /// removed, but without removing any qualifiers that may have been applied
- /// through typedefs.
- QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
-
- /// \brief Retrieve the unqualified variant of the given type,
- /// removing as little sugar as possible.
- ///
- /// This routine looks through various kinds of sugar to find the
- /// least-desugared type that is unqualified. For example, given:
- ///
- /// \code
- /// typedef int Integer;
- /// typedef const Integer CInteger;
- /// typedef CInteger DifferenceType;
- /// \endcode
- ///
- /// Executing \c getUnqualifiedType() on the type \c DifferenceType will
- /// desugar until we hit the type \c Integer, which has no qualifiers on it.
- ///
- /// The resulting type might still be qualified if it's sugar for an array
- /// type. To strip qualifiers even from within a sugared array type, use
- /// ASTContext::getUnqualifiedArrayType.
- inline QualType getUnqualifiedType() const;
-
- /// Retrieve the unqualified variant of the given type, removing as little
- /// sugar as possible.
- ///
- /// Like getUnqualifiedType(), but also returns the set of
- /// qualifiers that were built up.
- ///
- /// The resulting type might still be qualified if it's sugar for an array
- /// type. To strip qualifiers even from within a sugared array type, use
- /// ASTContext::getUnqualifiedArrayType.
- inline SplitQualType getSplitUnqualifiedType() const;
-
- /// \brief Determine whether this type is more qualified than the other
- /// given type, requiring exact equality for non-CVR qualifiers.
- bool isMoreQualifiedThan(QualType Other) const;
-
- /// \brief Determine whether this type is at least as qualified as the other
- /// given type, requiring exact equality for non-CVR qualifiers.
- bool isAtLeastAsQualifiedAs(QualType Other) const;
-
- QualType getNonReferenceType() const;
-
- /// \brief Determine the type of a (typically non-lvalue) expression with the
- /// specified result type.
- ///
- /// This routine should be used for expressions for which the return type is
- /// explicitly specified (e.g., in a cast or call) and isn't necessarily
- /// an lvalue. It removes a top-level reference (since there are no
- /// expressions of reference type) and deletes top-level cvr-qualifiers
- /// from non-class types (in C++) or all types (in C).
- QualType getNonLValueExprType(const ASTContext &Context) const;
-
- /// Return the specified type with any "sugar" removed from
- /// the type. This takes off typedefs, typeof's etc. If the outer level of
- /// the type is already concrete, it returns it unmodified. This is similar
- /// to getting the canonical type, but it doesn't remove *all* typedefs. For
- /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
- /// concrete.
- ///
- /// Qualifiers are left in place.
- QualType getDesugaredType(const ASTContext &Context) const {
- return getDesugaredType(*this, Context);
- }
-
- SplitQualType getSplitDesugaredType() const {
- return getSplitDesugaredType(*this);
- }
-
- /// \brief Return the specified type with one level of "sugar" removed from
- /// the type.
- ///
- /// This routine takes off the first typedef, typeof, etc. If the outer level
- /// of the type is already concrete, it returns it unmodified.
- QualType getSingleStepDesugaredType(const ASTContext &Context) const {
- return getSingleStepDesugaredTypeImpl(*this, Context);
- }
-
- /// Returns the specified type after dropping any
- /// outer-level parentheses.
- QualType IgnoreParens() const {
- if (isa<ParenType>(*this))
- return QualType::IgnoreParens(*this);
- return *this;
- }
-
- /// Indicate whether the specified types and qualifiers are identical.
- 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;
- }
- std::string getAsString() const {
- return getAsString(split());
- }
- static std::string getAsString(SplitQualType split) {
- return getAsString(split.Ty, split.Quals);
- }
- static std::string getAsString(const Type *ty, Qualifiers qs);
-
- std::string getAsString(const PrintingPolicy &Policy) const;
-
- void print(raw_ostream &OS, const PrintingPolicy &Policy,
- const Twine &PlaceHolder = Twine()) const {
- print(split(), OS, Policy, PlaceHolder);
- }
- static void print(SplitQualType split, raw_ostream &OS,
- const PrintingPolicy &policy, const Twine &PlaceHolder) {
- return print(split.Ty, split.Quals, OS, policy, PlaceHolder);
- }
- static void print(const Type *ty, Qualifiers qs,
- raw_ostream &OS, const PrintingPolicy &policy,
- const Twine &PlaceHolder);
-
- void getAsStringInternal(std::string &Str,
- const PrintingPolicy &Policy) const {
- return getAsStringInternal(split(), Str, Policy);
- }
- static void getAsStringInternal(SplitQualType split, std::string &out,
- const PrintingPolicy &policy) {
- return getAsStringInternal(split.Ty, split.Quals, out, policy);
- }
- static void getAsStringInternal(const Type *ty, Qualifiers qs,
- std::string &out,
- const PrintingPolicy &policy);
-
- class StreamedQualTypeHelper {
- const QualType &T;
- const PrintingPolicy &Policy;
- const Twine &PlaceHolder;
- public:
- StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy,
- const Twine &PlaceHolder)
- : T(T), Policy(Policy), PlaceHolder(PlaceHolder) { }
-
- friend raw_ostream &operator<<(raw_ostream &OS,
- const StreamedQualTypeHelper &SQT) {
- SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder);
- return OS;
- }
- };
-
- StreamedQualTypeHelper stream(const PrintingPolicy &Policy,
- const Twine &PlaceHolder = Twine()) const {
- return StreamedQualTypeHelper(*this, Policy, PlaceHolder);
- }
-
- void dump(const char *s) const;
- void dump() const;
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddPointer(getAsOpaquePtr());
- }
-
- /// Return the address space of this type.
- inline unsigned getAddressSpace() const;
-
- /// Returns gc attribute of this type.
- inline Qualifiers::GC getObjCGCAttr() const;
-
- /// true when Type is objc's weak.
- bool isObjCGCWeak() const {
- return getObjCGCAttr() == Qualifiers::Weak;
- }
-
- /// true when Type is objc's strong.
- bool isObjCGCStrong() const {
- return getObjCGCAttr() == Qualifiers::Strong;
- }
-
- /// Returns lifetime attribute of this type.
- Qualifiers::ObjCLifetime getObjCLifetime() const {
- return getQualifiers().getObjCLifetime();
- }
-
- bool hasNonTrivialObjCLifetime() const {
- return getQualifiers().hasNonTrivialObjCLifetime();
- }
-
- bool hasStrongOrWeakObjCLifetime() const {
- return getQualifiers().hasStrongOrWeakObjCLifetime();
- }
-
- enum DestructionKind {
- DK_none,
- DK_cxx_destructor,
- DK_objc_strong_lifetime,
- DK_objc_weak_lifetime
- };
-
- /// Returns a nonzero value if objects of this type require
- /// non-trivial work to clean up after. Non-zero because it's
- /// conceivable that qualifiers (objc_gc(weak)?) could make
- /// something require destruction.
- DestructionKind isDestructedType() const {
- return isDestructedTypeImpl(*this);
- }
-
- /// Determine whether expressions of the given type are forbidden
- /// from being lvalues in C.
- ///
- /// The expression types that are forbidden to be lvalues are:
- /// - 'void', but not qualified void
- /// - function types
- ///
- /// The exact rule here is C99 6.3.2.1:
- /// An lvalue is an expression with an object type or an incomplete
- /// type other than void.
- bool isCForbiddenLValueType() const;
-
- /// Substitute type arguments for the Objective-C type parameters used in the
- /// subject type.
- ///
- /// \param ctx ASTContext in which the type exists.
- ///
- /// \param typeArgs The type arguments that will be substituted for the
- /// Objective-C type parameters in the subject type, which are generally
- /// computed via \c Type::getObjCSubstitutions. If empty, the type
- /// parameters will be replaced with their bounds or id/Class, as appropriate
- /// for the context.
- ///
- /// \param context The context in which the subject type was written.
- ///
- /// \returns the resulting type.
- QualType substObjCTypeArgs(ASTContext &ctx,
- ArrayRef<QualType> typeArgs,
- ObjCSubstitutionContext context) const;
-
- /// Substitute type arguments from an object type for the Objective-C type
- /// parameters used in the subject type.
- ///
- /// This operation combines the computation of type arguments for
- /// substitution (\c Type::getObjCSubstitutions) with the actual process of
- /// substitution (\c QualType::substObjCTypeArgs) for the convenience of
- /// callers that need to perform a single substitution in isolation.
- ///
- /// \param objectType The type of the object whose member type we're
- /// substituting into. For example, this might be the receiver of a message
- /// or the base of a property access.
- ///
- /// \param dc The declaration context from which the subject type was
- /// retrieved, which indicates (for example) which type parameters should
- /// be substituted.
- ///
- /// \param context The context in which the subject type was written.
- ///
- /// \returns the subject type after replacing all of the Objective-C type
- /// parameters with their corresponding arguments.
- QualType substObjCMemberType(QualType objectType,
- const DeclContext *dc,
- ObjCSubstitutionContext context) const;
-
- /// Strip Objective-C "__kindof" types from the given type.
- QualType stripObjCKindOfType(const ASTContext &ctx) const;
-
-private:
- // These methods are implemented in a separate translation unit;
- // "static"-ize them to avoid creating temporary QualTypes in the
- // caller.
- static bool isConstant(QualType T, ASTContext& Ctx);
- static QualType getDesugaredType(QualType T, const ASTContext &Context);
- static SplitQualType getSplitDesugaredType(QualType T);
- static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);
- static QualType getSingleStepDesugaredTypeImpl(QualType type,
- const ASTContext &C);
- static QualType IgnoreParens(QualType T);
- static DestructionKind isDestructedTypeImpl(QualType type);
-};
-
-} // end clang.
-
-namespace llvm {
-/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
-/// to a specific Type class.
-template<> struct simplify_type< ::clang::QualType> {
- typedef const ::clang::Type *SimpleType;
- static SimpleType getSimplifiedValue(::clang::QualType Val) {
- return Val.getTypePtr();
- }
-};
-
-// Teach SmallPtrSet that QualType is "basically a pointer".
-template<>
-class PointerLikeTypeTraits<clang::QualType> {
-public:
- static inline void *getAsVoidPointer(clang::QualType P) {
- return P.getAsOpaquePtr();
- }
- static inline clang::QualType getFromVoidPointer(void *P) {
- return clang::QualType::getFromOpaquePtr(P);
- }
- // Various qualifiers go in low bits.
- enum { NumLowBitsAvailable = 0 };
-};
-
-} // end namespace llvm
-
-namespace clang {
-
-/// \brief Base class that is common to both the \c ExtQuals and \c Type
-/// classes, which allows \c QualType to access the common fields between the
-/// two.
-///
-class ExtQualsTypeCommonBase {
- ExtQualsTypeCommonBase(const Type *baseType, QualType canon)
- : BaseType(baseType), CanonicalType(canon) {}
-
- /// \brief The "base" type of an extended qualifiers type (\c ExtQuals) or
- /// a self-referential pointer (for \c Type).
- ///
- /// This pointer allows an efficient mapping from a QualType to its
- /// underlying type pointer.
- const Type *const BaseType;
-
- /// \brief The canonical type of this type. A QualType.
- QualType CanonicalType;
-
- friend class QualType;
- friend class Type;
- friend class ExtQuals;
-};
-
-/// We can encode up to four bits in the low bits of a
-/// type pointer, but there are many more type qualifiers that we want
-/// to be able to apply to an arbitrary type. Therefore we have this
-/// struct, intended to be heap-allocated and used by QualType to
-/// store qualifiers.
-///
-/// The current design tags the 'const', 'restrict', and 'volatile' qualifiers
-/// in three low bits on the QualType pointer; a fourth bit records whether
-/// the pointer is an ExtQuals node. The extended qualifiers (address spaces,
-/// Objective-C GC attributes) are much more rare.
-class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
- // NOTE: changing the fast qualifiers should be straightforward as
- // long as you don't make 'const' non-fast.
- // 1. Qualifiers:
- // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ).
- // Fast qualifiers must occupy the low-order bits.
- // b) Update Qualifiers::FastWidth and FastMask.
- // 2. QualType:
- // a) Update is{Volatile,Restrict}Qualified(), defined inline.
- // b) Update remove{Volatile,Restrict}, defined near the end of
- // this header.
- // 3. ASTContext:
- // a) Update get{Volatile,Restrict}Type.
-
- /// The immutable set of qualifiers applied by this node. Always contains
- /// extended qualifiers.
- Qualifiers Quals;
-
- ExtQuals *this_() { return this; }
-
-public:
- ExtQuals(const Type *baseType, QualType canon, Qualifiers quals)
- : ExtQualsTypeCommonBase(baseType,
- canon.isNull() ? QualType(this_(), 0) : canon),
- Quals(quals)
- {
- assert(Quals.hasNonFastQualifiers()
- && "ExtQuals created with no fast qualifiers");
- assert(!Quals.hasFastQualifiers()
- && "ExtQuals created with fast qualifiers");
- }
-
- Qualifiers getQualifiers() const { return Quals; }
-
- bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
- Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
-
- bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); }
- Qualifiers::ObjCLifetime getObjCLifetime() const {
- return Quals.getObjCLifetime();
- }
-
- bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
- unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
-
- const Type *getBaseType() const { return BaseType; }
-
-public:
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, getBaseType(), Quals);
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- const Type *BaseType,
- Qualifiers Quals) {
- assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!");
- ID.AddPointer(BaseType);
- Quals.Profile(ID);
- }
-};
-
-/// The kind of C++11 ref-qualifier associated with a function type.
-/// This determines whether a member function's "this" object can be an
-/// lvalue, rvalue, or neither.
-enum RefQualifierKind {
- /// \brief No ref-qualifier was provided.
- RQ_None = 0,
- /// \brief An lvalue ref-qualifier was provided (\c &).
- RQ_LValue,
- /// \brief An rvalue ref-qualifier was provided (\c &&).
- RQ_RValue
-};
-
-/// Which keyword(s) were used to create an AutoType.
-enum class AutoTypeKeyword {
- /// \brief auto
- Auto,
- /// \brief decltype(auto)
- DecltypeAuto,
- /// \brief __auto_type (GNU extension)
- GNUAutoType
-};
-
-/// The base class of the type hierarchy.
-///
-/// A central concept with types is that each type always has a canonical
-/// type. A canonical type is the type with any typedef names stripped out
-/// of it or the types it references. For example, consider:
-///
-/// typedef int foo;
-/// typedef foo* bar;
-/// 'int *' 'foo *' 'bar'
-///
-/// There will be a Type object created for 'int'. Since int is canonical, its
-/// CanonicalType pointer points to itself. There is also a Type for 'foo' (a
-/// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next
-/// there is a PointerType that represents 'int*', which, like 'int', is
-/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical
-/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type
-/// is also 'int*'.
-///
-/// Non-canonical types are useful for emitting diagnostics, without losing
-/// information about typedefs being used. Canonical types are useful for type
-/// comparisons (they allow by-pointer equality tests) and useful for reasoning
-/// about whether something has a particular form (e.g. is a function type),
-/// because they implicitly, recursively, strip all typedefs out of a type.
-///
-/// Types, once created, are immutable.
-///
-class Type : public ExtQualsTypeCommonBase {
-public:
- enum TypeClass {
-#define TYPE(Class, Base) Class,
-#define LAST_TYPE(Class) TypeLast = Class,
-#define ABSTRACT_TYPE(Class, Base)
-#include "clang/AST/TypeNodes.def"
- TagFirst = Record, TagLast = Enum
- };
-
-private:
- Type(const Type &) = delete;
- void operator=(const Type &) = delete;
-
- /// Bitfields required by the Type class.
- class TypeBitfields {
- friend class Type;
- template <class T> friend class TypePropertyCache;
-
- /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
- unsigned TC : 8;
-
- /// Whether this type is a dependent type (C++ [temp.dep.type]).
- unsigned Dependent : 1;
-
- /// Whether this type somehow involves a template parameter, even
- /// if the resolution of the type does not depend on a template parameter.
- unsigned InstantiationDependent : 1;
-
- /// Whether this type is a variably-modified type (C99 6.7.5).
- unsigned VariablyModified : 1;
-
- /// \brief Whether this type contains an unexpanded parameter pack
- /// (for C++11 variadic templates).
- unsigned ContainsUnexpandedParameterPack : 1;
-
- /// \brief True if the cache (i.e. the bitfields here starting with
- /// 'Cache') is valid.
- mutable unsigned CacheValid : 1;
-
- /// \brief Linkage of this type.
- mutable unsigned CachedLinkage : 3;
-
- /// \brief Whether this type involves and local or unnamed types.
- mutable unsigned CachedLocalOrUnnamed : 1;
-
- /// \brief Whether this type comes from an AST file.
- mutable unsigned FromAST : 1;
-
- bool isCacheValid() const {
- return CacheValid;
- }
- Linkage getLinkage() const {
- assert(isCacheValid() && "getting linkage from invalid cache");
- return static_cast<Linkage>(CachedLinkage);
- }
- bool hasLocalOrUnnamedType() const {
- assert(isCacheValid() && "getting linkage from invalid cache");
- return CachedLocalOrUnnamed;
- }
- };
- enum { NumTypeBits = 18 };
-
-protected:
- // These classes allow subclasses to somewhat cleanly pack bitfields
- // into Type.
-
- class ArrayTypeBitfields {
- friend class ArrayType;
-
- unsigned : NumTypeBits;
-
- /// CVR qualifiers from declarations like
- /// 'int X[static restrict 4]'. For function parameters only.
- unsigned IndexTypeQuals : 3;
-
- /// Storage class qualifiers from declarations like
- /// 'int X[static restrict 4]'. For function parameters only.
- /// Actually an ArrayType::ArraySizeModifier.
- unsigned SizeModifier : 3;
- };
-
- class BuiltinTypeBitfields {
- friend class BuiltinType;
-
- unsigned : NumTypeBits;
-
- /// The kind (BuiltinType::Kind) of builtin type this is.
- unsigned Kind : 8;
- };
-
- class FunctionTypeBitfields {
- friend class FunctionType;
- friend class FunctionProtoType;
-
- unsigned : NumTypeBits;
-
- /// Extra information which affects how the function is called, like
- /// regparm and the calling convention.
- unsigned ExtInfo : 9;
-
- /// Used only by FunctionProtoType, put here to pack with the
- /// other bitfields.
- /// The qualifiers are part of FunctionProtoType because...
- ///
- /// C++ 8.3.5p4: The return type, the parameter type list and the
- /// cv-qualifier-seq, [...], are part of the function type.
- unsigned TypeQuals : 3;
-
- /// \brief The ref-qualifier associated with a \c FunctionProtoType.
- ///
- /// This is a value of type \c RefQualifierKind.
- unsigned RefQualifier : 2;
- };
-
- class ObjCObjectTypeBitfields {
- friend class ObjCObjectType;
-
- unsigned : NumTypeBits;
-
- /// The number of type arguments stored directly on this object type.
- unsigned NumTypeArgs : 7;
-
- /// The number of protocols stored directly on this object type.
- unsigned NumProtocols : 6;
-
- /// Whether this is a "kindof" type.
- unsigned IsKindOf : 1;
- };
- static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned");
-
- class ReferenceTypeBitfields {
- friend class ReferenceType;
-
- unsigned : NumTypeBits;
-
- /// True if the type was originally spelled with an lvalue sigil.
- /// This is never true of rvalue references but can also be false
- /// on lvalue references because of C++0x [dcl.typedef]p9,
- /// as follows:
- ///
- /// typedef int &ref; // lvalue, spelled lvalue
- /// typedef int &&rvref; // rvalue
- /// ref &a; // lvalue, inner ref, spelled lvalue
- /// ref &&a; // lvalue, inner ref
- /// rvref &a; // lvalue, inner ref, spelled lvalue
- /// rvref &&a; // rvalue, inner ref
- unsigned SpelledAsLValue : 1;
-
- /// True if the inner type is a reference type. This only happens
- /// in non-canonical forms.
- unsigned InnerRef : 1;
- };
-
- class TypeWithKeywordBitfields {
- friend class TypeWithKeyword;
-
- unsigned : NumTypeBits;
-
- /// An ElaboratedTypeKeyword. 8 bits for efficient access.
- unsigned Keyword : 8;
- };
-
- class VectorTypeBitfields {
- friend class VectorType;
-
- unsigned : NumTypeBits;
-
- /// The kind of vector, either a generic vector type or some
- /// target-specific vector type such as for AltiVec or Neon.
- unsigned VecKind : 3;
-
- /// The number of elements in the vector.
- unsigned NumElements : 29 - NumTypeBits;
-
- enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 };
- };
-
- class AttributedTypeBitfields {
- friend class AttributedType;
-
- unsigned : NumTypeBits;
-
- /// An AttributedType::Kind
- unsigned AttrKind : 32 - NumTypeBits;
- };
-
- class AutoTypeBitfields {
- friend class AutoType;
-
- unsigned : NumTypeBits;
-
- /// Was this placeholder type spelled as 'auto', 'decltype(auto)',
- /// or '__auto_type'? AutoTypeKeyword value.
- unsigned Keyword : 2;
- };
-
- union {
- TypeBitfields TypeBits;
- ArrayTypeBitfields ArrayTypeBits;
- AttributedTypeBitfields AttributedTypeBits;
- AutoTypeBitfields AutoTypeBits;
- BuiltinTypeBitfields BuiltinTypeBits;
- FunctionTypeBitfields FunctionTypeBits;
- ObjCObjectTypeBitfields ObjCObjectTypeBits;
- ReferenceTypeBitfields ReferenceTypeBits;
- TypeWithKeywordBitfields TypeWithKeywordBits;
- VectorTypeBitfields VectorTypeBits;
- };
-
-private:
- /// \brief Set whether this type comes from an AST file.
- void setFromAST(bool V = true) const {
- TypeBits.FromAST = V;
- }
-
- template <class T> friend class TypePropertyCache;
-
-protected:
- // silence VC++ warning C4355: 'this' : used in base member initializer list
- Type *this_() { return this; }
- Type(TypeClass tc, QualType canon, bool Dependent,
- bool InstantiationDependent, bool VariablyModified,
- bool ContainsUnexpandedParameterPack)
- : ExtQualsTypeCommonBase(this,
- canon.isNull() ? QualType(this_(), 0) : canon) {
- TypeBits.TC = tc;
- TypeBits.Dependent = Dependent;
- TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
- TypeBits.VariablyModified = VariablyModified;
- TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
- TypeBits.CacheValid = false;
- TypeBits.CachedLocalOrUnnamed = false;
- TypeBits.CachedLinkage = NoLinkage;
- TypeBits.FromAST = false;
- }
- friend class ASTContext;
-
- void setDependent(bool D = true) {
- TypeBits.Dependent = D;
- if (D)
- TypeBits.InstantiationDependent = true;
- }
- void setInstantiationDependent(bool D = true) {
- TypeBits.InstantiationDependent = D; }
- void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM;
- }
- void setContainsUnexpandedParameterPack(bool PP = true) {
- TypeBits.ContainsUnexpandedParameterPack = PP;
- }
-
-public:
- TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); }
-
- /// \brief Whether this type comes from an AST file.
- bool isFromAST() const { return TypeBits.FromAST; }
-
- /// \brief Whether this type is or contains an unexpanded parameter
- /// pack, used to support C++0x variadic templates.
- ///
- /// A type that contains a parameter pack shall be expanded by the
- /// ellipsis operator at some point. For example, the typedef in the
- /// following example contains an unexpanded parameter pack 'T':
- ///
- /// \code
- /// template<typename ...T>
- /// struct X {
- /// typedef T* pointer_types; // ill-formed; T is a parameter pack.
- /// };
- /// \endcode
- ///
- /// Note that this routine does not specify which
- bool containsUnexpandedParameterPack() const {
- return TypeBits.ContainsUnexpandedParameterPack;
- }
-
- /// Determines if this type would be canonical if it had no further
- /// qualification.
- bool isCanonicalUnqualified() const {
- return CanonicalType == QualType(this, 0);
- }
-
- /// Pull a single level of sugar off of this locally-unqualified type.
- /// Users should generally prefer SplitQualType::getSingleStepDesugaredType()
- /// or QualType::getSingleStepDesugaredType(const ASTContext&).
- QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
-
- /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
- /// object types, function types, and incomplete types.
-
- /// Return true if this is an incomplete type.
- /// A type that can describe objects, but which lacks information needed to
- /// determine its size (e.g. void, or a fwd declared struct). Clients of this
- /// routine will need to determine if the size is actually required.
- ///
- /// \brief Def If non-null, and the type refers to some kind of declaration
- /// that can be completed (such as a C struct, C++ class, or Objective-C
- /// class), will be set to the declaration.
- bool isIncompleteType(NamedDecl **Def = nullptr) const;
-
- /// Return true if this is an incomplete or object
- /// type, in other words, not a function type.
- bool isIncompleteOrObjectType() const {
- return !isFunctionType();
- }
-
- /// \brief Determine whether this type is an object type.
- bool isObjectType() const {
- // C++ [basic.types]p8:
- // An object type is a (possibly cv-qualified) type that is not a
- // function type, not a reference type, and not a void type.
- return !isReferenceType() && !isFunctionType() && !isVoidType();
- }
-
- /// Return true if this is a literal type
- /// (C++11 [basic.types]p10)
- bool isLiteralType(const ASTContext &Ctx) const;
-
- /// Test if this type is a standard-layout type.
- /// (C++0x [basic.type]p9)
- bool isStandardLayoutType() const;
-
- /// Helper methods to distinguish type categories. All type predicates
- /// operate on the canonical type, ignoring typedefs and qualifiers.
-
- /// Returns true if the type is a builtin type.
- bool isBuiltinType() const;
-
- /// Test for a particular builtin type.
- bool isSpecificBuiltinType(unsigned K) const;
-
- /// Test for a type which does not represent an actual type-system type but
- /// is instead used as a placeholder for various convenient purposes within
- /// Clang. All such types are BuiltinTypes.
- bool isPlaceholderType() const;
- const BuiltinType *getAsPlaceholderType() const;
-
- /// Test for a specific placeholder type.
- bool isSpecificPlaceholderType(unsigned K) const;
-
- /// Test for a placeholder type other than Overload; see
- /// BuiltinType::isNonOverloadPlaceholderType.
- bool isNonOverloadPlaceholderType() const;
-
- /// isIntegerType() does *not* include complex integers (a GCC extension).
- /// isComplexIntegerType() can be used to test for complex integers.
- bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum)
- bool isEnumeralType() const;
- bool isBooleanType() const;
- bool isCharType() const;
- bool isWideCharType() const;
- bool isChar16Type() const;
- bool isChar32Type() const;
- bool isAnyCharacterType() const;
- bool isIntegralType(ASTContext &Ctx) const;
-
- /// Determine whether this type is an integral or enumeration type.
- bool isIntegralOrEnumerationType() const;
- /// Determine whether this type is an integral or unscoped enumeration type.
- bool isIntegralOrUnscopedEnumerationType() const;
-
- /// Floating point categories.
- bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
- /// isComplexType() does *not* include complex integers (a GCC extension).
- /// isComplexIntegerType() can be used to test for complex integers.
- bool isComplexType() const; // C99 6.2.5p11 (complex)
- bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int.
- bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex)
- bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half)
- bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
- bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
- bool isVoidType() const; // C99 6.2.5p19
- bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
- bool isAggregateType() const;
- bool isFundamentalType() const;
- bool isCompoundType() const;
-
- // Type Predicates: Check to see if this type is structurally the specified
- // type, ignoring typedefs and qualifiers.
- bool isFunctionType() const;
- bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); }
- bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
- bool isPointerType() const;
- bool isAnyPointerType() const; // Any C pointer or ObjC object pointer
- bool isBlockPointerType() const;
- bool isVoidPointerType() const;
- bool isReferenceType() const;
- bool isLValueReferenceType() const;
- bool isRValueReferenceType() const;
- bool isFunctionPointerType() const;
- bool isMemberPointerType() const;
- bool isMemberFunctionPointerType() const;
- bool isMemberDataPointerType() const;
- bool isArrayType() const;
- bool isConstantArrayType() const;
- bool isIncompleteArrayType() const;
- bool isVariableArrayType() const;
- bool isDependentSizedArrayType() const;
- bool isRecordType() const;
- bool isClassType() const;
- bool isStructureType() const;
- bool isObjCBoxableRecordType() const;
- bool isInterfaceType() const;
- bool isStructureOrClassType() const;
- bool isUnionType() const;
- bool isComplexIntegerType() const; // GCC _Complex integer type.
- bool isVectorType() const; // GCC vector type.
- bool isExtVectorType() const; // Extended vector type.
- bool isObjCObjectPointerType() const; // pointer to ObjC object
- bool isObjCRetainableType() const; // ObjC object or block pointer
- bool isObjCLifetimeType() const; // (array of)* retainable type
- bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type
- bool isObjCNSObjectType() const; // __attribute__((NSObject))
- bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class))
- // FIXME: change this to 'raw' interface type, so we can used 'interface' type
- // for the common case.
- bool isObjCObjectType() const; // NSString or typeof(*(id)0)
- bool isObjCQualifiedInterfaceType() const; // NSString<foo>
- bool isObjCQualifiedIdType() const; // id<foo>
- bool isObjCQualifiedClassType() const; // Class<foo>
- bool isObjCObjectOrInterfaceType() const;
- bool isObjCIdType() const; // id
- bool isObjCInertUnsafeUnretainedType() const;
-
- /// Whether the type is Objective-C 'id' or a __kindof type of an
- /// object type, e.g., __kindof NSView * or __kindof id
- /// <NSCopying>.
- ///
- /// \param bound Will be set to the bound on non-id subtype types,
- /// which will be (possibly specialized) Objective-C class type, or
- /// null for 'id.
- bool isObjCIdOrObjectKindOfType(const ASTContext &ctx,
- const ObjCObjectType *&bound) const;
-
- bool isObjCClassType() const; // Class
-
- /// Whether the type is Objective-C 'Class' or a __kindof type of an
- /// Class type, e.g., __kindof Class <NSCopying>.
- ///
- /// Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound
- /// here because Objective-C's type system cannot express "a class
- /// object for a subclass of NSFoo".
- bool isObjCClassOrClassKindOfType() const;
-
- bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const;
- bool isObjCSelType() const; // Class
- bool isObjCBuiltinType() const; // 'id' or 'Class'
- bool isObjCARCBridgableType() const;
- bool isCARCBridgableType() const;
- bool isTemplateTypeParmType() const; // C++ template type parameter
- bool isNullPtrType() const; // C++0x nullptr_t
- bool isAtomicType() const; // C11 _Atomic()
-
- bool isImage1dT() const; // OpenCL image1d_t
- bool isImage1dArrayT() const; // OpenCL image1d_array_t
- bool isImage1dBufferT() const; // OpenCL image1d_buffer_t
- bool isImage2dT() const; // OpenCL image2d_t
- bool isImage2dArrayT() const; // OpenCL image2d_array_t
- bool isImage2dDepthT() const; // OpenCL image_2d_depth_t
- bool isImage2dArrayDepthT() const; // OpenCL image_2d_array_depth_t
- bool isImage2dMSAAT() const; // OpenCL image_2d_msaa_t
- bool isImage2dArrayMSAAT() const; // OpenCL image_2d_array_msaa_t
- bool isImage2dMSAATDepth() const; // OpenCL image_2d_msaa_depth_t
- bool isImage2dArrayMSAATDepth() const; // OpenCL image_2d_array_msaa_depth_t
- bool isImage3dT() const; // OpenCL image3d_t
-
- bool isImageType() const; // Any OpenCL image type
-
- bool isSamplerT() const; // OpenCL sampler_t
- bool isEventT() const; // OpenCL event_t
- bool isClkEventT() const; // OpenCL clk_event_t
- bool isQueueT() const; // OpenCL queue_t
- bool isNDRangeT() const; // OpenCL ndrange_t
- bool isReserveIDT() const; // OpenCL reserve_id_t
-
- bool isOpenCLSpecificType() const; // Any OpenCL specific type
-
- /// Determines if this type, which must satisfy
- /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
- /// than implicitly __strong.
- bool isObjCARCImplicitlyUnretainedType() const;
-
- /// Return the implicit lifetime for this type, which must not be dependent.
- Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const;
-
- enum ScalarTypeKind {
- STK_CPointer,
- STK_BlockPointer,
- STK_ObjCObjectPointer,
- STK_MemberPointer,
- STK_Bool,
- STK_Integral,
- STK_Floating,
- STK_IntegralComplex,
- STK_FloatingComplex
- };
- /// Given that this is a scalar type, classify it.
- ScalarTypeKind getScalarTypeKind() const;
-
- /// Whether this type is a dependent type, meaning that its definition
- /// somehow depends on a template parameter (C++ [temp.dep.type]).
- bool isDependentType() const { return TypeBits.Dependent; }
-
- /// \brief Determine whether this type is an instantiation-dependent type,
- /// meaning that the type involves a template parameter (even if the
- /// definition does not actually depend on the type substituted for that
- /// template parameter).
- bool isInstantiationDependentType() const {
- return TypeBits.InstantiationDependent;
- }
-
- /// \brief Determine whether this type is an undeduced type, meaning that
- /// it somehow involves a C++11 'auto' type which has not yet been deduced.
- bool isUndeducedType() const;
-
- /// \brief Whether this type is a variably-modified type (C99 6.7.5).
- bool isVariablyModifiedType() const { return TypeBits.VariablyModified; }
-
- /// \brief Whether this type involves a variable-length array type
- /// with a definite size.
- bool hasSizedVLAType() const;
-
- /// \brief Whether this type is or contains a local or unnamed type.
- bool hasUnnamedOrLocalType() const;
-
- bool isOverloadableType() const;
-
- /// \brief Determine wither this type is a C++ elaborated-type-specifier.
- bool isElaboratedTypeSpecifier() const;
-
- bool canDecayToPointerType() const;
-
- /// Whether this type is represented natively as a pointer. This includes
- /// pointers, references, block pointers, and Objective-C interface,
- /// qualified id, and qualified interface types, as well as nullptr_t.
- bool hasPointerRepresentation() const;
-
- /// Whether this type can represent an objective pointer type for the
- /// purpose of GC'ability
- bool hasObjCPointerRepresentation() const;
-
- /// \brief Determine whether this type has an integer representation
- /// of some sort, e.g., it is an integer type or a vector.
- bool hasIntegerRepresentation() const;
-
- /// \brief Determine whether this type has an signed integer representation
- /// of some sort, e.g., it is an signed integer type or a vector.
- bool hasSignedIntegerRepresentation() const;
-
- /// \brief Determine whether this type has an unsigned integer representation
- /// of some sort, e.g., it is an unsigned integer type or a vector.
- bool hasUnsignedIntegerRepresentation() const;
-
- /// \brief Determine whether this type has a floating-point representation
- /// of some sort, e.g., it is a floating-point type or a vector thereof.
- bool hasFloatingRepresentation() const;
-
- // Type Checking Functions: Check to see if this type is structurally the
- // specified type, ignoring typedefs and qualifiers, and return a pointer to
- // the best type we can.
- const RecordType *getAsStructureType() const;
- /// NOTE: getAs*ArrayType are methods on ASTContext.
- const RecordType *getAsUnionType() const;
- const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
- const ObjCObjectType *getAsObjCInterfaceType() const;
- // The following is a convenience method that returns an ObjCObjectPointerType
- // for object declared using an interface.
- const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
- const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
- const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
- const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
-
- /// \brief Retrieves the CXXRecordDecl that this type refers to, either
- /// because the type is a RecordType or because it is the injected-class-name
- /// type of a class template or class template partial specialization.
- CXXRecordDecl *getAsCXXRecordDecl() const;
-
- /// \brief Retrieves the TagDecl that this type refers to, either
- /// because the type is a TagType or because it is the injected-class-name
- /// type of a class template or class template partial specialization.
- TagDecl *getAsTagDecl() const;
-
- /// If this is a pointer or reference to a RecordType, return the
- /// CXXRecordDecl that that type refers to.
- ///
- /// If this is not a pointer or reference, or the type being pointed to does
- /// not refer to a CXXRecordDecl, returns NULL.
- const CXXRecordDecl *getPointeeCXXRecordDecl() const;
-
- /// Get the AutoType whose type will be deduced for a variable with
- /// an initializer of this type. This looks through declarators like pointer
- /// types, but not through decltype or typedefs.
- AutoType *getContainedAutoType() const;
-
- /// Member-template getAs<specific type>'. Look through sugar for
- /// an instance of \<specific type>. This scheme will eventually
- /// replace the specific getAsXXXX methods above.
- ///
- /// There are some specializations of this member template listed
- /// immediately following this class.
- template <typename T> const T *getAs() const;
-
- /// A variant of getAs<> for array types which silently discards
- /// qualifiers from the outermost type.
- const ArrayType *getAsArrayTypeUnsafe() const;
-
- /// Member-template castAs<specific type>. Look through sugar for
- /// the underlying instance of \<specific type>.
- ///
- /// This method has the same relationship to getAs<T> as cast<T> has
- /// to dyn_cast<T>; which is to say, the underlying type *must*
- /// have the intended type, and this method will never return null.
- template <typename T> const T *castAs() const;
-
- /// A variant of castAs<> for array type which silently discards
- /// qualifiers from the outermost type.
- const ArrayType *castAsArrayTypeUnsafe() const;
-
- /// Get the base element type of this type, potentially discarding type
- /// qualifiers. This should never be used when type qualifiers
- /// are meaningful.
- const Type *getBaseElementTypeUnsafe() const;
-
- /// If this is an array type, return the element type of the array,
- /// potentially with type qualifiers missing.
- /// This should never be used when type qualifiers are meaningful.
- const Type *getArrayElementTypeNoTypeQual() const;
-
- /// If this is a pointer, ObjC object pointer, or block
- /// pointer, this returns the respective pointee.
- QualType getPointeeType() const;
-
- /// Return the specified type with any "sugar" removed from the type,
- /// removing any typedefs, typeofs, etc., as well as any qualifiers.
- const Type *getUnqualifiedDesugaredType() const;
-
- /// More type predicates useful for type checking/promotion
- bool isPromotableIntegerType() const; // C99 6.3.1.1p2
-
- /// Return true if this is an integer type that is
- /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
- /// or an enum decl which has a signed representation.
- bool isSignedIntegerType() const;
-
- /// Return true if this is an integer type that is
- /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool],
- /// or an enum decl which has an unsigned representation.
- bool isUnsignedIntegerType() const;
-
- /// Determines whether this is an integer type that is signed or an
- /// enumeration types whose underlying type is a signed integer type.
- bool isSignedIntegerOrEnumerationType() const;
-
- /// Determines whether this is an integer type that is unsigned or an
- /// enumeration types whose underlying type is a unsigned integer type.
- bool isUnsignedIntegerOrEnumerationType() const;
-
- /// Return true if this is not a variable sized type,
- /// according to the rules of C99 6.7.5p3. It is not legal to call this on
- /// incomplete types.
- bool isConstantSizeType() const;
-
- /// Returns true if this type can be represented by some
- /// set of type specifiers.
- bool isSpecifierType() const;
-
- /// Determine the linkage of this type.
- Linkage getLinkage() const;
-
- /// Determine the visibility of this type.
- Visibility getVisibility() const {
- return getLinkageAndVisibility().getVisibility();
- }
-
- /// Return true if the visibility was explicitly set is the code.
- bool isVisibilityExplicit() const {
- return getLinkageAndVisibility().isVisibilityExplicit();
- }
-
- /// Determine the linkage and visibility of this type.
- LinkageInfo getLinkageAndVisibility() const;
-
- /// True if the computed linkage is valid. Used for consistency
- /// checking. Should always return true.
- bool isLinkageValid() const;
-
- /// Determine the nullability of the given type.
- ///
- /// Note that nullability is only captured as sugar within the type
- /// system, not as part of the canonical type, so nullability will
- /// be lost by canonicalization and desugaring.
- Optional<NullabilityKind> getNullability(const ASTContext &context) const;
-
- /// Determine whether the given type can have a nullability
- /// specifier applied to it, i.e., if it is any kind of pointer type
- /// or a dependent type that could instantiate to any kind of
- /// pointer type.
- bool canHaveNullability() const;
-
- /// Retrieve the set of substitutions required when accessing a member
- /// of the Objective-C receiver type that is declared in the given context.
- ///
- /// \c *this is the type of the object we're operating on, e.g., the
- /// receiver for a message send or the base of a property access, and is
- /// expected to be of some object or object pointer type.
- ///
- /// \param dc The declaration context for which we are building up a
- /// substitution mapping, which should be an Objective-C class, extension,
- /// category, or method within.
- ///
- /// \returns an array of type arguments that can be substituted for
- /// the type parameters of the given declaration context in any type described
- /// within that context, or an empty optional to indicate that no
- /// substitution is required.
- Optional<ArrayRef<QualType>>
- getObjCSubstitutions(const DeclContext *dc) const;
-
- /// Determines if this is an ObjC interface type that may accept type
- /// parameters.
- bool acceptsObjCTypeParams() const;
-
- const char *getTypeClassName() const;
-
- QualType getCanonicalTypeInternal() const {
- return CanonicalType;
- }
- CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
- void dump() const;
-
- friend class ASTReader;
- friend class ASTWriter;
-};
-
-/// \brief This will check for a TypedefType by removing any existing sugar
-/// until it reaches a TypedefType or a non-sugared type.
-template <> const TypedefType *Type::getAs() const;
-
-/// \brief This will check for a TemplateSpecializationType by removing any
-/// existing sugar until it reaches a TemplateSpecializationType or a
-/// non-sugared type.
-template <> const TemplateSpecializationType *Type::getAs() const;
-
-/// \brief This will check for an AttributedType by removing any existing sugar
-/// until it reaches an AttributedType or a non-sugared type.
-template <> const AttributedType *Type::getAs() const;
-
-// We can do canonical leaf types faster, because we don't have to
-// worry about preserving child type decoration.
-#define TYPE(Class, Base)
-#define LEAF_TYPE(Class) \
-template <> inline const Class##Type *Type::getAs() const { \
- return dyn_cast<Class##Type>(CanonicalType); \
-} \
-template <> inline const Class##Type *Type::castAs() const { \
- return cast<Class##Type>(CanonicalType); \
-}
-#include "clang/AST/TypeNodes.def"
-
-
-/// This class is used for builtin types like 'int'. Builtin
-/// types are always canonical and have a literal name field.
-class BuiltinType : public Type {
-public:
- enum Kind {
-#define BUILTIN_TYPE(Id, SingletonId) Id,
-#define LAST_BUILTIN_TYPE(Id) LastKind = Id
-#include "clang/AST/BuiltinTypes.def"
- };
-
-public:
- BuiltinType(Kind K)
- : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
- /*InstantiationDependent=*/(K == Dependent),
- /*VariablyModified=*/false,
- /*Unexpanded paramter pack=*/false) {
- BuiltinTypeBits.Kind = K;
- }
-
- Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); }
- StringRef getName(const PrintingPolicy &Policy) const;
- const char *getNameAsCString(const PrintingPolicy &Policy) const {
- // The StringRef is null-terminated.
- StringRef str = getName(Policy);
- assert(!str.empty() && str.data()[str.size()] == '\0');
- return str.data();
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- bool isInteger() const {
- return getKind() >= Bool && getKind() <= Int128;
- }
-
- bool isSignedInteger() const {
- return getKind() >= Char_S && getKind() <= Int128;
- }
-
- bool isUnsignedInteger() const {
- return getKind() >= Bool && getKind() <= UInt128;
- }
-
- bool isFloatingPoint() const {
- return getKind() >= Half && getKind() <= LongDouble;
- }
-
- /// Determines whether the given kind corresponds to a placeholder type.
- static bool isPlaceholderTypeKind(Kind K) {
- return K >= Overload;
- }
-
- /// Determines whether this type is a placeholder type, i.e. a type
- /// which cannot appear in arbitrary positions in a fully-formed
- /// expression.
- bool isPlaceholderType() const {
- return isPlaceholderTypeKind(getKind());
- }
-
- /// Determines whether this type is a placeholder type other than
- /// Overload. Most placeholder types require only syntactic
- /// information about their context in order to be resolved (e.g.
- /// whether it is a call expression), which means they can (and
- /// should) be resolved in an earlier "phase" of analysis.
- /// Overload expressions sometimes pick up further information
- /// from their context, like whether the context expects a
- /// specific function-pointer type, and so frequently need
- /// special treatment.
- bool isNonOverloadPlaceholderType() const {
- return getKind() > Overload;
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
-};
-
-/// Complex values, per C99 6.2.5p11. This supports the C99 complex
-/// types (_Complex float etc) as well as the GCC integer complex extensions.
-///
-class ComplexType : public Type, public llvm::FoldingSetNode {
- QualType ElementType;
- ComplexType(QualType Element, QualType CanonicalPtr) :
- Type(Complex, CanonicalPtr, Element->isDependentType(),
- Element->isInstantiationDependentType(),
- Element->isVariablyModifiedType(),
- Element->containsUnexpandedParameterPack()),
- ElementType(Element) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getElementType() const { return ElementType; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
- ID.AddPointer(Element.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
-};
-
-/// Sugar for parentheses used when specifying types.
-///
-class ParenType : public Type, public llvm::FoldingSetNode {
- QualType Inner;
-
- ParenType(QualType InnerType, QualType CanonType) :
- Type(Paren, CanonType, InnerType->isDependentType(),
- InnerType->isInstantiationDependentType(),
- InnerType->isVariablyModifiedType(),
- InnerType->containsUnexpandedParameterPack()),
- Inner(InnerType) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
-
- QualType getInnerType() const { return Inner; }
-
- bool isSugared() const { return true; }
- QualType desugar() const { return getInnerType(); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getInnerType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) {
- Inner.Profile(ID);
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Paren; }
-};
-
-/// PointerType - C99 6.7.5.1 - Pointer Declarators.
-///
-class PointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType;
-
- PointerType(QualType Pointee, QualType CanonicalPtr) :
- Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
- PointeeType(Pointee) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
-
- QualType getPointeeType() const { return PointeeType; }
-
- /// Returns true if address spaces of pointers overlap.
- /// OpenCL v2.0 defines conversion rules for pointers to different
- /// address spaces (OpenCLC v2.0 s6.5.5) and notion of overlapping
- /// address spaces.
- /// CL1.1 or CL1.2:
- /// address spaces overlap iff they are they same.
- /// CL2.0 adds:
- /// __generic overlaps with any address space except for __constant.
- bool isAddressSpaceOverlapping(const PointerType &other) const {
- Qualifiers thisQuals = PointeeType.getQualifiers();
- Qualifiers otherQuals = other.getPointeeType().getQualifiers();
- // Address spaces overlap if at least one of them is a superset of another
- return thisQuals.isAddressSpaceSupersetOf(otherQuals) ||
- otherQuals.isAddressSpaceSupersetOf(thisQuals);
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
- ID.AddPointer(Pointee.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
-};
-
-/// Represents a type which was implicitly adjusted by the semantic
-/// engine for arbitrary reasons. For example, array and function types can
-/// decay, and function types can have their calling conventions adjusted.
-class AdjustedType : public Type, public llvm::FoldingSetNode {
- QualType OriginalTy;
- QualType AdjustedTy;
-
-protected:
- AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
- QualType CanonicalPtr)
- : Type(TC, CanonicalPtr, OriginalTy->isDependentType(),
- OriginalTy->isInstantiationDependentType(),
- OriginalTy->isVariablyModifiedType(),
- OriginalTy->containsUnexpandedParameterPack()),
- OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getOriginalType() const { return OriginalTy; }
- QualType getAdjustedType() const { return AdjustedTy; }
-
- bool isSugared() const { return true; }
- QualType desugar() const { return AdjustedTy; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, OriginalTy, AdjustedTy);
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
- ID.AddPointer(Orig.getAsOpaquePtr());
- ID.AddPointer(New.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed;
- }
-};
-
-/// Represents a pointer type decayed from an array or function type.
-class DecayedType : public AdjustedType {
-
- DecayedType(QualType OriginalType, QualType DecayedPtr, QualType CanonicalPtr)
- : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
- assert(isa<PointerType>(getAdjustedType()));
- }
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getDecayedType() const { return getAdjustedType(); }
-
- QualType getPointeeType() const {
- return cast<PointerType>(getDecayedType())->getPointeeType();
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
-};
-
-/// Pointer to a block type.
-/// This type is to represent types syntactically represented as
-/// "void (^)(int)", etc. Pointee is required to always be a function type.
-///
-class BlockPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType; // Block is some kind of pointer type
- BlockPointerType(QualType Pointee, QualType CanonicalCls) :
- Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
- PointeeType(Pointee) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
-
- // Get the pointee type. Pointee is required to always be a function type.
- QualType getPointeeType() const { return PointeeType; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
- ID.AddPointer(Pointee.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == BlockPointer;
- }
-};
-
-/// Base for LValueReferenceType and RValueReferenceType
-///
-class ReferenceType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType;
-
-protected:
- ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
- bool SpelledAsLValue) :
- Type(tc, CanonicalRef, Referencee->isDependentType(),
- Referencee->isInstantiationDependentType(),
- Referencee->isVariablyModifiedType(),
- Referencee->containsUnexpandedParameterPack()),
- PointeeType(Referencee)
- {
- ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue;
- ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
- }
-
-public:
- bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; }
- bool isInnerRef() const { return ReferenceTypeBits.InnerRef; }
-
- QualType getPointeeTypeAsWritten() const { return PointeeType; }
- QualType getPointeeType() const {
- // FIXME: this might strip inner qualifiers; okay?
- const ReferenceType *T = this;
- while (T->isInnerRef())
- T = T->PointeeType->castAs<ReferenceType>();
- return T->PointeeType;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, PointeeType, isSpelledAsLValue());
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- QualType Referencee,
- bool SpelledAsLValue) {
- ID.AddPointer(Referencee.getAsOpaquePtr());
- ID.AddBoolean(SpelledAsLValue);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == LValueReference ||
- T->getTypeClass() == RValueReference;
- }
-};
-
-/// An lvalue reference type, per C++11 [dcl.ref].
-///
-class LValueReferenceType : public ReferenceType {
- LValueReferenceType(QualType Referencee, QualType CanonicalRef,
- bool SpelledAsLValue) :
- ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue)
- {}
- friend class ASTContext; // ASTContext creates these
-public:
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == LValueReference;
- }
-};
-
-/// An rvalue reference type, per C++11 [dcl.ref].
-///
-class RValueReferenceType : public ReferenceType {
- RValueReferenceType(QualType Referencee, QualType CanonicalRef) :
- ReferenceType(RValueReference, Referencee, CanonicalRef, false) {
- }
- friend class ASTContext; // ASTContext creates these
-public:
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == RValueReference;
- }
-};
-
-/// A pointer to member type per C++ 8.3.3 - Pointers to members.
-///
-/// This includes both pointers to data members and pointer to member functions.
-///
-class MemberPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType;
- /// The class of which the pointee is a member. Must ultimately be a
- /// RecordType, but could be a typedef or a template parameter too.
- const Type *Class;
-
- MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
- Type(MemberPointer, CanonicalPtr,
- Cls->isDependentType() || Pointee->isDependentType(),
- (Cls->isInstantiationDependentType() ||
- Pointee->isInstantiationDependentType()),
- Pointee->isVariablyModifiedType(),
- (Cls->containsUnexpandedParameterPack() ||
- Pointee->containsUnexpandedParameterPack())),
- PointeeType(Pointee), Class(Cls) {
- }
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getPointeeType() const { return PointeeType; }
-
- /// Returns true if the member type (i.e. the pointee type) is a
- /// function type rather than a data-member type.
- bool isMemberFunctionPointer() const {
- return PointeeType->isFunctionProtoType();
- }
-
- /// Returns true if the member type (i.e. the pointee type) is a
- /// data type rather than a function type.
- bool isMemberDataPointer() const {
- return !PointeeType->isFunctionProtoType();
- }
-
- const Type *getClass() const { return Class; }
- CXXRecordDecl *getMostRecentCXXRecordDecl() const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType(), getClass());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
- const Type *Class) {
- ID.AddPointer(Pointee.getAsOpaquePtr());
- ID.AddPointer(Class);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == MemberPointer;
- }
-};
-
-/// Represents an array type, per C99 6.7.5.2 - Array Declarators.
-///
-class ArrayType : public Type, public llvm::FoldingSetNode {
-public:
- /// Capture whether this is a normal array (e.g. int X[4])
- /// an array with a static size (e.g. int X[static 4]), or an array
- /// with a star size (e.g. int X[*]).
- /// 'static' is only allowed on function parameters.
- enum ArraySizeModifier {
- Normal, Static, Star
- };
-private:
- /// The element type of the array.
- QualType ElementType;
-
-protected:
- // 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;
- }
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getElementType() const { return ElementType; }
- ArraySizeModifier getSizeModifier() const {
- return ArraySizeModifier(ArrayTypeBits.SizeModifier);
- }
- Qualifiers getIndexTypeQualifiers() const {
- return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers());
- }
- unsigned getIndexTypeCVRQualifiers() const {
- return ArrayTypeBits.IndexTypeQuals;
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArray ||
- T->getTypeClass() == VariableArray ||
- T->getTypeClass() == IncompleteArray ||
- T->getTypeClass() == DependentSizedArray;
- }
-};
-
-/// 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 {
- 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:
- 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) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- const llvm::APInt &getSize() const { return Size; }
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
-
- /// \brief Determine the number of bits required to address a member of
- // an array with the given element type and number of elements.
- static unsigned getNumAddressingBits(ASTContext &Context,
- QualType ElementType,
- const llvm::APInt &NumElements);
-
- /// \brief Determine the maximum number of active bits that an array's size
- /// can require, which limits the maximum size of the array.
- static unsigned getMaxSizeBits(ASTContext &Context);
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getSize(),
- 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 bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArray;
- }
-};
-
-/// Represents a C array with an unspecified size. For example 'int A[]' has
-/// an IncompleteArrayType where the element type is 'int' and the size is
-/// unspecified.
-class IncompleteArrayType : public ArrayType {
-
- IncompleteArrayType(QualType et, QualType can,
- ArraySizeModifier sm, unsigned tq)
- : ArrayType(IncompleteArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == IncompleteArray;
- }
-
- friend class StmtIteratorBase;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getSizeModifier(),
- getIndexTypeCVRQualifiers());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
- ArraySizeModifier SizeMod, unsigned TypeQuals) {
- ID.AddPointer(ET.getAsOpaquePtr());
- ID.AddInteger(SizeMod);
- ID.AddInteger(TypeQuals);
- }
-};
-
-/// Represents a C array with a specified size that is not an
-/// integer-constant-expression. For example, 'int s[x+foo()]'.
-/// Since the size expression is an arbitrary expression, we store it as such.
-///
-/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and
-/// should not be: two lexically equivalent variable array types could mean
-/// different things, for example, these variables do not have the same type
-/// dynamically:
-///
-/// void foo(int x) {
-/// int Y[x];
-/// ++x;
-/// int Z[x];
-/// }
-///
-class VariableArrayType : public ArrayType {
- /// An assignment-expression. VLA's are only permitted within
- /// a function block.
- Stmt *SizeExpr;
- /// The range spanned by the left and right array brackets.
- SourceRange Brackets;
-
- VariableArrayType(QualType et, QualType can, Expr *e,
- ArraySizeModifier sm, unsigned tq,
- SourceRange brackets)
- : ArrayType(VariableArray, et, can, sm, tq,
- et->containsUnexpandedParameterPack()),
- SizeExpr((Stmt*) e), Brackets(brackets) {}
- friend class ASTContext; // ASTContext creates these.
-
-public:
- Expr *getSizeExpr() const {
- // We use C-style casts instead of cast<> here because we do not wish
- // to have a dependency of Type.h on Stmt.h/Expr.h.
- return (Expr*) SizeExpr;
- }
- SourceRange getBracketsRange() const { return Brackets; }
- SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
- SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == VariableArray;
- }
-
- friend class StmtIteratorBase;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- llvm_unreachable("Cannot unique VariableArrayTypes.");
- }
-};
-
-/// Represents an array type in C++ whose size is a value-dependent expression.
-///
-/// For example:
-/// \code
-/// template<typename T, int Size>
-/// class array {
-/// T data[Size];
-/// };
-/// \endcode
-///
-/// For these types, we won't actually know what the array bound is
-/// until template instantiation occurs, at which point this will
-/// become either a ConstantArrayType or a VariableArrayType.
-class DependentSizedArrayType : public ArrayType {
- const ASTContext &Context;
-
- /// \brief An assignment expression that will instantiate to the
- /// size of the array.
- ///
- /// The expression itself might be null, in which case the array
- /// type will have its size deduced from an initializer.
- Stmt *SizeExpr;
-
- /// The range spanned by the left and right array brackets.
- SourceRange Brackets;
-
- DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can,
- Expr *e, ArraySizeModifier sm, unsigned tq,
- SourceRange brackets);
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- Expr *getSizeExpr() const {
- // We use C-style casts instead of cast<> here because we do not wish
- // to have a dependency of Type.h on Stmt.h/Expr.h.
- return (Expr*) SizeExpr;
- }
- SourceRange getBracketsRange() const { return Brackets; }
- SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
- SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentSizedArray;
- }
-
- friend class StmtIteratorBase;
-
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getElementType(),
- getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- QualType ET, ArraySizeModifier SizeMod,
- unsigned TypeQuals, Expr *E);
-};
-
-/// Represents an extended vector type where either the type or size is
-/// dependent.
-///
-/// For example:
-/// \code
-/// template<typename T, int Size>
-/// class vector {
-/// typedef T __attribute__((ext_vector_type(Size))) type;
-/// }
-/// \endcode
-class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
- const ASTContext &Context;
- Expr *SizeExpr;
- /// The element type of the array.
- QualType ElementType;
- SourceLocation loc;
-
- DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType,
- QualType can, Expr *SizeExpr, SourceLocation loc);
-
- friend class ASTContext;
-
-public:
- Expr *getSizeExpr() const { return SizeExpr; }
- QualType getElementType() const { return ElementType; }
- SourceLocation getAttributeLoc() const { return loc; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentSizedExtVector;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getElementType(), getSizeExpr());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- QualType ElementType, Expr *SizeExpr);
-};
-
-
-/// Represents a GCC generic vector type. This type is created using
-/// __attribute__((vector_size(n)), where "n" specifies the vector size in
-/// bytes; or from an Altivec __vector or vector declaration.
-/// Since the constructor takes the number of vector elements, the
-/// client is responsible for converting the size into the number of elements.
-class VectorType : public Type, public llvm::FoldingSetNode {
-public:
- enum VectorKind {
- GenericVector, ///< not a target-specific vector type
- AltiVecVector, ///< is AltiVec vector
- AltiVecPixel, ///< is AltiVec 'vector Pixel'
- AltiVecBool, ///< is AltiVec 'vector bool ...'
- NeonVector, ///< is ARM Neon vector
- NeonPolyVector ///< is ARM Neon polynomial vector
- };
-protected:
- /// The element type of the vector.
- QualType ElementType;
-
- VectorType(QualType vecType, unsigned nElements, QualType canonType,
- VectorKind vecKind);
-
- VectorType(TypeClass tc, QualType vecType, unsigned nElements,
- QualType canonType, VectorKind vecKind);
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
-
- QualType getElementType() const { return ElementType; }
- unsigned getNumElements() const { return VectorTypeBits.NumElements; }
- static bool isVectorSizeTooLarge(unsigned NumElements) {
- return NumElements > VectorTypeBitfields::MaxNumElements;
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- VectorKind getVectorKind() const {
- return VectorKind(VectorTypeBits.VecKind);
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getNumElements(),
- getTypeClass(), getVectorKind());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
- unsigned NumElements, TypeClass TypeClass,
- VectorKind VecKind) {
- ID.AddPointer(ElementType.getAsOpaquePtr());
- ID.AddInteger(NumElements);
- ID.AddInteger(TypeClass);
- ID.AddInteger(VecKind);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
- }
-};
-
-/// ExtVectorType - Extended vector type. This type is created using
-/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
-/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
-/// class enables syntactic extensions, like Vector Components for accessing
-/// points, colors, and textures (modeled after OpenGL Shading Language).
-class ExtVectorType : public VectorType {
- ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
- VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
- friend class ASTContext; // ASTContext creates these.
-public:
- static int getPointAccessorIdx(char c) {
- switch (c) {
- default: return -1;
- case 'x': return 0;
- case 'y': return 1;
- case 'z': return 2;
- case 'w': return 3;
- }
- }
- static int getNumericAccessorIdx(char c) {
- switch (c) {
- default: return -1;
- case '0': return 0;
- case '1': return 1;
- case '2': return 2;
- case '3': return 3;
- case '4': return 4;
- case '5': return 5;
- case '6': return 6;
- case '7': return 7;
- case '8': return 8;
- case '9': return 9;
- case 'A':
- case 'a': return 10;
- case 'B':
- case 'b': return 11;
- case 'C':
- case 'c': return 12;
- case 'D':
- case 'd': return 13;
- case 'E':
- case 'e': return 14;
- case 'F':
- case 'f': return 15;
- }
- }
-
- static int getAccessorIdx(char c) {
- if (int idx = getPointAccessorIdx(c)+1) return idx-1;
- return getNumericAccessorIdx(c);
- }
-
- bool isAccessorWithinNumElements(char c) const {
- if (int idx = getAccessorIdx(c)+1)
- return unsigned(idx-1) < getNumElements();
- return false;
- }
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ExtVector;
- }
-};
-
-/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
-/// class of FunctionNoProtoType and FunctionProtoType.
-///
-class FunctionType : public Type {
- // The type returned by the function.
- QualType ResultType;
-
- public:
- /// A class which abstracts out some details necessary for
- /// making a call.
- ///
- /// It is not actually used directly for storing this information in
- /// a FunctionType, although FunctionType does currently use the
- /// same bit-pattern.
- ///
- // If you add a field (say Foo), other than the obvious places (both,
- // constructors, compile failures), what you need to update is
- // * Operator==
- // * getFoo
- // * withFoo
- // * functionType. Add Foo, getFoo.
- // * ASTContext::getFooType
- // * ASTContext::mergeFunctionTypes
- // * FunctionNoProtoType::Profile
- // * FunctionProtoType::Profile
- // * TypePrinter::PrintFunctionProto
- // * AST read and write
- // * Codegen
- class ExtInfo {
- // Feel free to rearrange or add bits, but if you go over 9,
- // you'll need to adjust both the Bits field below and
- // Type::FunctionTypeBitfields.
-
- // | CC |noreturn|produces|regparm|
- // |0 .. 3| 4 | 5 | 6 .. 8|
- //
- // regparm is either 0 (no regparm attribute) or the regparm value+1.
- enum { CallConvMask = 0xF };
- enum { NoReturnMask = 0x10 };
- enum { ProducesResultMask = 0x20 };
- enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask),
- RegParmOffset = 6 }; // Assumed to be the last field
-
- uint16_t Bits;
-
- ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
-
- friend class FunctionType;
-
- public:
- // Constructor with no defaults. Use this when you know that you
- // have all the elements (when reading an AST file for example).
- ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
- bool producesResult) {
- assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
- Bits = ((unsigned) cc) |
- (noReturn ? NoReturnMask : 0) |
- (producesResult ? ProducesResultMask : 0) |
- (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0);
- }
-
- // Constructor with all defaults. Use when for example creating a
- // function known to use defaults.
- ExtInfo() : Bits(CC_C) { }
-
- // Constructor with just the calling convention, which is an important part
- // of the canonical type.
- ExtInfo(CallingConv CC) : Bits(CC) { }
-
- bool getNoReturn() const { return Bits & NoReturnMask; }
- bool getProducesResult() const { return Bits & ProducesResultMask; }
- bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
- unsigned getRegParm() const {
- unsigned RegParm = Bits >> RegParmOffset;
- if (RegParm > 0)
- --RegParm;
- return RegParm;
- }
- CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
-
- bool operator==(ExtInfo Other) const {
- return Bits == Other.Bits;
- }
- bool operator!=(ExtInfo Other) const {
- return Bits != Other.Bits;
- }
-
- // Note that we don't have setters. That is by design, use
- // the following with methods instead of mutating these objects.
-
- ExtInfo withNoReturn(bool noReturn) const {
- if (noReturn)
- return ExtInfo(Bits | NoReturnMask);
- else
- return ExtInfo(Bits & ~NoReturnMask);
- }
-
- ExtInfo withProducesResult(bool producesResult) const {
- if (producesResult)
- return ExtInfo(Bits | ProducesResultMask);
- else
- return ExtInfo(Bits & ~ProducesResultMask);
- }
-
- ExtInfo withRegParm(unsigned RegParm) const {
- assert(RegParm < 7 && "Invalid regparm value");
- return ExtInfo((Bits & ~RegParmMask) |
- ((RegParm + 1) << RegParmOffset));
- }
-
- ExtInfo withCallingConv(CallingConv cc) const {
- return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc);
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger(Bits);
- }
- };
-
-protected:
- FunctionType(TypeClass tc, QualType res,
- QualType Canonical, bool Dependent,
- bool InstantiationDependent,
- bool VariablyModified, bool ContainsUnexpandedParameterPack,
- ExtInfo Info)
- : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
- ContainsUnexpandedParameterPack),
- ResultType(res) {
- FunctionTypeBits.ExtInfo = Info.Bits;
- }
- unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
-
-public:
- QualType getReturnType() const { return ResultType; }
-
- bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
- unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
- /// Determine whether this function type includes the GNU noreturn
- /// attribute. The C++11 [[noreturn]] attribute does not affect the function
- /// type.
- bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
- CallingConv getCallConv() const { return getExtInfo().getCC(); }
- ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
- bool isConst() const { return getTypeQuals() & Qualifiers::Const; }
- bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; }
- bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; }
-
- /// \brief Determine the type of an expression that calls a function of
- /// this type.
- QualType getCallResultType(ASTContext &Context) const {
- return getReturnType().getNonLValueExprType(Context);
- }
-
- static StringRef getNameForCallConv(CallingConv CC);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == FunctionNoProto ||
- T->getTypeClass() == FunctionProto;
- }
-};
-
-/// Represents a K&R-style 'int foo()' function, which has
-/// no information available about its arguments.
-class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
- FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
- : FunctionType(FunctionNoProto, Result, Canonical,
- /*Dependent=*/false, /*InstantiationDependent=*/false,
- Result->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false, Info) {}
-
- friend class ASTContext; // ASTContext creates these.
-
-public:
- // No additional state past what FunctionType provides.
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReturnType(), getExtInfo());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
- ExtInfo Info) {
- Info.Profile(ID);
- ID.AddPointer(ResultType.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == FunctionNoProto;
- }
-};
-
-/// Represents a prototype with parameter type info, e.g.
-/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
-/// parameters, not as having a single void parameter. Such a type can have an
-/// exception specification, but this specification is not part of the canonical
-/// type.
-class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
-public:
- struct ExceptionSpecInfo {
- ExceptionSpecInfo()
- : Type(EST_None), NoexceptExpr(nullptr),
- SourceDecl(nullptr), SourceTemplate(nullptr) {}
-
- ExceptionSpecInfo(ExceptionSpecificationType EST)
- : Type(EST), NoexceptExpr(nullptr), SourceDecl(nullptr),
- SourceTemplate(nullptr) {}
-
- /// The kind of exception specification this is.
- ExceptionSpecificationType Type;
- /// Explicitly-specified list of exception types.
- ArrayRef<QualType> Exceptions;
- /// Noexcept expression, if this is EST_ComputedNoexcept.
- Expr *NoexceptExpr;
- /// The function whose exception specification this is, for
- /// EST_Unevaluated and EST_Uninstantiated.
- FunctionDecl *SourceDecl;
- /// The function template whose exception specification this is instantiated
- /// from, for EST_Uninstantiated.
- FunctionDecl *SourceTemplate;
- };
-
- /// Extra information about a function prototype.
- struct ExtProtoInfo {
- ExtProtoInfo()
- : Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- RefQualifier(RQ_None), ConsumedParameters(nullptr) {}
-
- ExtProtoInfo(CallingConv CC)
- : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0),
- RefQualifier(RQ_None), ConsumedParameters(nullptr) {}
-
- ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) {
- ExtProtoInfo Result(*this);
- Result.ExceptionSpec = O;
- return Result;
- }
-
- FunctionType::ExtInfo ExtInfo;
- bool Variadic : 1;
- bool HasTrailingReturn : 1;
- unsigned char TypeQuals;
- RefQualifierKind RefQualifier;
- ExceptionSpecInfo ExceptionSpec;
- const bool *ConsumedParameters;
- };
-
-private:
- /// \brief Determine whether there are any argument types that
- /// contain an unexpanded parameter pack.
- static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray,
- unsigned numArgs) {
- for (unsigned Idx = 0; Idx < numArgs; ++Idx)
- if (ArgArray[Idx]->containsUnexpandedParameterPack())
- return true;
-
- return false;
- }
-
- FunctionProtoType(QualType result, ArrayRef<QualType> params,
- QualType canonical, const ExtProtoInfo &epi);
-
- /// The number of parameters this function has, not counting '...'.
- unsigned NumParams : 15;
-
- /// The number of types in the exception spec, if any.
- unsigned NumExceptions : 9;
-
- /// The type of exception specification this function has.
- unsigned ExceptionSpecType : 4;
-
- /// Whether this function has any consumed parameters.
- unsigned HasAnyConsumedParams : 1;
-
- /// Whether the function is variadic.
- unsigned Variadic : 1;
-
- /// Whether this function has a trailing return type.
- unsigned HasTrailingReturn : 1;
-
- // ParamInfo - There is an variable size array after the class in memory that
- // holds the parameter types.
-
- // Exceptions - There is another variable size array after ArgInfo that
- // holds the exception types.
-
- // NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing
- // to the expression in the noexcept() specifier.
-
- // ExceptionSpecDecl, ExceptionSpecTemplate - Instead of Exceptions, there may
- // be a pair of FunctionDecl* pointing to the function which should be used to
- // instantiate this function type's exception specification, and the function
- // from which it should be instantiated.
-
- // ConsumedParameters - A variable size array, following Exceptions
- // and of length NumParams, holding flags indicating which parameters
- // are consumed. This only appears if HasAnyConsumedParams is true.
-
- friend class ASTContext; // ASTContext creates these.
-
- const bool *getConsumedParamsBuffer() const {
- assert(hasAnyConsumedParams());
-
- // Find the end of the exceptions.
- Expr *const *eh_end = reinterpret_cast<Expr *const *>(exception_end());
- if (getExceptionSpecType() == EST_ComputedNoexcept)
- eh_end += 1; // NoexceptExpr
- // The memory layout of these types isn't handled here, so
- // hopefully this is never called for them?
- assert(getExceptionSpecType() != EST_Uninstantiated &&
- getExceptionSpecType() != EST_Unevaluated);
-
- return reinterpret_cast<const bool*>(eh_end);
- }
-
-public:
- unsigned getNumParams() const { return NumParams; }
- QualType getParamType(unsigned i) const {
- assert(i < NumParams && "invalid parameter index");
- return param_type_begin()[i];
- }
- ArrayRef<QualType> getParamTypes() const {
- return llvm::makeArrayRef(param_type_begin(), param_type_end());
- }
-
- ExtProtoInfo getExtProtoInfo() const {
- ExtProtoInfo EPI;
- EPI.ExtInfo = getExtInfo();
- EPI.Variadic = isVariadic();
- EPI.HasTrailingReturn = hasTrailingReturn();
- EPI.ExceptionSpec.Type = getExceptionSpecType();
- EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
- EPI.RefQualifier = getRefQualifier();
- if (EPI.ExceptionSpec.Type == EST_Dynamic) {
- EPI.ExceptionSpec.Exceptions = exceptions();
- } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) {
- EPI.ExceptionSpec.NoexceptExpr = getNoexceptExpr();
- } else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) {
- EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
- EPI.ExceptionSpec.SourceTemplate = getExceptionSpecTemplate();
- } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) {
- EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl();
- }
- if (hasAnyConsumedParams())
- EPI.ConsumedParameters = getConsumedParamsBuffer();
- return EPI;
- }
-
- /// Get the kind of exception specification on this function.
- ExceptionSpecificationType getExceptionSpecType() const {
- return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
- }
- /// Return whether this function has any kind of exception spec.
- bool hasExceptionSpec() const {
- return getExceptionSpecType() != EST_None;
- }
- /// Return whether this function has a dynamic (throw) exception spec.
- bool hasDynamicExceptionSpec() const {
- return isDynamicExceptionSpec(getExceptionSpecType());
- }
- /// Return whether this function has a noexcept exception spec.
- bool hasNoexceptExceptionSpec() const {
- return isNoexceptExceptionSpec(getExceptionSpecType());
- }
- /// Return whether this function has a dependent exception spec.
- bool hasDependentExceptionSpec() const;
- /// Result type of getNoexceptSpec().
- enum NoexceptResult {
- NR_NoNoexcept, ///< There is no noexcept specifier.
- NR_BadNoexcept, ///< The noexcept specifier has a bad expression.
- NR_Dependent, ///< The noexcept specifier is dependent.
- NR_Throw, ///< The noexcept specifier evaluates to false.
- NR_Nothrow ///< The noexcept specifier evaluates to true.
- };
- /// Get the meaning of the noexcept spec on this function, if any.
- NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const;
- unsigned getNumExceptions() const { return NumExceptions; }
- QualType getExceptionType(unsigned i) const {
- assert(i < NumExceptions && "Invalid exception number!");
- return exception_begin()[i];
- }
- Expr *getNoexceptExpr() const {
- if (getExceptionSpecType() != EST_ComputedNoexcept)
- return nullptr;
- // NoexceptExpr sits where the arguments end.
- return *reinterpret_cast<Expr *const *>(param_type_end());
- }
- /// \brief If this function type has an exception specification which hasn't
- /// been determined yet (either because it has not been evaluated or because
- /// it has not been instantiated), this is the function whose exception
- /// specification is represented by this type.
- FunctionDecl *getExceptionSpecDecl() const {
- if (getExceptionSpecType() != EST_Uninstantiated &&
- getExceptionSpecType() != EST_Unevaluated)
- return nullptr;
- return reinterpret_cast<FunctionDecl *const *>(param_type_end())[0];
- }
- /// \brief If this function type has an uninstantiated exception
- /// specification, this is the function whose exception specification
- /// should be instantiated to find the exception specification for
- /// this type.
- FunctionDecl *getExceptionSpecTemplate() const {
- if (getExceptionSpecType() != EST_Uninstantiated)
- return nullptr;
- return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
- }
- /// Determine whether this function type has a non-throwing exception
- /// specification. If this depends on template arguments, returns
- /// \c ResultIfDependent.
- bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const;
-
- bool isVariadic() const { return Variadic; }
-
- /// Determines whether this function prototype contains a
- /// parameter pack at the end.
- ///
- /// A function template whose last parameter is a parameter pack can be
- /// called with an arbitrary number of arguments, much like a variadic
- /// function.
- bool isTemplateVariadic() const;
-
- bool hasTrailingReturn() const { return HasTrailingReturn; }
-
- unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
-
-
- /// Retrieve the ref-qualifier associated with this function type.
- RefQualifierKind getRefQualifier() const {
- return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier);
- }
-
- typedef const QualType *param_type_iterator;
- typedef llvm::iterator_range<param_type_iterator> param_type_range;
-
- param_type_range param_types() const {
- return param_type_range(param_type_begin(), param_type_end());
- }
- param_type_iterator param_type_begin() const {
- return reinterpret_cast<const QualType *>(this+1);
- }
- param_type_iterator param_type_end() const {
- return param_type_begin() + NumParams;
- }
-
- typedef const QualType *exception_iterator;
-
- ArrayRef<QualType> exceptions() const {
- return llvm::makeArrayRef(exception_begin(), exception_end());
- }
- exception_iterator exception_begin() const {
- // exceptions begin where arguments end
- return param_type_end();
- }
- exception_iterator exception_end() const {
- if (getExceptionSpecType() != EST_Dynamic)
- return exception_begin();
- return exception_begin() + NumExceptions;
- }
-
- bool hasAnyConsumedParams() const { return HasAnyConsumedParams; }
- bool isParamConsumed(unsigned I) const {
- assert(I < getNumParams() && "parameter index out of range");
- if (hasAnyConsumedParams())
- return getConsumedParamsBuffer()[I];
- return false;
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void printExceptionSpecification(raw_ostream &OS,
- const PrintingPolicy &Policy) const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == FunctionProto;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
- param_type_iterator ArgTys, unsigned NumArgs,
- const ExtProtoInfo &EPI, const ASTContext &Context);
-};
-
-/// \brief Represents the dependent type named by a dependently-scoped
-/// typename using declaration, e.g.
-/// using typename Base<T>::foo;
-///
-/// Template instantiation turns these into the underlying type.
-class UnresolvedUsingType : public Type {
- UnresolvedUsingTypenameDecl *Decl;
-
- UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
- : Type(UnresolvedUsing, QualType(), true, true, false,
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
- friend class ASTContext; // ASTContext creates these.
-public:
-
- UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == UnresolvedUsing;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- return Profile(ID, Decl);
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- UnresolvedUsingTypenameDecl *D) {
- ID.AddPointer(D);
- }
-};
-
-
-class TypedefType : public Type {
- TypedefNameDecl *Decl;
-protected:
- TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
- : Type(tc, can, can->isDependentType(),
- can->isInstantiationDependentType(),
- can->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(const_cast<TypedefNameDecl*>(D)) {
- assert(!isa<TypedefType>(can) && "Invalid canonical type");
- }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- TypedefNameDecl *getDecl() const { return Decl; }
-
- bool isSugared() const { return true; }
- QualType desugar() const;
-
- static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
-};
-
-/// Represents a `typeof` (or __typeof__) expression (a GCC extension).
-class TypeOfExprType : public Type {
- Expr *TOExpr;
-
-protected:
- TypeOfExprType(Expr *E, QualType can = QualType());
- friend class ASTContext; // ASTContext creates these.
-public:
- Expr *getUnderlyingExpr() const { return TOExpr; }
-
- /// \brief Remove a single level of sugar.
- QualType desugar() const;
-
- /// \brief Returns whether this type directly provides sugar.
- bool isSugared() const;
-
- static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
-};
-
-/// \brief Internal representation of canonical, dependent
-/// `typeof(expr)` types.
-///
-/// This class is used internally by the ASTContext to manage
-/// canonical, dependent types, only. Clients will only see instances
-/// of this class via TypeOfExprType nodes.
-class DependentTypeOfExprType
- : public TypeOfExprType, public llvm::FoldingSetNode {
- const ASTContext &Context;
-
-public:
- DependentTypeOfExprType(const ASTContext &Context, Expr *E)
- : TypeOfExprType(E), Context(Context) { }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getUnderlyingExpr());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- Expr *E);
-};
-
-/// Represents `typeof(type)`, a GCC extension.
-class TypeOfType : public Type {
- QualType TOType;
- TypeOfType(QualType T, QualType can)
- : Type(TypeOf, can, T->isDependentType(),
- T->isInstantiationDependentType(),
- T->isVariablyModifiedType(),
- T->containsUnexpandedParameterPack()),
- TOType(T) {
- assert(!isa<TypedefType>(can) && "Invalid canonical type");
- }
- friend class ASTContext; // ASTContext creates these.
-public:
- QualType getUnderlyingType() const { return TOType; }
-
- /// \brief Remove a single level of sugar.
- QualType desugar() const { return getUnderlyingType(); }
-
- /// \brief Returns whether this type directly provides sugar.
- bool isSugared() const { return true; }
-
- static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
-};
-
-/// Represents the type `decltype(expr)` (C++11).
-class DecltypeType : public Type {
- Expr *E;
- QualType UnderlyingType;
-
-protected:
- DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
- friend class ASTContext; // ASTContext creates these.
-public:
- Expr *getUnderlyingExpr() const { return E; }
- QualType getUnderlyingType() const { return UnderlyingType; }
-
- /// \brief Remove a single level of sugar.
- QualType desugar() const;
-
- /// \brief Returns whether this type directly provides sugar.
- bool isSugared() const;
-
- static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
-};
-
-/// \brief Internal representation of canonical, dependent
-/// decltype(expr) types.
-///
-/// This class is used internally by the ASTContext to manage
-/// canonical, dependent types, only. Clients will only see instances
-/// of this class via DecltypeType nodes.
-class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
- const ASTContext &Context;
-
-public:
- DependentDecltypeType(const ASTContext &Context, Expr *E);
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getUnderlyingExpr());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- Expr *E);
-};
-
-/// A unary type transform, which is a type constructed from another.
-class UnaryTransformType : public Type {
-public:
- enum UTTKind {
- EnumUnderlyingType
- };
-
-private:
- /// The untransformed type.
- QualType BaseType;
- /// The transformed type if not dependent, otherwise the same as BaseType.
- QualType UnderlyingType;
-
- UTTKind UKind;
-protected:
- UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind,
- QualType CanonicalTy);
- friend class ASTContext;
-public:
- bool isSugared() const { return !isDependentType(); }
- QualType desugar() const { return UnderlyingType; }
-
- QualType getUnderlyingType() const { return UnderlyingType; }
- QualType getBaseType() const { return BaseType; }
-
- UTTKind getUTTKind() const { return UKind; }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == UnaryTransform;
- }
-};
-
-class TagType : public Type {
- /// Stores the TagDecl associated with this type. The decl may point to any
- /// TagDecl that declares the entity.
- TagDecl * decl;
-
- friend class ASTReader;
-
-protected:
- TagType(TypeClass TC, const TagDecl *D, QualType can);
-
-public:
- TagDecl *getDecl() const;
-
- /// Determines whether this type is in the process of being defined.
- bool isBeingDefined() const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
- }
-};
-
-/// A helper class that allows the use of isa/cast/dyncast
-/// to detect TagType objects of structs/unions/classes.
-class RecordType : public TagType {
-protected:
- explicit RecordType(const RecordDecl *D)
- : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { }
- explicit RecordType(TypeClass TC, RecordDecl *D)
- : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- RecordDecl *getDecl() const {
- return reinterpret_cast<RecordDecl*>(TagType::getDecl());
- }
-
- // FIXME: This predicate is a helper to QualType/Type. It needs to
- // recursively check all fields for const-ness. If any field is declared
- // const, it needs to return false.
- bool hasConstFields() const { return false; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Record; }
-};
-
-/// A helper class that allows the use of isa/cast/dyncast
-/// to detect TagType objects of enums.
-class EnumType : public TagType {
- explicit EnumType(const EnumDecl *D)
- : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { }
- friend class ASTContext; // ASTContext creates these.
-public:
-
- EnumDecl *getDecl() const {
- return reinterpret_cast<EnumDecl*>(TagType::getDecl());
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
-};
-
-/// An attributed type is a type to which a type attribute has been applied.
-///
-/// The "modified type" is the fully-sugared type to which the attributed
-/// type was applied; generally it is not canonically equivalent to the
-/// attributed type. The "equivalent type" is the minimally-desugared type
-/// which the type is canonically equivalent to.
-///
-/// For example, in the following attributed type:
-/// int32_t __attribute__((vector_size(16)))
-/// - the modified type is the TypedefType for int32_t
-/// - the equivalent type is VectorType(16, int32_t)
-/// - the canonical type is VectorType(16, int)
-class AttributedType : public Type, public llvm::FoldingSetNode {
-public:
- // It is really silly to have yet another attribute-kind enum, but
- // clang::attr::Kind doesn't currently cover the pure type attrs.
- enum Kind {
- // Expression operand.
- attr_address_space,
- attr_regparm,
- attr_vector_size,
- attr_neon_vector_type,
- attr_neon_polyvector_type,
-
- FirstExprOperandKind = attr_address_space,
- LastExprOperandKind = attr_neon_polyvector_type,
-
- // Enumerated operand (string or keyword).
- attr_objc_gc,
- attr_objc_ownership,
- attr_pcs,
- attr_pcs_vfp,
-
- FirstEnumOperandKind = attr_objc_gc,
- LastEnumOperandKind = attr_pcs_vfp,
-
- // No operand.
- attr_noreturn,
- attr_cdecl,
- attr_fastcall,
- attr_stdcall,
- attr_thiscall,
- attr_pascal,
- attr_vectorcall,
- attr_inteloclbicc,
- attr_ms_abi,
- attr_sysv_abi,
- attr_ptr32,
- attr_ptr64,
- attr_sptr,
- attr_uptr,
- attr_nonnull,
- attr_nullable,
- attr_null_unspecified,
- attr_objc_kindof,
- attr_objc_inert_unsafe_unretained,
- };
-
-private:
- QualType ModifiedType;
- QualType EquivalentType;
-
- friend class ASTContext; // creates these
-
- AttributedType(QualType canon, Kind attrKind,
- QualType modified, QualType equivalent)
- : Type(Attributed, canon, canon->isDependentType(),
- canon->isInstantiationDependentType(),
- canon->isVariablyModifiedType(),
- canon->containsUnexpandedParameterPack()),
- ModifiedType(modified), EquivalentType(equivalent) {
- AttributedTypeBits.AttrKind = attrKind;
- }
-
-public:
- Kind getAttrKind() const {
- return static_cast<Kind>(AttributedTypeBits.AttrKind);
- }
-
- QualType getModifiedType() const { return ModifiedType; }
- QualType getEquivalentType() const { return EquivalentType; }
-
- bool isSugared() const { return true; }
- QualType desugar() const { return getEquivalentType(); }
-
- /// Does this attribute behave like a type qualifier?
- ///
- /// A type qualifier adjusts a type to provide specialized rules for
- /// a specific object, like the standard const and volatile qualifiers.
- /// This includes attributes controlling things like nullability,
- /// address spaces, and ARC ownership. The value of the object is still
- /// largely described by the modified type.
- ///
- /// In contrast, many type attributes "rewrite" their modified type to
- /// produce a fundamentally different type, not necessarily related in any
- /// formalizable way to the original type. For example, calling convention
- /// and vector attributes are not simple type qualifiers.
- ///
- /// Type qualifiers are often, but not always, reflected in the canonical
- /// type.
- bool isQualifier() const;
-
- bool isMSTypeSpec() const;
-
- bool isCallingConv() const;
-
- llvm::Optional<NullabilityKind> getImmediateNullability() const;
-
- /// Retrieve the attribute kind corresponding to the given
- /// nullability kind.
- static Kind getNullabilityAttrKind(NullabilityKind kind) {
- switch (kind) {
- case NullabilityKind::NonNull:
- return attr_nonnull;
-
- case NullabilityKind::Nullable:
- return attr_nullable;
-
- case NullabilityKind::Unspecified:
- return attr_null_unspecified;
- }
- llvm_unreachable("Unknown nullability kind.");
- }
-
- /// Strip off the top-level nullability annotation on the given
- /// type, if it's there.
- ///
- /// \param T The type to strip. If the type is exactly an
- /// AttributedType specifying nullability (without looking through
- /// type sugar), the nullability is returned and this type changed
- /// to the underlying modified type.
- ///
- /// \returns the top-level nullability, if present.
- static Optional<NullabilityKind> stripOuterNullability(QualType &T);
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
- QualType modified, QualType equivalent) {
- ID.AddInteger(attrKind);
- ID.AddPointer(modified.getAsOpaquePtr());
- ID.AddPointer(equivalent.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Attributed;
- }
-};
-
-class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
- // Helper data collector for canonical types.
- struct CanonicalTTPTInfo {
- unsigned Depth : 15;
- unsigned ParameterPack : 1;
- unsigned Index : 16;
- };
-
- union {
- // Info for the canonical type.
- CanonicalTTPTInfo CanTTPTInfo;
- // Info for the non-canonical type.
- TemplateTypeParmDecl *TTPDecl;
- };
-
- /// Build a non-canonical type.
- TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
- : Type(TemplateTypeParm, Canon, /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- Canon->containsUnexpandedParameterPack()),
- TTPDecl(TTPDecl) { }
-
- /// Build the canonical type.
- TemplateTypeParmType(unsigned D, unsigned I, bool PP)
- : Type(TemplateTypeParm, QualType(this, 0),
- /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false, PP) {
- CanTTPTInfo.Depth = D;
- CanTTPTInfo.Index = I;
- CanTTPTInfo.ParameterPack = PP;
- }
-
- friend class ASTContext; // ASTContext creates these
-
- const CanonicalTTPTInfo& getCanTTPTInfo() const {
- QualType Can = getCanonicalTypeInternal();
- return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo;
- }
-
-public:
- unsigned getDepth() const { return getCanTTPTInfo().Depth; }
- unsigned getIndex() const { return getCanTTPTInfo().Index; }
- bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
-
- TemplateTypeParmDecl *getDecl() const {
- return isCanonicalUnqualified() ? nullptr : TTPDecl;
- }
-
- IdentifierInfo *getIdentifier() const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
- unsigned Index, bool ParameterPack,
- TemplateTypeParmDecl *TTPDecl) {
- ID.AddInteger(Depth);
- ID.AddInteger(Index);
- ID.AddBoolean(ParameterPack);
- ID.AddPointer(TTPDecl);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == TemplateTypeParm;
- }
-};
-
-/// \brief Represents the result of substituting a type for a template
-/// type parameter.
-///
-/// Within an instantiated template, all template type parameters have
-/// been replaced with these. They are used solely to record that a
-/// type was originally written as a template type parameter;
-/// therefore they are never canonical.
-class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
- // The original type parameter.
- const TemplateTypeParmType *Replaced;
-
- SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
- : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
- Canon->isInstantiationDependentType(),
- Canon->isVariablyModifiedType(),
- Canon->containsUnexpandedParameterPack()),
- Replaced(Param) { }
-
- friend class ASTContext;
-
-public:
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
-
- /// Gets the type that was substituted for the template
- /// parameter.
- QualType getReplacementType() const {
- return getCanonicalTypeInternal();
- }
-
- bool isSugared() const { return true; }
- QualType desugar() const { return getReplacementType(); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReplacedParameter(), getReplacementType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
- QualType Replacement) {
- ID.AddPointer(Replaced);
- ID.AddPointer(Replacement.getAsOpaquePtr());
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == SubstTemplateTypeParm;
- }
-};
-
-/// \brief Represents the result of substituting a set of types for a template
-/// type parameter pack.
-///
-/// When a pack expansion in the source code contains multiple parameter packs
-/// and those parameter packs correspond to different levels of template
-/// parameter lists, this type node is used to represent a template type
-/// parameter pack from an outer level, which has already had its argument pack
-/// substituted but that still lives within a pack expansion that itself
-/// could not be instantiated. When actually performing a substitution into
-/// that pack expansion (e.g., when all template parameters have corresponding
-/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType
-/// at the current pack substitution index.
-class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
- /// \brief The original type parameter.
- const TemplateTypeParmType *Replaced;
-
- /// \brief A pointer to the set of template arguments that this
- /// parameter pack is instantiated with.
- const TemplateArgument *Arguments;
-
- /// \brief The number of template arguments in \c Arguments.
- unsigned NumArguments;
-
- SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
- QualType Canon,
- const TemplateArgument &ArgPack);
-
- friend class ASTContext;
-
-public:
- IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
-
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- TemplateArgument getArgumentPack() const;
-
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
- const TemplateArgument &ArgPack);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == SubstTemplateTypeParmPack;
- }
-};
-
-/// \brief Represents a C++11 auto or C++14 decltype(auto) type.
-///
-/// These types are usually a placeholder for a deduced type. However, before
-/// the initializer is attached, or if the initializer is type-dependent, there
-/// is no deduced type and an auto type is canonical. In the latter case, it is
-/// also a dependent type.
-class AutoType : public Type, public llvm::FoldingSetNode {
- AutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent)
- : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
- /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
- /*VariablyModified=*/false,
- /*ContainsParameterPack=*/DeducedType.isNull()
- ? false : DeducedType->containsUnexpandedParameterPack()) {
- assert((DeducedType.isNull() || !IsDependent) &&
- "auto deduced to dependent type");
- AutoTypeBits.Keyword = (unsigned)Keyword;
- }
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- bool isDecltypeAuto() const {
- return getKeyword() == AutoTypeKeyword::DecltypeAuto;
- }
- AutoTypeKeyword getKeyword() const {
- return (AutoTypeKeyword)AutoTypeBits.Keyword;
- }
-
- bool isSugared() const { return !isCanonicalUnqualified(); }
- QualType desugar() const { return getCanonicalTypeInternal(); }
-
- /// \brief Get the type deduced for this auto type, or null if it's either
- /// not been deduced or was deduced to a dependent type.
- QualType getDeducedType() const {
- return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
- }
- bool isDeduced() const {
- return !isCanonicalUnqualified() || isDependentType();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getDeducedType(), getKeyword(), isDependentType());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
- AutoTypeKeyword Keyword, bool IsDependent) {
- ID.AddPointer(Deduced.getAsOpaquePtr());
- ID.AddInteger((unsigned)Keyword);
- ID.AddBoolean(IsDependent);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Auto;
- }
-};
-
-/// \brief Represents a type template specialization; the template
-/// must be a class template, a type alias template, or a template
-/// template parameter. A template which cannot be resolved to one of
-/// these, e.g. because it is written with a dependent scope
-/// specifier, is instead represented as a
-/// @c DependentTemplateSpecializationType.
-///
-/// A non-dependent template specialization type is always "sugar",
-/// typically for a \c RecordType. For example, a class template
-/// specialization type of \c vector<int> will refer to a tag type for
-/// the instantiation \c std::vector<int, std::allocator<int>>
-///
-/// Template specializations are dependent if either the template or
-/// any of the template arguments are dependent, in which case the
-/// type may also be canonical.
-///
-/// Instances of this type are allocated with a trailing array of
-/// TemplateArguments, followed by a QualType representing the
-/// non-canonical aliased type when the template is a type alias
-/// template.
-class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType
- : public Type,
- public llvm::FoldingSetNode {
- /// The name of the template being specialized. This is
- /// either a TemplateName::Template (in which case it is a
- /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a
- /// TypeAliasTemplateDecl*), a
- /// TemplateName::SubstTemplateTemplateParmPack, or a
- /// TemplateName::SubstTemplateTemplateParm (in which case the
- /// replacement must, recursively, be one of these).
- TemplateName Template;
-
- /// The number of template arguments named in this class template
- /// specialization.
- unsigned NumArgs : 31;
-
- /// Whether this template specialization type is a substituted type alias.
- bool TypeAlias : 1;
-
- TemplateSpecializationType(TemplateName T,
- const TemplateArgument *Args,
- unsigned NumArgs, QualType Canon,
- QualType Aliased);
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- /// Determine whether any of the given template arguments are dependent.
- static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
- unsigned NumArgs,
- bool &InstantiationDependent);
-
- static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &,
- bool &InstantiationDependent);
-
- /// \brief Print a template argument list, including the '<' and '>'
- /// enclosing the template arguments.
- static void PrintTemplateArgumentList(raw_ostream &OS,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const PrintingPolicy &Policy,
- bool SkipBrackets = false);
-
- static void PrintTemplateArgumentList(raw_ostream &OS,
- const TemplateArgumentLoc *Args,
- unsigned NumArgs,
- const PrintingPolicy &Policy);
-
- static void PrintTemplateArgumentList(raw_ostream &OS,
- const TemplateArgumentListInfo &,
- const PrintingPolicy &Policy);
-
- /// True if this template specialization type matches a current
- /// instantiation in the context in which it is found.
- bool isCurrentInstantiation() const {
- return isa<InjectedClassNameType>(getCanonicalTypeInternal());
- }
-
- /// \brief Determine if this template specialization type is for a type alias
- /// template that has been substituted.
- ///
- /// Nearly every template specialization type whose template is an alias
- /// template will be substituted. However, this is not the case when
- /// the specialization contains a pack expansion but the template alias
- /// does not have a corresponding parameter pack, e.g.,
- ///
- /// \code
- /// template<typename T, typename U, typename V> struct S;
- /// template<typename T, typename U> using A = S<T, int, U>;
- /// template<typename... Ts> struct X {
- /// typedef A<Ts...> type; // not a type alias
- /// };
- /// \endcode
- bool isTypeAlias() const { return TypeAlias; }
-
- /// Get the aliased type, if this is a specialization of a type alias
- /// template.
- QualType getAliasedType() const {
- assert(isTypeAlias() && "not a type alias template specialization");
- return *reinterpret_cast<const QualType*>(end());
- }
-
- typedef const TemplateArgument * iterator;
-
- iterator begin() const { return getArgs(); }
- iterator end() const; // defined inline in TemplateBase.h
-
- /// Retrieve the name of the template that we are specializing.
- TemplateName getTemplateName() const { return Template; }
-
- /// Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return reinterpret_cast<const TemplateArgument *>(this + 1);
- }
-
- /// Retrieve the number of template arguments.
- unsigned getNumArgs() const { return NumArgs; }
-
- /// Retrieve a specific template argument as a type.
- /// \pre \c isArgType(Arg)
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
- bool isSugared() const {
- return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
- }
- QualType desugar() const { return getCanonicalTypeInternal(); }
-
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
- Profile(ID, Template, getArgs(), NumArgs, Ctx);
- if (isTypeAlias())
- getAliasedType().Profile(ID);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const ASTContext &Context);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == TemplateSpecialization;
- }
-};
-
-/// The injected class name of a C++ class template or class
-/// template partial specialization. Used to record that a type was
-/// spelled with a bare identifier rather than as a template-id; the
-/// equivalent for non-templated classes is just RecordType.
-///
-/// Injected class name types are always dependent. Template
-/// instantiation turns these into RecordTypes.
-///
-/// Injected class name types are always canonical. This works
-/// because it is impossible to compare an injected class name type
-/// with the corresponding non-injected template type, for the same
-/// reason that it is impossible to directly compare template
-/// parameters from different dependent contexts: injected class name
-/// types can only occur within the scope of a particular templated
-/// declaration, and within that scope every template specialization
-/// will canonicalize to the injected class name (when appropriate
-/// according to the rules of the language).
-class InjectedClassNameType : public Type {
- CXXRecordDecl *Decl;
-
- /// The template specialization which this type represents.
- /// For example, in
- /// template <class T> class A { ... };
- /// this is A<T>, whereas in
- /// template <class X, class Y> class A<B<X,Y> > { ... };
- /// this is A<B<X,Y> >.
- ///
- /// It is always unqualified, always a template specialization type,
- /// and always dependent.
- QualType InjectedType;
-
- friend class ASTContext; // ASTContext creates these.
- friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
- // currently suitable for AST reading, too much
- // interdependencies.
- InjectedClassNameType(CXXRecordDecl *D, QualType TST)
- : Type(InjectedClassName, QualType(), /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- /*ContainsUnexpandedParameterPack=*/false),
- Decl(D), InjectedType(TST) {
- assert(isa<TemplateSpecializationType>(TST));
- assert(!TST.hasQualifiers());
- assert(TST->isDependentType());
- }
-
-public:
- QualType getInjectedSpecializationType() const { return InjectedType; }
- const TemplateSpecializationType *getInjectedTST() const {
- return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
- }
-
- CXXRecordDecl *getDecl() const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == InjectedClassName;
- }
-};
-
-/// \brief The kind of a tag type.
-enum TagTypeKind {
- /// \brief The "struct" keyword.
- TTK_Struct,
- /// \brief The "__interface" keyword.
- TTK_Interface,
- /// \brief The "union" keyword.
- TTK_Union,
- /// \brief The "class" keyword.
- TTK_Class,
- /// \brief The "enum" keyword.
- TTK_Enum
-};
-
-/// \brief The elaboration keyword that precedes a qualified type name or
-/// introduces an elaborated-type-specifier.
-enum ElaboratedTypeKeyword {
- /// \brief The "struct" keyword introduces the elaborated-type-specifier.
- ETK_Struct,
- /// \brief The "__interface" keyword introduces the elaborated-type-specifier.
- ETK_Interface,
- /// \brief The "union" keyword introduces the elaborated-type-specifier.
- ETK_Union,
- /// \brief The "class" keyword introduces the elaborated-type-specifier.
- ETK_Class,
- /// \brief The "enum" keyword introduces the elaborated-type-specifier.
- ETK_Enum,
- /// \brief The "typename" keyword precedes the qualified type name, e.g.,
- /// \c typename T::type.
- ETK_Typename,
- /// \brief No keyword precedes the qualified type name.
- ETK_None
-};
-
-/// A helper class for Type nodes having an ElaboratedTypeKeyword.
-/// The keyword in stored in the free bits of the base class.
-/// Also provides a few static helpers for converting and printing
-/// elaborated type keyword and tag type kind enumerations.
-class TypeWithKeyword : public Type {
-protected:
- TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
- QualType Canonical, bool Dependent,
- bool InstantiationDependent, bool VariablyModified,
- bool ContainsUnexpandedParameterPack)
- : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
- ContainsUnexpandedParameterPack) {
- TypeWithKeywordBits.Keyword = Keyword;
- }
-
-public:
- ElaboratedTypeKeyword getKeyword() const {
- return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword);
- }
-
- /// Converts a type specifier (DeclSpec::TST) into an elaborated type keyword.
- static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
-
- /// Converts a type specifier (DeclSpec::TST) into a tag type kind.
- /// It is an error to provide a type specifier which *isn't* a tag kind here.
- static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
-
- /// Converts a TagTypeKind into an elaborated type keyword.
- static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
-
- /// Converts an elaborated type keyword into a TagTypeKind.
- /// It is an error to provide an elaborated type keyword
- /// which *isn't* a tag kind here.
- static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
-
- static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
-
- static StringRef getKeywordName(ElaboratedTypeKeyword Keyword);
-
- static StringRef getTagTypeKindName(TagTypeKind Kind) {
- return getKeywordName(getKeywordForTagTypeKind(Kind));
- }
-
- class CannotCastToThisType {};
- static CannotCastToThisType classof(const Type *);
-};
-
-/// \brief Represents a type that was referred to using an elaborated type
-/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
-/// or both.
-///
-/// This type is used to keep track of a type name as written in the
-/// source code, including tag keywords and any nested-name-specifiers.
-/// The type itself is always "sugar", used to express what was written
-/// in the source code but containing no additional semantic information.
-class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
-
- /// The nested name specifier containing the qualifier.
- NestedNameSpecifier *NNS;
-
- /// The type that this qualified name refers to.
- QualType NamedType;
-
- ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
- QualType NamedType, QualType CanonType)
- : TypeWithKeyword(Keyword, Elaborated, CanonType,
- NamedType->isDependentType(),
- NamedType->isInstantiationDependentType(),
- NamedType->isVariablyModifiedType(),
- NamedType->containsUnexpandedParameterPack()),
- NNS(NNS), NamedType(NamedType) {
- assert(!(Keyword == ETK_None && NNS == nullptr) &&
- "ElaboratedType cannot have elaborated type keyword "
- "and name qualifier both null.");
- }
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- ~ElaboratedType();
-
- /// Retrieve the qualification on this type.
- NestedNameSpecifier *getQualifier() const { return NNS; }
-
- /// Retrieve the type named by the qualified-id.
- QualType getNamedType() const { return NamedType; }
-
- /// Remove a single level of sugar.
- QualType desugar() const { return getNamedType(); }
-
- /// Returns whether this type directly provides sugar.
- bool isSugared() const { return true; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getKeyword(), NNS, NamedType);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, QualType NamedType) {
- ID.AddInteger(Keyword);
- ID.AddPointer(NNS);
- NamedType.Profile(ID);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == Elaborated;
- }
-};
-
-/// \brief Represents a qualified type name for which the type name is
-/// dependent.
-///
-/// DependentNameType represents a class of dependent types that involve a
-/// possibly dependent nested-name-specifier (e.g., "T::") followed by a
-/// name of a type. The DependentNameType may start with a "typename" (for a
-/// typename-specifier), "class", "struct", "union", or "enum" (for a
-/// dependent elaborated-type-specifier), or nothing (in contexts where we
-/// know that we must be referring to a type, e.g., in a base class specifier).
-/// Typically the nested-name-specifier is dependent, but in MSVC compatibility
-/// mode, this type is used with non-dependent names to delay name lookup until
-/// instantiation.
-class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
-
- /// \brief The nested name specifier containing the qualifier.
- NestedNameSpecifier *NNS;
-
- /// \brief The type that this typename specifier refers to.
- const IdentifierInfo *Name;
-
- DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
- const IdentifierInfo *Name, QualType CanonType)
- : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/false,
- NNS->containsUnexpandedParameterPack()),
- NNS(NNS), Name(Name) {}
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- /// Retrieve the qualification on this type.
- NestedNameSpecifier *getQualifier() const { return NNS; }
-
- /// Retrieve the type named by the typename specifier as an identifier.
- ///
- /// This routine will return a non-NULL identifier pointer when the
- /// form of the original typename was terminated by an identifier,
- /// e.g., "typename T::type".
- const IdentifierInfo *getIdentifier() const {
- return Name;
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getKeyword(), NNS, Name);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
- ID.AddInteger(Keyword);
- ID.AddPointer(NNS);
- ID.AddPointer(Name);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentName;
- }
-};
-
-/// Represents a template specialization type whose template cannot be
-/// resolved, e.g.
-/// A<T>::template B<T>
-class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType
- : public TypeWithKeyword,
- public llvm::FoldingSetNode {
-
- /// The nested name specifier containing the qualifier.
- NestedNameSpecifier *NNS;
-
- /// The identifier of the template.
- const IdentifierInfo *Name;
-
- /// \brief The number of template arguments named in this class template
- /// specialization.
- unsigned NumArgs;
-
- const TemplateArgument *getArgBuffer() const {
- return reinterpret_cast<const TemplateArgument*>(this+1);
- }
- TemplateArgument *getArgBuffer() {
- return reinterpret_cast<TemplateArgument*>(this+1);
- }
-
- DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- unsigned NumArgs,
- const TemplateArgument *Args,
- QualType Canon);
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- NestedNameSpecifier *getQualifier() const { return NNS; }
- const IdentifierInfo *getIdentifier() const { return Name; }
-
- /// \brief Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return getArgBuffer();
- }
-
- /// \brief Retrieve the number of template arguments.
- unsigned getNumArgs() const { return NumArgs; }
-
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
- typedef const TemplateArgument * iterator;
- iterator begin() const { return getArgs(); }
- iterator end() const; // inline in TemplateBase.h
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- const ASTContext &Context,
- ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *Qualifier,
- const IdentifierInfo *Name,
- unsigned NumArgs,
- const TemplateArgument *Args);
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == DependentTemplateSpecialization;
- }
-};
-
-/// \brief Represents a pack expansion of types.
-///
-/// Pack expansions are part of C++11 variadic templates. A pack
-/// expansion contains a pattern, which itself contains one or more
-/// "unexpanded" parameter packs. When instantiated, a pack expansion
-/// produces a series of types, each instantiated from the pattern of
-/// the expansion, where the Ith instantiation of the pattern uses the
-/// Ith arguments bound to each of the unexpanded parameter packs. The
-/// pack expansion is considered to "expand" these unexpanded
-/// parameter packs.
-///
-/// \code
-/// template<typename ...Types> struct tuple;
-///
-/// template<typename ...Types>
-/// struct tuple_of_references {
-/// typedef tuple<Types&...> type;
-/// };
-/// \endcode
-///
-/// Here, the pack expansion \c Types&... is represented via a
-/// PackExpansionType whose pattern is Types&.
-class PackExpansionType : public Type, public llvm::FoldingSetNode {
- /// \brief The pattern of the pack expansion.
- QualType Pattern;
-
- /// \brief The number of expansions that this pack expansion will
- /// generate when substituted (+1), or indicates that
- ///
- /// This field will only have a non-zero value when some of the parameter
- /// packs that occur within the pattern have been substituted but others have
- /// not.
- unsigned NumExpansions;
-
- PackExpansionType(QualType Pattern, QualType Canon,
- Optional<unsigned> NumExpansions)
- : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
- /*InstantiationDependent=*/true,
- /*VariablyModified=*/Pattern->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false),
- Pattern(Pattern),
- NumExpansions(NumExpansions? *NumExpansions + 1: 0) { }
-
- friend class ASTContext; // ASTContext creates these
-
-public:
- /// \brief Retrieve the pattern of this pack expansion, which is the
- /// type that will be repeatedly instantiated when instantiating the
- /// pack expansion itself.
- QualType getPattern() const { return Pattern; }
-
- /// \brief Retrieve the number of expansions that this pack expansion will
- /// generate, if known.
- Optional<unsigned> getNumExpansions() const {
- if (NumExpansions)
- return NumExpansions - 1;
-
- return None;
- }
-
- bool isSugared() const { return !Pattern->isDependentType(); }
- QualType desugar() const { return isSugared() ? Pattern : QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPattern(), getNumExpansions());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
- Optional<unsigned> NumExpansions) {
- ID.AddPointer(Pattern.getAsOpaquePtr());
- ID.AddBoolean(NumExpansions.hasValue());
- if (NumExpansions)
- ID.AddInteger(*NumExpansions);
- }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == PackExpansion;
- }
-};
-
-/// Represents a class type in Objective C.
-///
-/// Every Objective C type is a combination of a base type, a set of
-/// type arguments (optional, for parameterized classes) and a list of
-/// protocols.
-///
-/// Given the following declarations:
-/// \code
-/// \@class C<T>;
-/// \@protocol P;
-/// \endcode
-///
-/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType
-/// with base C and no protocols.
-///
-/// 'C<P>' is an unspecialized ObjCObjectType with base C and protocol list [P].
-/// 'C<C*>' is a specialized ObjCObjectType with type arguments 'C*' and no
-/// protocol list.
-/// 'C<C*><P>' is a specialized ObjCObjectType with base C, type arguments 'C*',
-/// and protocol list [P].
-///
-/// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose
-/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType
-/// and no protocols.
-///
-/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType
-/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually
-/// this should get its own sugar class to better represent the source.
-class ObjCObjectType : public Type {
- // ObjCObjectType.NumTypeArgs - the number of type arguments stored
- // after the ObjCObjectPointerType node.
- // ObjCObjectType.NumProtocols - the number of protocols stored
- // after the type arguments of ObjCObjectPointerType node.
- //
- // These protocols are those written directly on the type. If
- // protocol qualifiers ever become additive, the iterators will need
- // to get kindof complicated.
- //
- // In the canonical object type, these are sorted alphabetically
- // and uniqued.
-
- /// Either a BuiltinType or an InterfaceType or sugar for either.
- QualType BaseType;
-
- /// Cached superclass type.
- mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool>
- CachedSuperClassType;
-
- ObjCProtocolDecl * const *getProtocolStorage() const {
- return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
- }
-
- QualType *getTypeArgStorage();
- const QualType *getTypeArgStorage() const {
- return const_cast<ObjCObjectType *>(this)->getTypeArgStorage();
- }
-
- ObjCProtocolDecl **getProtocolStorage();
-
-protected:
- ObjCObjectType(QualType Canonical, QualType Base,
- ArrayRef<QualType> typeArgs,
- ArrayRef<ObjCProtocolDecl *> protocols,
- bool isKindOf);
-
- enum Nonce_ObjCInterface { Nonce_ObjCInterface };
- ObjCObjectType(enum Nonce_ObjCInterface)
- : Type(ObjCInterface, QualType(), false, false, false, false),
- BaseType(QualType(this_(), 0)) {
- ObjCObjectTypeBits.NumProtocols = 0;
- ObjCObjectTypeBits.NumTypeArgs = 0;
- ObjCObjectTypeBits.IsKindOf = 0;
- }
-
- void computeSuperClassTypeSlow() const;
-
-public:
- /// Gets the base type of this object type. This is always (possibly
- /// sugar for) one of:
- /// - the 'id' builtin type (as opposed to the 'id' type visible to the
- /// user, which is a typedef for an ObjCObjectPointerType)
- /// - the 'Class' builtin type (same caveat)
- /// - an ObjCObjectType (currently always an ObjCInterfaceType)
- QualType getBaseType() const { return BaseType; }
-
- bool isObjCId() const {
- return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
- }
- bool isObjCClass() const {
- return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
- }
- bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
- bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
- bool isObjCUnqualifiedIdOrClass() const {
- if (!qual_empty()) return false;
- if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>())
- return T->getKind() == BuiltinType::ObjCId ||
- T->getKind() == BuiltinType::ObjCClass;
- return false;
- }
- bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); }
- bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); }
-
- /// Gets the interface declaration for this object type, if the base type
- /// really is an interface.
- ObjCInterfaceDecl *getInterface() const;
-
- /// Determine whether this object type is "specialized", meaning
- /// that it has type arguments.
- bool isSpecialized() const;
-
- /// Determine whether this object type was written with type arguments.
- bool isSpecializedAsWritten() const {
- return ObjCObjectTypeBits.NumTypeArgs > 0;
- }
-
- /// Determine whether this object type is "unspecialized", meaning
- /// that it has no type arguments.
- bool isUnspecialized() const { return !isSpecialized(); }
-
- /// Determine whether this object type is "unspecialized" as
- /// written, meaning that it has no type arguments.
- bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }
-
- /// Retrieve the type arguments of this object type (semantically).
- ArrayRef<QualType> getTypeArgs() const;
-
- /// Retrieve the type arguments of this object type as they were
- /// written.
- ArrayRef<QualType> getTypeArgsAsWritten() const {
- return llvm::makeArrayRef(getTypeArgStorage(),
- ObjCObjectTypeBits.NumTypeArgs);
- }
-
- typedef ObjCProtocolDecl * const *qual_iterator;
- typedef llvm::iterator_range<qual_iterator> qual_range;
-
- qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
- qual_iterator qual_begin() const { return getProtocolStorage(); }
- qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
-
- bool qual_empty() const { return getNumProtocols() == 0; }
-
- /// Return the number of qualifying protocols in this interface type,
- /// or 0 if there are none.
- unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; }
-
- /// Fetch a protocol by index.
- ObjCProtocolDecl *getProtocol(unsigned I) const {
- assert(I < getNumProtocols() && "Out-of-range protocol access");
- return qual_begin()[I];
- }
-
- /// Retrieve all of the protocol qualifiers.
- ArrayRef<ObjCProtocolDecl *> getProtocols() const {
- return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
- }
-
- /// Whether this is a "__kindof" type as written.
- bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; }
-
- /// Whether this ia a "__kindof" type (semantically).
- bool isKindOfType() const;
-
- /// Retrieve the type of the superclass of this object type.
- ///
- /// This operation substitutes any type arguments into the
- /// superclass of the current class type, potentially producing a
- /// specialization of the superclass type. Produces a null type if
- /// there is no superclass.
- QualType getSuperClassType() const {
- if (!CachedSuperClassType.getInt())
- computeSuperClassTypeSlow();
-
- assert(CachedSuperClassType.getInt() && "Superclass not set?");
- return QualType(CachedSuperClassType.getPointer(), 0);
- }
-
- /// Strip off the Objective-C "kindof" type and (with it) any
- /// protocol qualifiers.
- QualType stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCObject ||
- T->getTypeClass() == ObjCInterface;
- }
-};
-
-/// A class providing a concrete implementation
-/// of ObjCObjectType, so as to not increase the footprint of
-/// ObjCInterfaceType. Code outside of ASTContext and the core type
-/// system should not reference this type.
-class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
- friend class ASTContext;
-
- // If anyone adds fields here, ObjCObjectType::getProtocolStorage()
- // will need to be modified.
-
- ObjCObjectTypeImpl(QualType Canonical, QualType Base,
- ArrayRef<QualType> typeArgs,
- ArrayRef<ObjCProtocolDecl *> protocols,
- bool isKindOf)
- : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {}
-
-public:
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- QualType Base,
- ArrayRef<QualType> typeArgs,
- ArrayRef<ObjCProtocolDecl *> protocols,
- bool isKindOf);
-};
-
-inline QualType *ObjCObjectType::getTypeArgStorage() {
- return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1);
-}
-
-inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
- return reinterpret_cast<ObjCProtocolDecl**>(
- getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs);
-}
-
-/// Interfaces are the core concept in Objective-C for object oriented design.
-/// They basically correspond to C++ classes. There are two kinds of interface
-/// types: normal interfaces like `NSString`, and qualified interfaces, which
-/// are qualified with a protocol list like `NSString<NSCopyable, NSAmazing>`.
-///
-/// ObjCInterfaceType guarantees the following properties when considered
-/// as a subtype of its superclass, ObjCObjectType:
-/// - There are no protocol qualifiers. To reinforce this, code which
-/// tries to invoke the protocol methods via an ObjCInterfaceType will
-/// fail to compile.
-/// - It is its own base type. That is, if T is an ObjCInterfaceType*,
-/// T->getBaseType() == QualType(T, 0).
-class ObjCInterfaceType : public ObjCObjectType {
- mutable ObjCInterfaceDecl *Decl;
-
- ObjCInterfaceType(const ObjCInterfaceDecl *D)
- : ObjCObjectType(Nonce_ObjCInterface),
- Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
- friend class ASTContext; // ASTContext creates these.
- friend class ASTReader;
- friend class ObjCInterfaceDecl;
-
-public:
- /// Get the declaration of this interface.
- ObjCInterfaceDecl *getDecl() const { return Decl; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCInterface;
- }
-
- // Nonsense to "hide" certain members of ObjCObjectType within this
- // class. People asking for protocols on an ObjCInterfaceType are
- // not going to get what they want: ObjCInterfaceTypes are
- // guaranteed to have no protocols.
- enum {
- qual_iterator,
- qual_begin,
- qual_end,
- getNumProtocols,
- getProtocol
- };
-};
-
-inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
- QualType baseType = getBaseType();
- while (const ObjCObjectType *ObjT = baseType->getAs<ObjCObjectType>()) {
- if (const ObjCInterfaceType *T = dyn_cast<ObjCInterfaceType>(ObjT))
- return T->getDecl();
-
- baseType = ObjT->getBaseType();
- }
-
- return nullptr;
-}
-
-/// Represents a pointer to an Objective C object.
-///
-/// These are constructed from pointer declarators when the pointee type is
-/// an ObjCObjectType (or sugar for one). In addition, the 'id' and 'Class'
-/// types are typedefs for these, and the protocol-qualified types 'id<P>'
-/// and 'Class<P>' are translated into these.
-///
-/// Pointers to pointers to Objective C objects are still PointerTypes;
-/// only the first level of pointer gets it own type implementation.
-class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType;
-
- ObjCObjectPointerType(QualType Canonical, QualType Pointee)
- : Type(ObjCObjectPointer, Canonical,
- Pointee->isDependentType(),
- Pointee->isInstantiationDependentType(),
- Pointee->isVariablyModifiedType(),
- Pointee->containsUnexpandedParameterPack()),
- PointeeType(Pointee) {}
- friend class ASTContext; // ASTContext creates these.
-
-public:
- /// Gets the type pointed to by this ObjC pointer.
- /// The result will always be an ObjCObjectType or sugar thereof.
- QualType getPointeeType() const { return PointeeType; }
-
- /// Gets the type pointed to by this ObjC pointer. Always returns non-null.
- ///
- /// This method is equivalent to getPointeeType() except that
- /// it discards any typedefs (or other sugar) between this
- /// type and the "outermost" object type. So for:
- /// \code
- /// \@class A; \@protocol P; \@protocol Q;
- /// typedef A<P> AP;
- /// typedef A A1;
- /// typedef A1<P> A1P;
- /// typedef A1P<Q> A1PQ;
- /// \endcode
- /// For 'A*', getObjectType() will return 'A'.
- /// For 'A<P>*', getObjectType() will return 'A<P>'.
- /// For 'AP*', getObjectType() will return 'A<P>'.
- /// For 'A1*', getObjectType() will return 'A'.
- /// For 'A1<P>*', getObjectType() will return 'A1<P>'.
- /// For 'A1P*', getObjectType() will return 'A1<P>'.
- /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because
- /// adding protocols to a protocol-qualified base discards the
- /// old qualifiers (for now). But if it didn't, getObjectType()
- /// would return 'A1P<Q>' (and we'd have to make iterating over
- /// qualifiers more complicated).
- const ObjCObjectType *getObjectType() const {
- return PointeeType->castAs<ObjCObjectType>();
- }
-
- /// If this pointer points to an Objective C
- /// \@interface type, gets the type for that interface. Any protocol
- /// qualifiers on the interface are ignored.
- ///
- /// \return null if the base type for this pointer is 'id' or 'Class'
- const ObjCInterfaceType *getInterfaceType() const;
-
- /// If this pointer points to an Objective \@interface
- /// type, gets the declaration for that interface.
- ///
- /// \return null if the base type for this pointer is 'id' or 'Class'
- ObjCInterfaceDecl *getInterfaceDecl() const {
- return getObjectType()->getInterface();
- }
-
- /// True if this is equivalent to the 'id' type, i.e. if
- /// its object type is the primitive 'id' type with no protocols.
- bool isObjCIdType() const {
- return getObjectType()->isObjCUnqualifiedId();
- }
-
- /// True if this is equivalent to the 'Class' type,
- /// i.e. if its object tive is the primitive 'Class' type with no protocols.
- bool isObjCClassType() const {
- return getObjectType()->isObjCUnqualifiedClass();
- }
-
- /// True if this is equivalent to the 'id' or 'Class' type,
- bool isObjCIdOrClassType() const {
- return getObjectType()->isObjCUnqualifiedIdOrClass();
- }
-
- /// True if this is equivalent to 'id<P>' for some non-empty set of
- /// protocols.
- bool isObjCQualifiedIdType() const {
- return getObjectType()->isObjCQualifiedId();
- }
-
- /// True if this is equivalent to 'Class<P>' for some non-empty set of
- /// protocols.
- bool isObjCQualifiedClassType() const {
- return getObjectType()->isObjCQualifiedClass();
- }
-
- /// Whether this is a "__kindof" type.
- bool isKindOfType() const { return getObjectType()->isKindOfType(); }
-
- /// Whether this type is specialized, meaning that it has type arguments.
- bool isSpecialized() const { return getObjectType()->isSpecialized(); }
-
- /// Whether this type is specialized, meaning that it has type arguments.
- bool isSpecializedAsWritten() const {
- return getObjectType()->isSpecializedAsWritten();
- }
-
- /// Whether this type is unspecialized, meaning that is has no type arguments.
- bool isUnspecialized() const { return getObjectType()->isUnspecialized(); }
-
- /// Determine whether this object type is "unspecialized" as
- /// written, meaning that it has no type arguments.
- bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }
-
- /// Retrieve the type arguments for this type.
- ArrayRef<QualType> getTypeArgs() const {
- return getObjectType()->getTypeArgs();
- }
-
- /// Retrieve the type arguments for this type.
- ArrayRef<QualType> getTypeArgsAsWritten() const {
- return getObjectType()->getTypeArgsAsWritten();
- }
-
- /// An iterator over the qualifiers on the object type. Provided
- /// for convenience. This will always iterate over the full set of
- /// protocols on a type, not just those provided directly.
- typedef ObjCObjectType::qual_iterator qual_iterator;
- typedef llvm::iterator_range<qual_iterator> qual_range;
-
- qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
- qual_iterator qual_begin() const {
- return getObjectType()->qual_begin();
- }
- qual_iterator qual_end() const {
- return getObjectType()->qual_end();
- }
- bool qual_empty() const { return getObjectType()->qual_empty(); }
-
- /// Return the number of qualifying protocols on the object type.
- unsigned getNumProtocols() const {
- return getObjectType()->getNumProtocols();
- }
-
- /// Retrieve a qualifying protocol by index on the object type.
- ObjCProtocolDecl *getProtocol(unsigned I) const {
- return getObjectType()->getProtocol(I);
- }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- /// Retrieve the type of the superclass of this object pointer type.
- ///
- /// This operation substitutes any type arguments into the
- /// superclass of the current class type, potentially producing a
- /// pointer to a specialization of the superclass type. Produces a
- /// null type if there is no superclass.
- QualType getSuperClassType() const;
-
- /// Strip off the Objective-C "kindof" type and (with it) any
- /// protocol qualifiers.
- const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals(
- const ASTContext &ctx) const;
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
- ID.AddPointer(T.getAsOpaquePtr());
- }
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCObjectPointer;
- }
-};
-
-class AtomicType : public Type, public llvm::FoldingSetNode {
- QualType ValueType;
-
- AtomicType(QualType ValTy, QualType Canonical)
- : Type(Atomic, Canonical, ValTy->isDependentType(),
- ValTy->isInstantiationDependentType(),
- ValTy->isVariablyModifiedType(),
- ValTy->containsUnexpandedParameterPack()),
- ValueType(ValTy) {}
- friend class ASTContext; // ASTContext creates these.
-
- public:
- /// Gets the type contained by this atomic type, i.e.
- /// the type returned by performing an atomic load of this atomic type.
- QualType getValueType() const { return ValueType; }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getValueType());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
- ID.AddPointer(T.getAsOpaquePtr());
- }
- static bool classof(const Type *T) {
- return T->getTypeClass() == Atomic;
- }
-};
-
-/// A qualifier set is used to build a set of qualifiers.
-class QualifierCollector : public Qualifiers {
-public:
- QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {}
-
- /// Collect any qualifiers on the given type and return an
- /// unqualified type. The qualifiers are assumed to be consistent
- /// with those already in the type.
- const Type *strip(QualType type) {
- addFastQualifiers(type.getLocalFastQualifiers());
- if (!type.hasLocalNonFastQualifiers())
- return type.getTypePtrUnsafe();
-
- const ExtQuals *extQuals = type.getExtQualsUnsafe();
- addConsistentQualifiers(extQuals->getQualifiers());
- return extQuals->getBaseType();
- }
-
- /// Apply the collected qualifiers to the given type.
- QualType apply(const ASTContext &Context, QualType QT) const;
-
- /// Apply the collected qualifiers to the given type.
- QualType apply(const ASTContext &Context, const Type* T) const;
-};
-
-
-// Inline function definitions.
-
-inline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
- SplitQualType desugar =
- Ty->getLocallyUnqualifiedSingleStepDesugaredType().split();
- desugar.Quals.addConsistentQualifiers(Quals);
- return desugar;
-}
-
-inline const Type *QualType::getTypePtr() const {
- return getCommonPtr()->BaseType;
-}
-
-inline const Type *QualType::getTypePtrOrNull() const {
- return (isNull() ? nullptr : getCommonPtr()->BaseType);
-}
-
-inline SplitQualType QualType::split() const {
- if (!hasLocalNonFastQualifiers())
- return SplitQualType(getTypePtrUnsafe(),
- Qualifiers::fromFastMask(getLocalFastQualifiers()));
-
- const ExtQuals *eq = getExtQualsUnsafe();
- Qualifiers qs = eq->getQualifiers();
- qs.addFastQualifiers(getLocalFastQualifiers());
- return SplitQualType(eq->getBaseType(), qs);
-}
-
-inline Qualifiers QualType::getLocalQualifiers() const {
- Qualifiers Quals;
- if (hasLocalNonFastQualifiers())
- Quals = getExtQualsUnsafe()->getQualifiers();
- Quals.addFastQualifiers(getLocalFastQualifiers());
- return Quals;
-}
-
-inline Qualifiers QualType::getQualifiers() const {
- Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers();
- quals.addFastQualifiers(getLocalFastQualifiers());
- return quals;
-}
-
-inline unsigned QualType::getCVRQualifiers() const {
- unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers();
- cvr |= getLocalCVRQualifiers();
- return cvr;
-}
-
-inline QualType QualType::getCanonicalType() const {
- QualType canon = getCommonPtr()->CanonicalType;
- return canon.withFastQualifiers(getLocalFastQualifiers());
-}
-
-inline bool QualType::isCanonical() const {
- return getTypePtr()->isCanonicalUnqualified();
-}
-
-inline bool QualType::isCanonicalAsParam() const {
- if (!isCanonical()) return false;
- if (hasLocalQualifiers()) return false;
-
- const Type *T = getTypePtr();
- if (T->isVariablyModifiedType() && T->hasSizedVLAType())
- return false;
-
- return !isa<FunctionType>(T) && !isa<ArrayType>(T);
-}
-
-inline bool QualType::isConstQualified() const {
- return isLocalConstQualified() ||
- getCommonPtr()->CanonicalType.isLocalConstQualified();
-}
-
-inline bool QualType::isRestrictQualified() const {
- return isLocalRestrictQualified() ||
- getCommonPtr()->CanonicalType.isLocalRestrictQualified();
-}
-
-
-inline bool QualType::isVolatileQualified() const {
- return isLocalVolatileQualified() ||
- getCommonPtr()->CanonicalType.isLocalVolatileQualified();
-}
-
-inline bool QualType::hasQualifiers() const {
- return hasLocalQualifiers() ||
- getCommonPtr()->CanonicalType.hasLocalQualifiers();
-}
-
-inline QualType QualType::getUnqualifiedType() const {
- if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
- return QualType(getTypePtr(), 0);
-
- return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0);
-}
-
-inline SplitQualType QualType::getSplitUnqualifiedType() const {
- if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
- return split();
-
- return getSplitUnqualifiedTypeImpl(*this);
-}
-
-inline void QualType::removeLocalConst() {
- removeLocalFastQualifiers(Qualifiers::Const);
-}
-
-inline void QualType::removeLocalRestrict() {
- removeLocalFastQualifiers(Qualifiers::Restrict);
-}
-
-inline void QualType::removeLocalVolatile() {
- removeLocalFastQualifiers(Qualifiers::Volatile);
-}
-
-inline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
- assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits");
- assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask);
-
- // Fast path: we don't need to touch the slow qualifiers.
- removeLocalFastQualifiers(Mask);
-}
-
-/// Return the address space of this type.
-inline unsigned QualType::getAddressSpace() const {
- return getQualifiers().getAddressSpace();
-}
-
-/// Return the gc attribute of this type.
-inline Qualifiers::GC QualType::getObjCGCAttr() const {
- return getQualifiers().getObjCGCAttr();
-}
-
-inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) {
- if (const PointerType *PT = t.getAs<PointerType>()) {
- if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>())
- return FT->getExtInfo();
- } else if (const FunctionType *FT = t.getAs<FunctionType>())
- return FT->getExtInfo();
-
- return FunctionType::ExtInfo();
-}
-
-inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
- return getFunctionExtInfo(*t);
-}
-
-/// Determine whether this type is more
-/// qualified than the Other type. For example, "const volatile int"
-/// is more qualified than "const int", "volatile int", and
-/// "int". However, it is not more qualified than "const volatile
-/// int".
-inline bool QualType::isMoreQualifiedThan(QualType other) const {
- Qualifiers myQuals = getQualifiers();
- Qualifiers otherQuals = other.getQualifiers();
- return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals));
-}
-
-/// Determine whether this type is at last
-/// as qualified as the Other type. For example, "const volatile
-/// int" is at least as qualified as "const int", "volatile int",
-/// "int", and "const volatile int".
-inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const {
- return getQualifiers().compatiblyIncludes(other.getQualifiers());
-}
-
-/// If Type is a reference type (e.g., const
-/// int&), returns the type that the reference refers to ("const
-/// int"). Otherwise, returns the type itself. This routine is used
-/// throughout Sema to implement C++ 5p6:
-///
-/// If an expression initially has the type "reference to T" (8.3.2,
-/// 8.5.3), the type is adjusted to "T" prior to any further
-/// analysis, the expression designates the object or function
-/// denoted by the reference, and the expression is an lvalue.
-inline QualType QualType::getNonReferenceType() const {
- if (const ReferenceType *RefType = (*this)->getAs<ReferenceType>())
- return RefType->getPointeeType();
- else
- return *this;
-}
-
-inline bool QualType::isCForbiddenLValueType() const {
- return ((getTypePtr()->isVoidType() && !hasQualifiers()) ||
- getTypePtr()->isFunctionType());
-}
-
-/// Tests whether the type is categorized as a fundamental type.
-///
-/// \returns True for types specified in C++0x [basic.fundamental].
-inline bool Type::isFundamentalType() const {
- return isVoidType() ||
- // FIXME: It's really annoying that we don't have an
- // 'isArithmeticType()' which agrees with the standard definition.
- (isArithmeticType() && !isEnumeralType());
-}
-
-/// Tests whether the type is categorized as a compound type.
-///
-/// \returns True for types specified in C++0x [basic.compound].
-inline bool Type::isCompoundType() const {
- // C++0x [basic.compound]p1:
- // Compound types can be constructed in the following ways:
- // -- arrays of objects of a given type [...];
- return isArrayType() ||
- // -- functions, which have parameters of given types [...];
- isFunctionType() ||
- // -- pointers to void or objects or functions [...];
- isPointerType() ||
- // -- references to objects or functions of a given type. [...]
- isReferenceType() ||
- // -- classes containing a sequence of objects of various types, [...];
- isRecordType() ||
- // -- unions, which are classes capable of containing objects of different
- // types at different times;
- isUnionType() ||
- // -- enumerations, which comprise a set of named constant values. [...];
- isEnumeralType() ||
- // -- pointers to non-static class members, [...].
- isMemberPointerType();
-}
-
-inline bool Type::isFunctionType() const {
- return isa<FunctionType>(CanonicalType);
-}
-inline bool Type::isPointerType() const {
- return isa<PointerType>(CanonicalType);
-}
-inline bool Type::isAnyPointerType() const {
- return isPointerType() || isObjCObjectPointerType();
-}
-inline bool Type::isBlockPointerType() const {
- return isa<BlockPointerType>(CanonicalType);
-}
-inline bool Type::isReferenceType() const {
- return isa<ReferenceType>(CanonicalType);
-}
-inline bool Type::isLValueReferenceType() const {
- return isa<LValueReferenceType>(CanonicalType);
-}
-inline bool Type::isRValueReferenceType() const {
- return isa<RValueReferenceType>(CanonicalType);
-}
-inline bool Type::isFunctionPointerType() const {
- if (const PointerType *T = getAs<PointerType>())
- return T->getPointeeType()->isFunctionType();
- else
- return false;
-}
-inline bool Type::isMemberPointerType() const {
- return isa<MemberPointerType>(CanonicalType);
-}
-inline bool Type::isMemberFunctionPointerType() const {
- if (const MemberPointerType* T = getAs<MemberPointerType>())
- return T->isMemberFunctionPointer();
- else
- return false;
-}
-inline bool Type::isMemberDataPointerType() const {
- if (const MemberPointerType* T = getAs<MemberPointerType>())
- return T->isMemberDataPointer();
- else
- return false;
-}
-inline bool Type::isArrayType() const {
- return isa<ArrayType>(CanonicalType);
-}
-inline bool Type::isConstantArrayType() const {
- return isa<ConstantArrayType>(CanonicalType);
-}
-inline bool Type::isIncompleteArrayType() const {
- return isa<IncompleteArrayType>(CanonicalType);
-}
-inline bool Type::isVariableArrayType() const {
- return isa<VariableArrayType>(CanonicalType);
-}
-inline bool Type::isDependentSizedArrayType() const {
- return isa<DependentSizedArrayType>(CanonicalType);
-}
-inline bool Type::isBuiltinType() const {
- return isa<BuiltinType>(CanonicalType);
-}
-inline bool Type::isRecordType() const {
- return isa<RecordType>(CanonicalType);
-}
-inline bool Type::isEnumeralType() const {
- return isa<EnumType>(CanonicalType);
-}
-inline bool Type::isAnyComplexType() const {
- return isa<ComplexType>(CanonicalType);
-}
-inline bool Type::isVectorType() const {
- return isa<VectorType>(CanonicalType);
-}
-inline bool Type::isExtVectorType() const {
- return isa<ExtVectorType>(CanonicalType);
-}
-inline bool Type::isObjCObjectPointerType() const {
- return isa<ObjCObjectPointerType>(CanonicalType);
-}
-inline bool Type::isObjCObjectType() const {
- return isa<ObjCObjectType>(CanonicalType);
-}
-inline bool Type::isObjCObjectOrInterfaceType() const {
- return isa<ObjCInterfaceType>(CanonicalType) ||
- isa<ObjCObjectType>(CanonicalType);
-}
-inline bool Type::isAtomicType() const {
- return isa<AtomicType>(CanonicalType);
-}
-
-inline bool Type::isObjCQualifiedIdType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
- return OPT->isObjCQualifiedIdType();
- return false;
-}
-inline bool Type::isObjCQualifiedClassType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
- return OPT->isObjCQualifiedClassType();
- return false;
-}
-inline bool Type::isObjCIdType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
- return OPT->isObjCIdType();
- return false;
-}
-inline bool Type::isObjCClassType() const {
- if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
- return OPT->isObjCClassType();
- return false;
-}
-inline bool Type::isObjCSelType() const {
- if (const PointerType *OPT = getAs<PointerType>())
- return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
- return false;
-}
-inline bool Type::isObjCBuiltinType() const {
- return isObjCIdType() || isObjCClassType() || isObjCSelType();
-}
-
-inline bool Type::isImage1dT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage1d);
-}
-
-inline bool Type::isImage1dArrayT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage1dArray);
-}
-
-inline bool Type::isImage1dBufferT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer);
-}
-
-inline bool Type::isImage2dT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2d);
-}
-
-inline bool Type::isImage2dArrayT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dArray);
-}
-
-inline bool Type::isImage2dDepthT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dDepth);
-}
-
-inline bool Type::isImage2dArrayDepthT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayDepth);
-}
-
-inline bool Type::isImage2dMSAAT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dMSAA);
-}
-
-inline bool Type::isImage2dArrayMSAAT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayMSAA);
-}
-
-inline bool Type::isImage2dMSAATDepth() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dMSAADepth);
-}
-
-inline bool Type::isImage2dArrayMSAATDepth() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayMSAADepth);
-}
-
-inline bool Type::isImage3dT() const {
- return isSpecificBuiltinType(BuiltinType::OCLImage3d);
-}
-
-inline bool Type::isSamplerT() const {
- return isSpecificBuiltinType(BuiltinType::OCLSampler);
-}
-
-inline bool Type::isEventT() const {
- return isSpecificBuiltinType(BuiltinType::OCLEvent);
-}
-
-inline bool Type::isClkEventT() const {
- return isSpecificBuiltinType(BuiltinType::OCLClkEvent);
-}
-
-inline bool Type::isQueueT() const {
- return isSpecificBuiltinType(BuiltinType::OCLQueue);
-}
-
-inline bool Type::isNDRangeT() const {
- return isSpecificBuiltinType(BuiltinType::OCLNDRange);
-}
-
-inline bool Type::isReserveIDT() const {
- return isSpecificBuiltinType(BuiltinType::OCLReserveID);
-}
-
-inline bool Type::isImageType() const {
- return isImage3dT() || isImage2dT() || isImage2dArrayT() ||
- isImage2dDepthT() || isImage2dArrayDepthT() || isImage2dMSAAT() ||
- isImage2dArrayMSAAT() || isImage2dMSAATDepth() ||
- isImage2dArrayMSAATDepth() || isImage1dT() || isImage1dArrayT() ||
- isImage1dBufferT();
-}
-
-inline bool Type::isOpenCLSpecificType() const {
- return isSamplerT() || isEventT() || isImageType() || isClkEventT() ||
- isQueueT() || isNDRangeT() || isReserveIDT();
-}
-
-inline bool Type::isTemplateTypeParmType() const {
- return isa<TemplateTypeParmType>(CanonicalType);
-}
-
-inline bool Type::isSpecificBuiltinType(unsigned K) const {
- if (const BuiltinType *BT = getAs<BuiltinType>())
- if (BT->getKind() == (BuiltinType::Kind) K)
- return true;
- return false;
-}
-
-inline bool Type::isPlaceholderType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
- return BT->isPlaceholderType();
- return false;
-}
-
-inline const BuiltinType *Type::getAsPlaceholderType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
- if (BT->isPlaceholderType())
- return BT;
- return nullptr;
-}
-
-inline bool Type::isSpecificPlaceholderType(unsigned K) const {
- assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K));
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
- return (BT->getKind() == (BuiltinType::Kind) K);
- return false;
-}
-
-inline bool Type::isNonOverloadPlaceholderType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
- return BT->isNonOverloadPlaceholderType();
- return false;
-}
-
-inline bool Type::isVoidType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Void;
- return false;
-}
-
-inline bool Type::isHalfType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Half;
- // FIXME: Should we allow complex __fp16? Probably not.
- return false;
-}
-
-inline bool Type::isNullPtrType() const {
- if (const BuiltinType *BT = getAs<BuiltinType>())
- return BT->getKind() == BuiltinType::NullPtr;
- return false;
-}
-
-extern bool IsEnumDeclComplete(EnumDecl *);
-extern bool IsEnumDeclScoped(EnumDecl *);
-
-inline bool Type::isIntegerType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::Int128;
- if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
- // Incomplete enum types are not treated as integer types.
- // FIXME: In C++, enum types are never integer types.
- return IsEnumDeclComplete(ET->getDecl()) &&
- !IsEnumDeclScoped(ET->getDecl());
- }
- return false;
-}
-
-inline bool Type::isScalarType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() > BuiltinType::Void &&
- BT->getKind() <= BuiltinType::NullPtr;
- if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
- // Enums are scalar types, but only if they are defined. Incomplete enums
- // are not treated as scalar types.
- return IsEnumDeclComplete(ET->getDecl());
- return isa<PointerType>(CanonicalType) ||
- isa<BlockPointerType>(CanonicalType) ||
- isa<MemberPointerType>(CanonicalType) ||
- isa<ComplexType>(CanonicalType) ||
- isa<ObjCObjectPointerType>(CanonicalType);
-}
-
-inline bool Type::isIntegralOrEnumerationType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::Int128;
-
- // Check for a complete enum type; incomplete enum types are not properly an
- // enumeration type in the sense required here.
- if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
- return IsEnumDeclComplete(ET->getDecl());
-
- return false;
-}
-
-inline bool Type::isBooleanType() const {
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
- return BT->getKind() == BuiltinType::Bool;
- return false;
-}
-
-inline bool Type::isUndeducedType() const {
- const AutoType *AT = getContainedAutoType();
- return AT && !AT->isDeduced();
-}
-
-/// \brief Determines whether this is a type for which one can define
-/// an overloaded operator.
-inline bool Type::isOverloadableType() const {
- return isDependentType() || isRecordType() || isEnumeralType();
-}
-
-/// \brief Determines whether this type can decay to a pointer type.
-inline bool Type::canDecayToPointerType() const {
- return isFunctionType() || isArrayType();
-}
-
-inline bool Type::hasPointerRepresentation() const {
- return (isPointerType() || isReferenceType() || isBlockPointerType() ||
- isObjCObjectPointerType() || isNullPtrType());
-}
-
-inline bool Type::hasObjCPointerRepresentation() const {
- return isObjCObjectPointerType();
-}
-
-inline const Type *Type::getBaseElementTypeUnsafe() const {
- const Type *type = this;
- while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe())
- type = arrayType->getElementType().getTypePtr();
- return type;
-}
-
-/// Insertion operator for diagnostics. This allows sending QualType's into a
-/// diagnostic with <<.
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- QualType T) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
- DiagnosticsEngine::ak_qualtype);
- return DB;
-}
-
-/// Insertion operator for partial diagnostics. This allows sending QualType's
-/// into a diagnostic with <<.
-inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- QualType T) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
- DiagnosticsEngine::ak_qualtype);
- return PD;
-}
-
-// Helper class template that is used by Type::getAs to ensure that one does
-// not try to look through a qualified type to get to an array type.
-template <typename T, bool isArrayType = (std::is_same<T, ArrayType>::value ||
- std::is_base_of<ArrayType, T>::value)>
-struct ArrayType_cannot_be_used_with_getAs {};
-
-template<typename T>
-struct ArrayType_cannot_be_used_with_getAs<T, true>;
-
-// Member-template getAs<specific type>'.
-template <typename T> const T *Type::getAs() const {
- ArrayType_cannot_be_used_with_getAs<T> at;
- (void)at;
-
- // If this is directly a T type, return it.
- if (const T *Ty = dyn_cast<T>(this))
- return Ty;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<T>(CanonicalType))
- return nullptr;
-
- // If this is a typedef for the type, strip the typedef off without
- // losing all typedef information.
- return cast<T>(getUnqualifiedDesugaredType());
-}
-
-inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
- // If this is directly an array type, return it.
- if (const ArrayType *arr = dyn_cast<ArrayType>(this))
- return arr;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<ArrayType>(CanonicalType))
- return nullptr;
-
- // If this is a typedef for the type, strip the typedef off without
- // losing all typedef information.
- return cast<ArrayType>(getUnqualifiedDesugaredType());
-}
-
-template <typename T> const T *Type::castAs() const {
- ArrayType_cannot_be_used_with_getAs<T> at;
- (void) at;
-
- if (const T *ty = dyn_cast<T>(this)) return ty;
- assert(isa<T>(CanonicalType));
- return cast<T>(getUnqualifiedDesugaredType());
-}
-
-inline const ArrayType *Type::castAsArrayTypeUnsafe() const {
- assert(isa<ArrayType>(CanonicalType));
- if (const ArrayType *arr = dyn_cast<ArrayType>(this)) return arr;
- return cast<ArrayType>(getUnqualifiedDesugaredType());
-}
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
deleted file mode 100644
index 26feda5..0000000
--- a/include/clang/AST/TypeLoc.h
+++ /dev/null
@@ -1,2039 +0,0 @@
-//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the clang::TypeLoc interface and its subclasses.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TYPELOC_H
-#define LLVM_CLANG_AST_TYPELOC_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/Specifiers.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
- class ASTContext;
- class ParmVarDecl;
- class TypeSourceInfo;
- class UnqualTypeLoc;
-
-// Predeclare all the type nodes.
-#define ABSTRACT_TYPELOC(Class, Base)
-#define TYPELOC(Class, Base) \
- class Class##TypeLoc;
-#include "clang/AST/TypeLocNodes.def"
-
-/// \brief Base wrapper for a particular "section" of type source info.
-///
-/// A client should use the TypeLoc subclasses through castAs()/getAs()
-/// in order to get at the actual information.
-class TypeLoc {
-protected:
- // The correctness of this relies on the property that, for Type *Ty,
- // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
- const void *Ty;
- void *Data;
-
-public:
- /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
- /// is of the desired type.
- ///
- /// \pre T::isKind(*this)
- template<typename T>
- T castAs() const {
- assert(T::isKind(*this));
- T t;
- TypeLoc& tl = t;
- tl = *this;
- return t;
- }
-
- /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
- /// this TypeLoc is not of the desired type.
- template<typename T>
- T getAs() const {
- if (!T::isKind(*this))
- return T();
- T t;
- TypeLoc& tl = t;
- tl = *this;
- return t;
- }
-
- /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
- /// except it also defines a Qualified enum that corresponds to the
- /// QualifiedLoc class.
- enum TypeLocClass {
-#define ABSTRACT_TYPE(Class, Base)
-#define TYPE(Class, Base) \
- Class = Type::Class,
-#include "clang/AST/TypeNodes.def"
- Qualified
- };
-
- TypeLoc() : Ty(nullptr), Data(nullptr) { }
- TypeLoc(QualType ty, void *opaqueData)
- : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
- TypeLoc(const Type *ty, void *opaqueData)
- : Ty(ty), Data(opaqueData) { }
-
- TypeLocClass getTypeLocClass() const {
- if (getType().hasLocalQualifiers()) return Qualified;
- return (TypeLocClass) getType()->getTypeClass();
- }
-
- bool isNull() const { return !Ty; }
- explicit operator bool() const { return Ty; }
-
- /// \brief Returns the size of type source info data block for the given type.
- static unsigned getFullDataSizeForType(QualType Ty);
-
- /// \brief Returns the alignment of type source info data block for
- /// the given type.
- static unsigned getLocalAlignmentForType(QualType Ty);
-
- /// \brief Get the type for which this source info wrapper provides
- /// information.
- QualType getType() const {
- return QualType::getFromOpaquePtr(Ty);
- }
-
- const Type *getTypePtr() const {
- return QualType::getFromOpaquePtr(Ty).getTypePtr();
- }
-
- /// \brief Get the pointer where source information is stored.
- void *getOpaqueData() const {
- return Data;
- }
-
- /// \brief Get the begin source location.
- SourceLocation getBeginLoc() const;
-
- /// \brief Get the end source location.
- SourceLocation getEndLoc() const;
-
- /// \brief Get the full source range.
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getBeginLoc(), getEndLoc());
- }
- SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
- SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
-
- /// \brief Get the local source range.
- SourceRange getLocalSourceRange() const {
- return getLocalSourceRangeImpl(*this);
- }
-
- /// \brief Returns the size of the type source info data block.
- unsigned getFullDataSize() const {
- return getFullDataSizeForType(getType());
- }
-
- /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
- /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
- TypeLoc getNextTypeLoc() const {
- return getNextTypeLocImpl(*this);
- }
-
- /// \brief Skips past any qualifiers, if this is qualified.
- UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
-
- TypeLoc IgnoreParens() const;
-
- /// \brief Find a type with the location of an explicit type qualifier.
- ///
- /// The result, if non-null, will be one of:
- /// QualifiedTypeLoc
- /// AtomicTypeLoc
- /// AttributedTypeLoc, for those type attributes that behave as qualifiers
- TypeLoc findExplicitQualifierLoc() const;
-
- /// \brief Initializes this to state that every location in this
- /// type is the given location.
- ///
- /// This method exists to provide a simple transition for code that
- /// relies on location-less types.
- void initialize(ASTContext &Context, SourceLocation Loc) const {
- initializeImpl(Context, *this, Loc);
- }
-
- /// \brief Initializes this by copying its information from another
- /// TypeLoc of the same type.
- void initializeFullCopy(TypeLoc Other) {
- assert(getType() == Other.getType());
- copy(Other);
- }
-
- /// \brief Initializes this by copying its information from another
- /// TypeLoc of the same type. The given size must be the full data
- /// size.
- void initializeFullCopy(TypeLoc Other, unsigned Size) {
- assert(getType() == Other.getType());
- assert(getFullDataSize() == Size);
- copy(Other);
- }
-
- /// Copies the other type loc into this one.
- void copy(TypeLoc other);
-
- friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
- return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
- }
-
- friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
- return !(LHS == RHS);
- }
-
- /// Find the location of the nullability specifier (__nonnull,
- /// __nullable, or __null_unspecifier), if there is one.
- SourceLocation findNullabilityLoc() const;
-
-private:
- static bool isKind(const TypeLoc&) {
- return true;
- }
-
- static void initializeImpl(ASTContext &Context, TypeLoc TL,
- SourceLocation Loc);
- static TypeLoc getNextTypeLocImpl(TypeLoc TL);
- static TypeLoc IgnoreParensImpl(TypeLoc TL);
- static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
-};
-
-/// \brief Return the TypeLoc for a type source info.
-inline TypeLoc TypeSourceInfo::getTypeLoc() const {
- // TODO: is this alignment already sufficient?
- return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
-}
-
-/// \brief Wrapper of type source information for a type with
-/// no direct qualifiers.
-class UnqualTypeLoc : public TypeLoc {
-public:
- UnqualTypeLoc() {}
- UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
-
- const Type *getTypePtr() const {
- return reinterpret_cast<const Type*>(Ty);
- }
-
- TypeLocClass getTypeLocClass() const {
- return (TypeLocClass) getTypePtr()->getTypeClass();
- }
-
-private:
- friend class TypeLoc;
- static bool isKind(const TypeLoc &TL) {
- return !TL.getType().hasLocalQualifiers();
- }
-};
-
-/// \brief Wrapper of type source information for a type with
-/// non-trivial direct qualifiers.
-///
-/// Currently, we intentionally do not provide source location for
-/// type qualifiers.
-class QualifiedTypeLoc : public TypeLoc {
-public:
- SourceRange getLocalSourceRange() const {
- return SourceRange();
- }
-
- UnqualTypeLoc getUnqualifiedLoc() const {
- unsigned align =
- TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
- uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
- dataInt = llvm::RoundUpToAlignment(dataInt, align);
- return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
- }
-
- /// Initializes the local data of this type source info block to
- /// provide no information.
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- // do nothing
- }
-
- void copyLocal(TypeLoc other) {
- // do nothing
- }
-
- TypeLoc getNextTypeLoc() const {
- return getUnqualifiedLoc();
- }
-
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataSize() const {
- // In fact, we don't currently preserve any location information
- // for qualifiers.
- return 0;
- }
-
- /// \brief Returns the alignment of the type source info data block that is
- /// specific to this type.
- unsigned getLocalDataAlignment() const {
- // We don't preserve any location information.
- return 1;
- }
-
-private:
- friend class TypeLoc;
- static bool isKind(const TypeLoc &TL) {
- return TL.getType().hasLocalQualifiers();
- }
-};
-
-inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
- if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
- return Loc.getUnqualifiedLoc();
- return castAs<UnqualTypeLoc>();
-}
-
-/// A metaprogramming base class for TypeLoc classes which correspond
-/// to a particular Type subclass. It is accepted for a single
-/// TypeLoc class to correspond to multiple Type classes.
-///
-/// \tparam Base a class from which to derive
-/// \tparam Derived the class deriving from this one
-/// \tparam TypeClass the concrete Type subclass associated with this
-/// location type
-/// \tparam LocalData the structure type of local location data for
-/// this type
-///
-/// TypeLocs with non-constant amounts of local data should override
-/// getExtraLocalDataSize(); getExtraLocalData() will then point to
-/// this extra memory.
-///
-/// TypeLocs with an inner type should define
-/// QualType getInnerType() const
-/// and getInnerTypeLoc() will then point to this inner type's
-/// location data.
-///
-/// A word about hierarchies: this template is not designed to be
-/// derived from multiple times in a hierarchy. It is also not
-/// designed to be used for classes where subtypes might provide
-/// different amounts of source information. It should be subclassed
-/// only at the deepest portion of the hierarchy where all children
-/// have identical source information; if that's an abstract type,
-/// then further descendents should inherit from
-/// InheritingConcreteTypeLoc instead.
-template <class Base, class Derived, class TypeClass, class LocalData>
-class ConcreteTypeLoc : public Base {
-
- const Derived *asDerived() const {
- return static_cast<const Derived*>(this);
- }
-
- friend class TypeLoc;
- static bool isKind(const TypeLoc &TL) {
- return !TL.getType().hasLocalQualifiers() &&
- Derived::classofType(TL.getTypePtr());
- }
-
- static bool classofType(const Type *Ty) {
- return TypeClass::classof(Ty);
- }
-
-public:
- unsigned getLocalDataAlignment() const {
- return std::max(llvm::alignOf<LocalData>(),
- asDerived()->getExtraLocalDataAlignment());
- }
- unsigned getLocalDataSize() const {
- unsigned size = sizeof(LocalData);
- unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
- size = llvm::RoundUpToAlignment(size, extraAlign);
- size += asDerived()->getExtraLocalDataSize();
- return size;
- }
-
- void copyLocal(Derived other) {
- // Some subclasses have no data to copy.
- if (asDerived()->getLocalDataSize() == 0) return;
-
- // Copy the fixed-sized local data.
- memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
-
- // Copy the variable-sized local data. We need to do this
- // separately because the padding in the source and the padding in
- // the destination might be different.
- memcpy(getExtraLocalData(), other.getExtraLocalData(),
- asDerived()->getExtraLocalDataSize());
- }
-
- TypeLoc getNextTypeLoc() const {
- return getNextTypeLoc(asDerived()->getInnerType());
- }
-
- const TypeClass *getTypePtr() const {
- return cast<TypeClass>(Base::getTypePtr());
- }
-
-protected:
- unsigned getExtraLocalDataSize() const {
- return 0;
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return 1;
- }
-
- LocalData *getLocalData() const {
- return static_cast<LocalData*>(Base::Data);
- }
-
- /// Gets a pointer past the Info structure; useful for classes with
- /// local data that can't be captured in the Info (e.g. because it's
- /// of variable size).
- void *getExtraLocalData() const {
- unsigned size = sizeof(LocalData);
- unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
- size = llvm::RoundUpToAlignment(size, extraAlign);
- return reinterpret_cast<char*>(Base::Data) + size;
- }
-
- void *getNonLocalData() const {
- uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
- data += asDerived()->getLocalDataSize();
- data = llvm::RoundUpToAlignment(data, getNextTypeAlign());
- return reinterpret_cast<void*>(data);
- }
-
- struct HasNoInnerType {};
- HasNoInnerType getInnerType() const { return HasNoInnerType(); }
-
- TypeLoc getInnerTypeLoc() const {
- return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
- }
-
-private:
- unsigned getInnerTypeSize() const {
- return getInnerTypeSize(asDerived()->getInnerType());
- }
-
- unsigned getInnerTypeSize(HasNoInnerType _) const {
- return 0;
- }
-
- unsigned getInnerTypeSize(QualType _) const {
- return getInnerTypeLoc().getFullDataSize();
- }
-
- unsigned getNextTypeAlign() const {
- return getNextTypeAlign(asDerived()->getInnerType());
- }
-
- unsigned getNextTypeAlign(HasNoInnerType _) const {
- return 1;
- }
-
- unsigned getNextTypeAlign(QualType T) const {
- return TypeLoc::getLocalAlignmentForType(T);
- }
-
- TypeLoc getNextTypeLoc(HasNoInnerType _) const {
- return TypeLoc();
- }
-
- TypeLoc getNextTypeLoc(QualType T) const {
- return TypeLoc(T, getNonLocalData());
- }
-};
-
-/// A metaprogramming class designed for concrete subtypes of abstract
-/// types where all subtypes share equivalently-structured source
-/// information. See the note on ConcreteTypeLoc.
-template <class Base, class Derived, class TypeClass>
-class InheritingConcreteTypeLoc : public Base {
- friend class TypeLoc;
- static bool classofType(const Type *Ty) {
- return TypeClass::classof(Ty);
- }
-
- static bool isKind(const TypeLoc &TL) {
- return !TL.getType().hasLocalQualifiers() &&
- Derived::classofType(TL.getTypePtr());
- }
- static bool isKind(const UnqualTypeLoc &TL) {
- return Derived::classofType(TL.getTypePtr());
- }
-
-public:
- const TypeClass *getTypePtr() const {
- return cast<TypeClass>(Base::getTypePtr());
- }
-};
-
-
-struct TypeSpecLocInfo {
- SourceLocation NameLoc;
-};
-
-/// \brief A reasonable base class for TypeLocs that correspond to
-/// types that are written as a type-specifier.
-class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- TypeSpecTypeLoc,
- Type,
- TypeSpecLocInfo> {
-public:
- enum { LocalDataSize = sizeof(TypeSpecLocInfo),
- LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment };
-
- SourceLocation getNameLoc() const {
- return this->getLocalData()->NameLoc;
- }
- void setNameLoc(SourceLocation Loc) {
- this->getLocalData()->NameLoc = Loc;
- }
- SourceRange getLocalSourceRange() const {
- return SourceRange(getNameLoc(), getNameLoc());
- }
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setNameLoc(Loc);
- }
-
-private:
- friend class TypeLoc;
- static bool isKind(const TypeLoc &TL);
-};
-
-
-struct BuiltinLocInfo {
- SourceLocation BuiltinLoc;
-};
-
-/// \brief Wrapper for source info for builtin types.
-class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- BuiltinTypeLoc,
- BuiltinType,
- BuiltinLocInfo> {
-public:
- SourceLocation getBuiltinLoc() const {
- return getLocalData()->BuiltinLoc;
- }
- void setBuiltinLoc(SourceLocation Loc) {
- getLocalData()->BuiltinLoc = Loc;
- }
-
- SourceLocation getNameLoc() const { return getBuiltinLoc(); }
-
- WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
- return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
- }
- const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
- return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
- }
-
- bool needsExtraLocalData() const {
- BuiltinType::Kind bk = getTypePtr()->getKind();
- return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
- || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
- || bk == BuiltinType::UChar
- || bk == BuiltinType::SChar;
- }
-
- unsigned getExtraLocalDataSize() const {
- return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getBuiltinLoc(), getBuiltinLoc());
- }
-
- TypeSpecifierSign getWrittenSignSpec() const {
- if (needsExtraLocalData())
- return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
- else
- return TSS_unspecified;
- }
- bool hasWrittenSignSpec() const {
- return getWrittenSignSpec() != TSS_unspecified;
- }
- void setWrittenSignSpec(TypeSpecifierSign written) {
- if (needsExtraLocalData())
- getWrittenBuiltinSpecs().Sign = written;
- }
-
- TypeSpecifierWidth getWrittenWidthSpec() const {
- if (needsExtraLocalData())
- return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
- else
- return TSW_unspecified;
- }
- bool hasWrittenWidthSpec() const {
- return getWrittenWidthSpec() != TSW_unspecified;
- }
- void setWrittenWidthSpec(TypeSpecifierWidth written) {
- if (needsExtraLocalData())
- getWrittenBuiltinSpecs().Width = written;
- }
-
- TypeSpecifierType getWrittenTypeSpec() const;
- bool hasWrittenTypeSpec() const {
- return getWrittenTypeSpec() != TST_unspecified;
- }
- void setWrittenTypeSpec(TypeSpecifierType written) {
- if (needsExtraLocalData())
- getWrittenBuiltinSpecs().Type = written;
- }
-
- bool hasModeAttr() const {
- if (needsExtraLocalData())
- return getWrittenBuiltinSpecs().ModeAttr;
- else
- return false;
- }
- void setModeAttr(bool written) {
- if (needsExtraLocalData())
- getWrittenBuiltinSpecs().ModeAttr = written;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setBuiltinLoc(Loc);
- if (needsExtraLocalData()) {
- WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
- wbs.Sign = TSS_unspecified;
- wbs.Width = TSW_unspecified;
- wbs.Type = TST_unspecified;
- wbs.ModeAttr = false;
- }
- }
-};
-
-
-/// \brief Wrapper for source info for typedefs.
-class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- TypedefTypeLoc,
- TypedefType> {
-public:
- TypedefNameDecl *getTypedefNameDecl() const {
- return getTypePtr()->getDecl();
- }
-};
-
-/// \brief Wrapper for source info for injected class names of class
-/// templates.
-class InjectedClassNameTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- InjectedClassNameTypeLoc,
- InjectedClassNameType> {
-public:
- CXXRecordDecl *getDecl() const {
- return getTypePtr()->getDecl();
- }
-};
-
-/// \brief Wrapper for source info for unresolved typename using decls.
-class UnresolvedUsingTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- UnresolvedUsingTypeLoc,
- UnresolvedUsingType> {
-public:
- UnresolvedUsingTypenameDecl *getDecl() const {
- return getTypePtr()->getDecl();
- }
-};
-
-/// \brief Wrapper for source info for tag types. Note that this only
-/// records source info for the name itself; a type written 'struct foo'
-/// should be represented as an ElaboratedTypeLoc. We currently
-/// only do that when C++ is enabled because of the expense of
-/// creating an ElaboratedType node for so many type references in C.
-class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- TagTypeLoc,
- TagType> {
-public:
- TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
-
- /// \brief True if the tag was defined in this type specifier.
- bool isDefinition() const {
- TagDecl *D = getDecl();
- return D->isCompleteDefinition() &&
- (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
- }
-};
-
-/// \brief Wrapper for source info for record types.
-class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
- RecordTypeLoc,
- RecordType> {
-public:
- RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
-};
-
-/// \brief Wrapper for source info for enum types.
-class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
- EnumTypeLoc,
- EnumType> {
-public:
- EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
-};
-
-/// \brief Wrapper for template type parameters.
-class TemplateTypeParmTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- TemplateTypeParmTypeLoc,
- TemplateTypeParmType> {
-public:
- TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
-};
-
-/// \brief Wrapper for substituted template type parameters.
-class SubstTemplateTypeParmTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- SubstTemplateTypeParmTypeLoc,
- SubstTemplateTypeParmType> {
-};
-
- /// \brief Wrapper for substituted template type parameters.
-class SubstTemplateTypeParmPackTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- SubstTemplateTypeParmPackTypeLoc,
- SubstTemplateTypeParmPackType> {
-};
-
-struct AttributedLocInfo {
- union {
- Expr *ExprOperand;
-
- /// A raw SourceLocation.
- unsigned EnumOperandLoc;
- };
-
- SourceRange OperandParens;
-
- SourceLocation AttrLoc;
-};
-
-/// \brief Type source information for an attributed type.
-class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- AttributedTypeLoc,
- AttributedType,
- AttributedLocInfo> {
-public:
- AttributedType::Kind getAttrKind() const {
- return getTypePtr()->getAttrKind();
- }
-
- bool hasAttrExprOperand() const {
- return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
- getAttrKind() <= AttributedType::LastExprOperandKind);
- }
-
- bool hasAttrEnumOperand() const {
- return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
- getAttrKind() <= AttributedType::LastEnumOperandKind);
- }
-
- bool hasAttrOperand() const {
- return hasAttrExprOperand() || hasAttrEnumOperand();
- }
-
- bool isQualifier() const {
- return getTypePtr()->isQualifier();
- }
-
- /// The modified type, which is generally canonically different from
- /// the attribute type.
- /// int main(int, char**) __attribute__((noreturn))
- /// ~~~ ~~~~~~~~~~~~~
- TypeLoc getModifiedLoc() const {
- return getInnerTypeLoc();
- }
-
- /// The location of the attribute name, i.e.
- /// __attribute__((regparm(1000)))
- /// ^~~~~~~
- SourceLocation getAttrNameLoc() const {
- return getLocalData()->AttrLoc;
- }
- void setAttrNameLoc(SourceLocation loc) {
- getLocalData()->AttrLoc = loc;
- }
-
- /// The attribute's expression operand, if it has one.
- /// void *cur_thread __attribute__((address_space(21)))
- /// ^~
- Expr *getAttrExprOperand() const {
- assert(hasAttrExprOperand());
- return getLocalData()->ExprOperand;
- }
- void setAttrExprOperand(Expr *e) {
- assert(hasAttrExprOperand());
- getLocalData()->ExprOperand = e;
- }
-
- /// The location of the attribute's enumerated operand, if it has one.
- /// void * __attribute__((objc_gc(weak)))
- /// ^~~~
- SourceLocation getAttrEnumOperandLoc() const {
- assert(hasAttrEnumOperand());
- return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
- }
- void setAttrEnumOperandLoc(SourceLocation loc) {
- assert(hasAttrEnumOperand());
- getLocalData()->EnumOperandLoc = loc.getRawEncoding();
- }
-
- /// The location of the parentheses around the operand, if there is
- /// an operand.
- /// void * __attribute__((objc_gc(weak)))
- /// ^ ^
- SourceRange getAttrOperandParensRange() const {
- assert(hasAttrOperand());
- return getLocalData()->OperandParens;
- }
- void setAttrOperandParensRange(SourceRange range) {
- assert(hasAttrOperand());
- getLocalData()->OperandParens = range;
- }
-
- SourceRange getLocalSourceRange() const {
- // Note that this does *not* include the range of the attribute
- // enclosure, e.g.:
- // __attribute__((foo(bar)))
- // ^~~~~~~~~~~~~~~ ~~
- // or
- // [[foo(bar)]]
- // ^~ ~~
- // That enclosure doesn't necessarily belong to a single attribute
- // anyway.
- SourceRange range(getAttrNameLoc());
- if (hasAttrOperand())
- range.setEnd(getAttrOperandParensRange().getEnd());
- return range;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation loc) {
- setAttrNameLoc(loc);
- if (hasAttrExprOperand()) {
- setAttrOperandParensRange(SourceRange(loc));
- setAttrExprOperand(nullptr);
- } else if (hasAttrEnumOperand()) {
- setAttrOperandParensRange(SourceRange(loc));
- setAttrEnumOperandLoc(loc);
- }
- }
-
- QualType getInnerType() const {
- return getTypePtr()->getModifiedType();
- }
-};
-
-
-struct ObjCObjectTypeLocInfo {
- SourceLocation TypeArgsLAngleLoc;
- SourceLocation TypeArgsRAngleLoc;
- SourceLocation ProtocolLAngleLoc;
- SourceLocation ProtocolRAngleLoc;
- bool HasBaseTypeAsWritten;
-};
-
-// A helper class for defining ObjC TypeLocs that can qualified with
-// protocols.
-//
-// TypeClass basically has to be either ObjCInterfaceType or
-// ObjCObjectPointerType.
-class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- ObjCObjectTypeLoc,
- ObjCObjectType,
- ObjCObjectTypeLocInfo> {
- // TypeSourceInfo*'s are stored after Info, one for each type argument.
- TypeSourceInfo **getTypeArgLocArray() const {
- return (TypeSourceInfo**)this->getExtraLocalData();
- }
-
- // SourceLocations are stored after the type argument information, one for
- // each Protocol.
- SourceLocation *getProtocolLocArray() const {
- return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
- }
-
-public:
- SourceLocation getTypeArgsLAngleLoc() const {
- return this->getLocalData()->TypeArgsLAngleLoc;
- }
- void setTypeArgsLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->TypeArgsLAngleLoc = Loc;
- }
-
- SourceLocation getTypeArgsRAngleLoc() const {
- return this->getLocalData()->TypeArgsRAngleLoc;
- }
- void setTypeArgsRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->TypeArgsRAngleLoc = Loc;
- }
-
- unsigned getNumTypeArgs() const {
- return this->getTypePtr()->getTypeArgsAsWritten().size();
- }
-
- TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
- assert(i < getNumTypeArgs() && "Index is out of bounds!");
- return getTypeArgLocArray()[i];
- }
-
- void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
- assert(i < getNumTypeArgs() && "Index is out of bounds!");
- getTypeArgLocArray()[i] = TInfo;
- }
-
- SourceLocation getProtocolLAngleLoc() const {
- return this->getLocalData()->ProtocolLAngleLoc;
- }
- void setProtocolLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->ProtocolLAngleLoc = Loc;
- }
-
- SourceLocation getProtocolRAngleLoc() const {
- return this->getLocalData()->ProtocolRAngleLoc;
- }
- void setProtocolRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->ProtocolRAngleLoc = Loc;
- }
-
- unsigned getNumProtocols() const {
- return this->getTypePtr()->getNumProtocols();
- }
-
- SourceLocation getProtocolLoc(unsigned i) const {
- assert(i < getNumProtocols() && "Index is out of bounds!");
- return getProtocolLocArray()[i];
- }
- void setProtocolLoc(unsigned i, SourceLocation Loc) {
- assert(i < getNumProtocols() && "Index is out of bounds!");
- getProtocolLocArray()[i] = Loc;
- }
-
- ObjCProtocolDecl *getProtocol(unsigned i) const {
- assert(i < getNumProtocols() && "Index is out of bounds!");
- return *(this->getTypePtr()->qual_begin() + i);
- }
-
-
- ArrayRef<SourceLocation> getProtocolLocs() const {
- return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
- }
-
- bool hasBaseTypeAsWritten() const {
- return getLocalData()->HasBaseTypeAsWritten;
- }
-
- void setHasBaseTypeAsWritten(bool HasBaseType) {
- getLocalData()->HasBaseTypeAsWritten = HasBaseType;
- }
-
- TypeLoc getBaseLoc() const {
- return getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- SourceLocation start = getTypeArgsLAngleLoc();
- if (start.isInvalid())
- start = getProtocolLAngleLoc();
- SourceLocation end = getProtocolRAngleLoc();
- if (end.isInvalid())
- end = getTypeArgsRAngleLoc();
- return SourceRange(start, end);
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
- + this->getNumProtocols() * sizeof(SourceLocation);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- assert(llvm::alignOf<ObjCObjectTypeLoc>()
- >= llvm::alignOf<TypeSourceInfo *>() &&
- "not enough alignment for tail-allocated data");
- return llvm::alignOf<TypeSourceInfo *>();
- }
-
- QualType getInnerType() const {
- return getTypePtr()->getBaseType();
- }
-};
-
-
-struct ObjCInterfaceLocInfo {
- SourceLocation NameLoc;
- SourceLocation NameEndLoc;
-};
-
-/// \brief Wrapper for source info for ObjC interfaces.
-class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
- ObjCInterfaceTypeLoc,
- ObjCInterfaceType,
- ObjCInterfaceLocInfo> {
-public:
- ObjCInterfaceDecl *getIFaceDecl() const {
- return getTypePtr()->getDecl();
- }
-
- SourceLocation getNameLoc() const {
- return getLocalData()->NameLoc;
- }
-
- void setNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getNameLoc(), getNameEndLoc());
- }
-
- SourceLocation getNameEndLoc() const {
- return getLocalData()->NameEndLoc;
- }
-
- void setNameEndLoc(SourceLocation Loc) {
- getLocalData()->NameEndLoc = Loc;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setNameLoc(Loc);
- setNameEndLoc(Loc);
- }
-};
-
-struct ParenLocInfo {
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
-};
-
-class ParenTypeLoc
- : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
- ParenLocInfo> {
-public:
- SourceLocation getLParenLoc() const {
- return this->getLocalData()->LParenLoc;
- }
- SourceLocation getRParenLoc() const {
- return this->getLocalData()->RParenLoc;
- }
- void setLParenLoc(SourceLocation Loc) {
- this->getLocalData()->LParenLoc = Loc;
- }
- void setRParenLoc(SourceLocation Loc) {
- this->getLocalData()->RParenLoc = Loc;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setLParenLoc(Loc);
- setRParenLoc(Loc);
- }
-
- TypeLoc getInnerLoc() const {
- return getInnerTypeLoc();
- }
-
- QualType getInnerType() const {
- return this->getTypePtr()->getInnerType();
- }
-};
-
-inline TypeLoc TypeLoc::IgnoreParens() const {
- if (ParenTypeLoc::isKind(*this))
- return IgnoreParensImpl(*this);
- return *this;
-}
-
-
-struct AdjustedLocInfo { }; // Nothing.
-
-class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
- AdjustedType, AdjustedLocInfo> {
-public:
- TypeLoc getOriginalLoc() const {
- return getInnerTypeLoc();
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- // do nothing
- }
-
- QualType getInnerType() const {
- // The inner type is the undecayed type, since that's what we have source
- // location information for.
- return getTypePtr()->getOriginalType();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange();
- }
-
- unsigned getLocalDataSize() const {
- // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
- // anyway. TypeLocBuilder can't handle data sizes of 1.
- return 0; // No data.
- }
-};
-
-/// \brief Wrapper for source info for pointers decayed from arrays and
-/// functions.
-class DecayedTypeLoc : public InheritingConcreteTypeLoc<
- AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
-};
-
-struct PointerLikeLocInfo {
- SourceLocation StarLoc;
-};
-
-/// A base class for
-template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
-class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
- TypeClass, LocalData> {
-public:
- SourceLocation getSigilLoc() const {
- return this->getLocalData()->StarLoc;
- }
- void setSigilLoc(SourceLocation Loc) {
- this->getLocalData()->StarLoc = Loc;
- }
-
- TypeLoc getPointeeLoc() const {
- return this->getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getSigilLoc(), getSigilLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-
- QualType getInnerType() const {
- return this->getTypePtr()->getPointeeType();
- }
-};
-
-
-/// \brief Wrapper for source info for pointers.
-class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
- PointerType> {
-public:
- SourceLocation getStarLoc() const {
- return getSigilLoc();
- }
- void setStarLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-
-/// \brief Wrapper for source info for block pointers.
-class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
- BlockPointerType> {
-public:
- SourceLocation getCaretLoc() const {
- return getSigilLoc();
- }
- void setCaretLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-struct MemberPointerLocInfo : public PointerLikeLocInfo {
- TypeSourceInfo *ClassTInfo;
-};
-
-/// \brief Wrapper for source info for member pointers.
-class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
- MemberPointerType,
- MemberPointerLocInfo> {
-public:
- SourceLocation getStarLoc() const {
- return getSigilLoc();
- }
- void setStarLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-
- const Type *getClass() const {
- return getTypePtr()->getClass();
- }
- TypeSourceInfo *getClassTInfo() const {
- return getLocalData()->ClassTInfo;
- }
- void setClassTInfo(TypeSourceInfo* TI) {
- getLocalData()->ClassTInfo = TI;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setSigilLoc(Loc);
- setClassTInfo(nullptr);
- }
-
- SourceRange getLocalSourceRange() const {
- if (TypeSourceInfo *TI = getClassTInfo())
- return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
- else
- return SourceRange(getStarLoc());
- }
-};
-
-/// Wraps an ObjCPointerType with source location information.
-class ObjCObjectPointerTypeLoc :
- public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
- ObjCObjectPointerType> {
-public:
- SourceLocation getStarLoc() const {
- return getSigilLoc();
- }
-
- void setStarLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-
-class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
- ReferenceType> {
-public:
- QualType getInnerType() const {
- return getTypePtr()->getPointeeTypeAsWritten();
- }
-};
-
-class LValueReferenceTypeLoc :
- public InheritingConcreteTypeLoc<ReferenceTypeLoc,
- LValueReferenceTypeLoc,
- LValueReferenceType> {
-public:
- SourceLocation getAmpLoc() const {
- return getSigilLoc();
- }
- void setAmpLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-class RValueReferenceTypeLoc :
- public InheritingConcreteTypeLoc<ReferenceTypeLoc,
- RValueReferenceTypeLoc,
- RValueReferenceType> {
-public:
- SourceLocation getAmpAmpLoc() const {
- return getSigilLoc();
- }
- void setAmpAmpLoc(SourceLocation Loc) {
- setSigilLoc(Loc);
- }
-};
-
-
-struct FunctionLocInfo {
- SourceLocation LocalRangeBegin;
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
- SourceLocation LocalRangeEnd;
-};
-
-/// \brief Wrapper for source info for functions.
-class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- FunctionTypeLoc,
- FunctionType,
- FunctionLocInfo> {
-public:
- SourceLocation getLocalRangeBegin() const {
- return getLocalData()->LocalRangeBegin;
- }
- void setLocalRangeBegin(SourceLocation L) {
- getLocalData()->LocalRangeBegin = L;
- }
-
- SourceLocation getLocalRangeEnd() const {
- return getLocalData()->LocalRangeEnd;
- }
- void setLocalRangeEnd(SourceLocation L) {
- getLocalData()->LocalRangeEnd = L;
- }
-
- SourceLocation getLParenLoc() const {
- return this->getLocalData()->LParenLoc;
- }
- void setLParenLoc(SourceLocation Loc) {
- this->getLocalData()->LParenLoc = Loc;
- }
-
- SourceLocation getRParenLoc() const {
- return this->getLocalData()->RParenLoc;
- }
- void setRParenLoc(SourceLocation Loc) {
- this->getLocalData()->RParenLoc = Loc;
- }
-
- SourceRange getParensRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
-
- ArrayRef<ParmVarDecl *> getParams() const {
- return llvm::makeArrayRef(getParmArray(), getNumParams());
- }
-
- // ParmVarDecls* are stored after Info, one for each parameter.
- ParmVarDecl **getParmArray() const {
- return (ParmVarDecl**) getExtraLocalData();
- }
-
- unsigned getNumParams() const {
- if (isa<FunctionNoProtoType>(getTypePtr()))
- return 0;
- return cast<FunctionProtoType>(getTypePtr())->getNumParams();
- }
- ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
- void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
-
- TypeLoc getReturnLoc() const {
- return getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setLocalRangeBegin(Loc);
- setLParenLoc(Loc);
- setRParenLoc(Loc);
- setLocalRangeEnd(Loc);
- for (unsigned i = 0, e = getNumParams(); i != e; ++i)
- setParam(i, nullptr);
- }
-
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getExtraLocalDataSize() const {
- return getNumParams() * sizeof(ParmVarDecl *);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return llvm::alignOf<ParmVarDecl*>();
- }
-
- QualType getInnerType() const { return getTypePtr()->getReturnType(); }
-};
-
-class FunctionProtoTypeLoc :
- public InheritingConcreteTypeLoc<FunctionTypeLoc,
- FunctionProtoTypeLoc,
- FunctionProtoType> {
-};
-
-class FunctionNoProtoTypeLoc :
- public InheritingConcreteTypeLoc<FunctionTypeLoc,
- FunctionNoProtoTypeLoc,
- FunctionNoProtoType> {
-};
-
-
-struct ArrayLocInfo {
- SourceLocation LBracketLoc, RBracketLoc;
- Expr *Size;
-};
-
-/// \brief Wrapper for source info for arrays.
-class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- ArrayTypeLoc,
- ArrayType,
- ArrayLocInfo> {
-public:
- SourceLocation getLBracketLoc() const {
- return getLocalData()->LBracketLoc;
- }
- void setLBracketLoc(SourceLocation Loc) {
- getLocalData()->LBracketLoc = Loc;
- }
-
- SourceLocation getRBracketLoc() const {
- return getLocalData()->RBracketLoc;
- }
- void setRBracketLoc(SourceLocation Loc) {
- getLocalData()->RBracketLoc = Loc;
- }
-
- SourceRange getBracketsRange() const {
- return SourceRange(getLBracketLoc(), getRBracketLoc());
- }
-
- Expr *getSizeExpr() const {
- return getLocalData()->Size;
- }
- void setSizeExpr(Expr *Size) {
- getLocalData()->Size = Size;
- }
-
- TypeLoc getElementLoc() const {
- return getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getLBracketLoc(), getRBracketLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setLBracketLoc(Loc);
- setRBracketLoc(Loc);
- setSizeExpr(nullptr);
- }
-
- QualType getInnerType() const { return getTypePtr()->getElementType(); }
-};
-
-class ConstantArrayTypeLoc :
- public InheritingConcreteTypeLoc<ArrayTypeLoc,
- ConstantArrayTypeLoc,
- ConstantArrayType> {
-};
-
-class IncompleteArrayTypeLoc :
- public InheritingConcreteTypeLoc<ArrayTypeLoc,
- IncompleteArrayTypeLoc,
- IncompleteArrayType> {
-};
-
-class DependentSizedArrayTypeLoc :
- public InheritingConcreteTypeLoc<ArrayTypeLoc,
- DependentSizedArrayTypeLoc,
- DependentSizedArrayType> {
-
-};
-
-class VariableArrayTypeLoc :
- public InheritingConcreteTypeLoc<ArrayTypeLoc,
- VariableArrayTypeLoc,
- VariableArrayType> {
-};
-
-
-// Location information for a TemplateName. Rudimentary for now.
-struct TemplateNameLocInfo {
- SourceLocation NameLoc;
-};
-
-struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
- SourceLocation TemplateKWLoc;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
-};
-
-class TemplateSpecializationTypeLoc :
- public ConcreteTypeLoc<UnqualTypeLoc,
- TemplateSpecializationTypeLoc,
- TemplateSpecializationType,
- TemplateSpecializationLocInfo> {
-public:
- SourceLocation getTemplateKeywordLoc() const {
- return getLocalData()->TemplateKWLoc;
- }
- void setTemplateKeywordLoc(SourceLocation Loc) {
- getLocalData()->TemplateKWLoc = Loc;
- }
-
- SourceLocation getLAngleLoc() const {
- return getLocalData()->LAngleLoc;
- }
- void setLAngleLoc(SourceLocation Loc) {
- getLocalData()->LAngleLoc = Loc;
- }
-
- SourceLocation getRAngleLoc() const {
- return getLocalData()->RAngleLoc;
- }
- void setRAngleLoc(SourceLocation Loc) {
- getLocalData()->RAngleLoc = Loc;
- }
-
- unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
- }
- void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
- getArgInfos()[i] = AI;
- }
- TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
- return getArgInfos()[i];
- }
-
- TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
- }
-
- SourceLocation getTemplateNameLoc() const {
- return getLocalData()->NameLoc;
- }
- void setTemplateNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
- }
-
- /// \brief - Copy the location information from the given info.
- void copy(TemplateSpecializationTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
-
- // We're potentially copying Expr references here. We don't
- // bother retaining them because TypeSourceInfos live forever, so
- // as long as the Expr was retained when originally written into
- // the TypeLoc, we're okay.
- memcpy(Data, Loc.Data, size);
- }
-
- SourceRange getLocalSourceRange() const {
- if (getTemplateKeywordLoc().isValid())
- return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
- else
- return SourceRange(getTemplateNameLoc(), getRAngleLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setTemplateKeywordLoc(Loc);
- setTemplateNameLoc(Loc);
- setLAngleLoc(Loc);
- setRAngleLoc(Loc);
- initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
- getArgInfos(), Loc);
- }
-
- static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
- const TemplateArgument *Args,
- TemplateArgumentLocInfo *ArgInfos,
- SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return getNumArgs() * sizeof(TemplateArgumentLocInfo);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return llvm::alignOf<TemplateArgumentLocInfo>();
- }
-
-private:
- TemplateArgumentLocInfo *getArgInfos() const {
- return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
- }
-};
-
-//===----------------------------------------------------------------------===//
-//
-// All of these need proper implementations.
-//
-//===----------------------------------------------------------------------===//
-
-// FIXME: size expression and attribute locations (or keyword if we
-// ever fully support altivec syntax).
-class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- VectorTypeLoc,
- VectorType> {
-};
-
-// FIXME: size expression and attribute locations.
-class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
- ExtVectorTypeLoc,
- ExtVectorType> {
-};
-
-// FIXME: attribute locations.
-// For some reason, this isn't a subtype of VectorType.
-class DependentSizedExtVectorTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- DependentSizedExtVectorTypeLoc,
- DependentSizedExtVectorType> {
-};
-
-// FIXME: location of the '_Complex' keyword.
-class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- ComplexTypeLoc,
- ComplexType> {
-};
-
-struct TypeofLocInfo {
- SourceLocation TypeofLoc;
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
-};
-
-struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
-};
-
-struct TypeOfTypeLocInfo : public TypeofLocInfo {
- TypeSourceInfo* UnderlyingTInfo;
-};
-
-template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
-class TypeofLikeTypeLoc
- : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
-public:
- SourceLocation getTypeofLoc() const {
- return this->getLocalData()->TypeofLoc;
- }
- void setTypeofLoc(SourceLocation Loc) {
- this->getLocalData()->TypeofLoc = Loc;
- }
-
- SourceLocation getLParenLoc() const {
- return this->getLocalData()->LParenLoc;
- }
- void setLParenLoc(SourceLocation Loc) {
- this->getLocalData()->LParenLoc = Loc;
- }
-
- SourceLocation getRParenLoc() const {
- return this->getLocalData()->RParenLoc;
- }
- void setRParenLoc(SourceLocation Loc) {
- this->getLocalData()->RParenLoc = Loc;
- }
-
- SourceRange getParensRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
- void setParensRange(SourceRange range) {
- setLParenLoc(range.getBegin());
- setRParenLoc(range.getEnd());
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getTypeofLoc(), getRParenLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setTypeofLoc(Loc);
- setLParenLoc(Loc);
- setRParenLoc(Loc);
- }
-};
-
-class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
- TypeOfExprType,
- TypeOfExprTypeLocInfo> {
-public:
- Expr* getUnderlyingExpr() const {
- return getTypePtr()->getUnderlyingExpr();
- }
- // Reimplemented to account for GNU/C++ extension
- // typeof unary-expression
- // where there are no parentheses.
- SourceRange getLocalSourceRange() const;
-};
-
-class TypeOfTypeLoc
- : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
-public:
- QualType getUnderlyingType() const {
- return this->getTypePtr()->getUnderlyingType();
- }
- TypeSourceInfo* getUnderlyingTInfo() const {
- return this->getLocalData()->UnderlyingTInfo;
- }
- void setUnderlyingTInfo(TypeSourceInfo* TI) const {
- this->getLocalData()->UnderlyingTInfo = TI;
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-};
-
-// FIXME: location of the 'decltype' and parens.
-class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- DecltypeTypeLoc,
- DecltypeType> {
-public:
- Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
-};
-
-struct UnaryTransformTypeLocInfo {
- // FIXME: While there's only one unary transform right now, future ones may
- // need different representations
- SourceLocation KWLoc, LParenLoc, RParenLoc;
- TypeSourceInfo *UnderlyingTInfo;
-};
-
-class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- UnaryTransformTypeLoc,
- UnaryTransformType,
- UnaryTransformTypeLocInfo> {
-public:
- SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
- void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
-
- SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
- void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
-
- SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
- void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
-
- TypeSourceInfo* getUnderlyingTInfo() const {
- return getLocalData()->UnderlyingTInfo;
- }
- void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
- getLocalData()->UnderlyingTInfo = TInfo;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getKWLoc(), getRParenLoc());
- }
-
- SourceRange getParensRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
- void setParensRange(SourceRange Range) {
- setLParenLoc(Range.getBegin());
- setRParenLoc(Range.getEnd());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setKWLoc(Loc);
- setRParenLoc(Loc);
- setLParenLoc(Loc);
- }
-};
-
-class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- AutoTypeLoc,
- AutoType> {
-};
-
-struct ElaboratedLocInfo {
- SourceLocation ElaboratedKWLoc;
- /// \brief Data associated with the nested-name-specifier location.
- void *QualifierData;
-};
-
-class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- ElaboratedTypeLoc,
- ElaboratedType,
- ElaboratedLocInfo> {
-public:
- SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
- }
- void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
- }
-
- NestedNameSpecifierLoc getQualifierLoc() const {
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
- }
-
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier()
- == getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
- }
-
- SourceRange getLocalSourceRange() const {
- if (getElaboratedKeywordLoc().isValid())
- if (getQualifierLoc())
- return SourceRange(getElaboratedKeywordLoc(),
- getQualifierLoc().getEndLoc());
- else
- return SourceRange(getElaboratedKeywordLoc());
- else
- return getQualifierLoc().getSourceRange();
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- TypeLoc getNamedTypeLoc() const {
- return getInnerTypeLoc();
- }
-
- QualType getInnerType() const {
- return getTypePtr()->getNamedType();
- }
-
- void copy(ElaboratedTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
- memcpy(Data, Loc.Data, size);
- }
-};
-
-// This is exactly the structure of an ElaboratedTypeLoc whose inner
-// type is some sort of TypeDeclTypeLoc.
-struct DependentNameLocInfo : ElaboratedLocInfo {
- SourceLocation NameLoc;
-};
-
-class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- DependentNameTypeLoc,
- DependentNameType,
- DependentNameLocInfo> {
-public:
- SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
- }
- void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
- }
-
- NestedNameSpecifierLoc getQualifierLoc() const {
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
- }
-
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier()
- == getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
- }
-
- SourceLocation getNameLoc() const {
- return this->getLocalData()->NameLoc;
- }
- void setNameLoc(SourceLocation Loc) {
- this->getLocalData()->NameLoc = Loc;
- }
-
- SourceRange getLocalSourceRange() const {
- if (getElaboratedKeywordLoc().isValid())
- return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
- else
- return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
- }
-
- void copy(DependentNameTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
- memcpy(Data, Loc.Data, size);
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-};
-
-struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
- SourceLocation TemplateKWLoc;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
- // followed by a TemplateArgumentLocInfo[]
-};
-
-class DependentTemplateSpecializationTypeLoc :
- public ConcreteTypeLoc<UnqualTypeLoc,
- DependentTemplateSpecializationTypeLoc,
- DependentTemplateSpecializationType,
- DependentTemplateSpecializationLocInfo> {
-public:
- SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
- }
- void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
- }
-
- NestedNameSpecifierLoc getQualifierLoc() const {
- if (!getLocalData()->QualifierData)
- return NestedNameSpecifierLoc();
-
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
- }
-
- void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- if (!QualifierLoc) {
- // Even if we have a nested-name-specifier in the dependent
- // template specialization type, we won't record the nested-name-specifier
- // location information when this type-source location information is
- // part of a nested-name-specifier.
- getLocalData()->QualifierData = nullptr;
- return;
- }
-
- assert(QualifierLoc.getNestedNameSpecifier()
- == getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
- }
-
- SourceLocation getTemplateKeywordLoc() const {
- return getLocalData()->TemplateKWLoc;
- }
- void setTemplateKeywordLoc(SourceLocation Loc) {
- getLocalData()->TemplateKWLoc = Loc;
- }
-
- SourceLocation getTemplateNameLoc() const {
- return this->getLocalData()->NameLoc;
- }
- void setTemplateNameLoc(SourceLocation Loc) {
- this->getLocalData()->NameLoc = Loc;
- }
-
- SourceLocation getLAngleLoc() const {
- return this->getLocalData()->LAngleLoc;
- }
- void setLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->LAngleLoc = Loc;
- }
-
- SourceLocation getRAngleLoc() const {
- return this->getLocalData()->RAngleLoc;
- }
- void setRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->RAngleLoc = Loc;
- }
-
- unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
- }
-
- void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
- getArgInfos()[i] = AI;
- }
- TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
- return getArgInfos()[i];
- }
-
- TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
- }
-
- SourceRange getLocalSourceRange() const {
- if (getElaboratedKeywordLoc().isValid())
- return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
- else if (getQualifierLoc())
- return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
- else if (getTemplateKeywordLoc().isValid())
- return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
- else
- return SourceRange(getTemplateNameLoc(), getRAngleLoc());
- }
-
- void copy(DependentTemplateSpecializationTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
- memcpy(Data, Loc.Data, size);
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return getNumArgs() * sizeof(TemplateArgumentLocInfo);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return llvm::alignOf<TemplateArgumentLocInfo>();
- }
-
-private:
- TemplateArgumentLocInfo *getArgInfos() const {
- return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
- }
-};
-
-
-struct PackExpansionTypeLocInfo {
- SourceLocation EllipsisLoc;
-};
-
-class PackExpansionTypeLoc
- : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
- PackExpansionType, PackExpansionTypeLocInfo> {
-public:
- SourceLocation getEllipsisLoc() const {
- return this->getLocalData()->EllipsisLoc;
- }
-
- void setEllipsisLoc(SourceLocation Loc) {
- this->getLocalData()->EllipsisLoc = Loc;
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getEllipsisLoc(), getEllipsisLoc());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setEllipsisLoc(Loc);
- }
-
- TypeLoc getPatternLoc() const {
- return getInnerTypeLoc();
- }
-
- QualType getInnerType() const {
- return this->getTypePtr()->getPattern();
- }
-};
-
-struct AtomicTypeLocInfo {
- SourceLocation KWLoc, LParenLoc, RParenLoc;
-};
-
-class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
- AtomicType, AtomicTypeLocInfo> {
-public:
- TypeLoc getValueLoc() const {
- return this->getInnerTypeLoc();
- }
-
- SourceRange getLocalSourceRange() const {
- return SourceRange(getKWLoc(), getRParenLoc());
- }
-
- SourceLocation getKWLoc() const {
- return this->getLocalData()->KWLoc;
- }
- void setKWLoc(SourceLocation Loc) {
- this->getLocalData()->KWLoc = Loc;
- }
-
- SourceLocation getLParenLoc() const {
- return this->getLocalData()->LParenLoc;
- }
- void setLParenLoc(SourceLocation Loc) {
- this->getLocalData()->LParenLoc = Loc;
- }
-
- SourceLocation getRParenLoc() const {
- return this->getLocalData()->RParenLoc;
- }
- void setRParenLoc(SourceLocation Loc) {
- this->getLocalData()->RParenLoc = Loc;
- }
-
- SourceRange getParensRange() const {
- return SourceRange(getLParenLoc(), getRParenLoc());
- }
- void setParensRange(SourceRange Range) {
- setLParenLoc(Range.getBegin());
- setRParenLoc(Range.getEnd());
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setKWLoc(Loc);
- setLParenLoc(Loc);
- setRParenLoc(Loc);
- }
-
- QualType getInnerType() const {
- return this->getTypePtr()->getValueType();
- }
-};
-
-
-}
-
-#endif
diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
deleted file mode 100644
index 4590e48..0000000
--- a/include/clang/AST/TypeLocNodes.def
+++ /dev/null
@@ -1,41 +0,0 @@
-//===-- TypeLocNodes.def - Metadata about TypeLoc wrappers ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TypeLoc info database. Each node is
-// enumerated by providing its core name (e.g., "Pointer" for "PointerTypeLoc")
-// and base class (e.g., "DeclaratorLoc"). All nodes except QualifiedTypeLoc
-// are associated
-//
-// TYPELOC(Class, Base) - A TypeLoc subclass. If UNQUAL_TYPELOC is
-// provided, there will be exactly one of these, Qualified.
-//
-// UNQUAL_TYPELOC(Class, Base, Type) - An UnqualTypeLoc subclass.
-//
-// ABSTRACT_TYPELOC(Class) - Refers to TypeSpecLoc and DeclaratorLoc.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef UNQUAL_TYPELOC
-# define UNQUAL_TYPELOC(Class, Base) TYPELOC(Class, Base)
-#endif
-
-#ifndef ABSTRACT_TYPELOC
-# define ABSTRACT_TYPELOC(Class, Base) UNQUAL_TYPELOC(Class, Base)
-#endif
-
-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"
-
-#undef DECLARATOR_TYPELOC
-#undef TYPESPEC_TYPELOC
-#undef ABSTRACT_TYPELOC
-#undef UNQUAL_TYPELOC
-#undef TYPELOC
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
deleted file mode 100644
index db5775a..0000000
--- a/include/clang/AST/TypeLocVisitor.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===--- TypeLocVisitor.h - Visitor for TypeLoc subclasses ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TypeLocVisitor interface.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_AST_TYPELOCVISITOR_H
-#define LLVM_CLANG_AST_TYPELOCVISITOR_H
-
-#include "clang/AST/TypeLoc.h"
-#include "clang/AST/TypeVisitor.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
-
-#define DISPATCH(CLASSNAME) \
- return static_cast<ImplClass*>(this)-> \
- Visit##CLASSNAME(TyLoc.castAs<CLASSNAME>())
-
-template<typename ImplClass, typename RetTy=void>
-class TypeLocVisitor {
-public:
- RetTy Visit(TypeLoc TyLoc) {
- switch (TyLoc.getTypeLocClass()) {
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
- case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
-#include "clang/AST/TypeLocNodes.def"
- }
- llvm_unreachable("unexpected type loc class!");
- }
-
- RetTy Visit(UnqualTypeLoc TyLoc) {
- switch (TyLoc.getTypeLocClass()) {
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
- case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
-#include "clang/AST/TypeLocNodes.def"
- }
- llvm_unreachable("unexpected type loc class!");
- }
-
-#define TYPELOC(CLASS, PARENT) \
- RetTy Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- DISPATCH(PARENT); \
- }
-#include "clang/AST/TypeLocNodes.def"
-
- RetTy VisitTypeLoc(TypeLoc TyLoc) { return RetTy(); }
-};
-
-#undef DISPATCH
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_TYPELOCVISITOR_H
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
deleted file mode 100644
index 2549f0b..0000000
--- a/include/clang/AST/TypeNodes.def
+++ /dev/null
@@ -1,129 +0,0 @@
-//===-- TypeNodes.def - Metadata about Type AST nodes -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// 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 alises 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)
-TYPE(Vector, 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(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)
-TYPE(Auto, Type)
-DEPENDENT_TYPE(InjectedClassName, Type)
-DEPENDENT_TYPE(DependentName, Type)
-DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
-NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type)
-TYPE(ObjCObject, Type)
-TYPE(ObjCInterface, ObjCObjectType)
-TYPE(ObjCObjectPointer, 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/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
deleted file mode 100644
index 392e544..0000000
--- a/include/clang/AST/TypeOrdering.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-------------- TypeOrdering.h - Total ordering for types -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Allows QualTypes to be sorted and hence used in maps and sets.
-///
-/// Defines clang::QualTypeOrdering, a total ordering on clang::QualType,
-/// and hence enables QualType values to be sorted and to be used in
-/// std::maps, std::sets, llvm::DenseMaps, and llvm::DenseSets.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TYPEORDERING_H
-#define LLVM_CLANG_AST_TYPEORDERING_H
-
-#include "clang/AST/CanonicalType.h"
-#include "clang/AST/Type.h"
-#include <functional>
-
-namespace clang {
-
-/// \brief Function object that provides a total ordering on QualType values.
-struct QualTypeOrdering : std::binary_function<QualType, QualType, bool> {
- bool operator()(QualType T1, QualType T2) const {
- return std::less<void*>()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr());
- }
-};
-
-}
-
-namespace llvm {
- template<class> struct DenseMapInfo;
-
- template<> struct DenseMapInfo<clang::QualType> {
- static inline clang::QualType getEmptyKey() { return clang::QualType(); }
-
- static inline clang::QualType getTombstoneKey() {
- using clang::QualType;
- return QualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
- }
-
- static unsigned getHashValue(clang::QualType Val) {
- return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
- ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
- }
-
- static bool isEqual(clang::QualType LHS, clang::QualType RHS) {
- return LHS == RHS;
- }
- };
-
- template<> struct DenseMapInfo<clang::CanQualType> {
- static inline clang::CanQualType getEmptyKey() {
- return clang::CanQualType();
- }
-
- static inline clang::CanQualType getTombstoneKey() {
- using clang::CanQualType;
- return CanQualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
- }
-
- static unsigned getHashValue(clang::CanQualType Val) {
- return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
- ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
- }
-
- static bool isEqual(clang::CanQualType LHS, clang::CanQualType RHS) {
- return LHS == RHS;
- }
- };
-}
-
-#endif
diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h
deleted file mode 100644
index 11e5a47..0000000
--- a/include/clang/AST/TypeVisitor.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TypeVisitor interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_TYPEVISITOR_H
-#define LLVM_CLANG_AST_TYPEVISITOR_H
-
-#include "clang/AST/Type.h"
-
-namespace clang {
-
-#define DISPATCH(CLASS) \
- return static_cast<ImplClass*>(this)-> \
- Visit##CLASS(static_cast<const CLASS*>(T))
-
-/// \brief An operation on a type.
-///
-/// \tparam ImplClass Class implementing the operation. Must be inherited from
-/// TypeVisitor.
-/// \tparam RetTy %Type of result produced by the operation.
-///
-/// The class implements polymorphic operation on an object of type derived
-/// from Type. The operation is performed by calling method Visit. It then
-/// dispatches the call to function \c VisitFooType, if actual argument type
-/// is \c FooType.
-///
-/// The class implements static polymorphism using Curiously Recurring
-/// Template Pattern. It is designed to be a base class for some concrete
-/// class:
-///
-/// \code
-/// class SomeVisitor : public TypeVisitor<SomeVisitor,sometype> { ... };
-/// ...
-/// Type *atype = ...
-/// ...
-/// SomeVisitor avisitor;
-/// sometype result = avisitor.Visit(atype);
-/// \endcode
-///
-/// Actual treatment is made by methods of the derived class, TypeVisitor only
-/// dispatches call to the appropriate method. If the implementation class
-/// \c ImplClass provides specific action for some type, say
-/// \c ConstantArrayType, it should define method
-/// <tt>VisitConstantArrayType(const ConstantArrayType*)</tt>. Otherwise
-/// \c TypeVisitor dispatches call to the method that handles parent type. In
-/// this example handlers are tried in the sequence:
-///
-/// \li <tt>ImplClass::VisitConstantArrayType(const ConstantArrayType*)</tt>
-/// \li <tt>ImplClass::VisitArrayType(const ArrayType*)</tt>
-/// \li <tt>ImplClass::VisitType(const Type*)</tt>
-/// \li <tt>TypeVisitor::VisitType(const Type*)</tt>
-///
-/// The first function of this sequence that is defined will handle object of
-/// type \c ConstantArrayType.
-template<typename ImplClass, typename RetTy=void>
-class TypeVisitor {
-public:
-
- /// \brief Performs the operation associated with this visitor object.
- RetTy Visit(const Type *T) {
- // Top switch stmt: dispatch to VisitFooType for each FooType.
- switch (T->getTypeClass()) {
-#define ABSTRACT_TYPE(CLASS, PARENT)
-#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type);
-#include "clang/AST/TypeNodes.def"
- }
- llvm_unreachable("Unknown type class!");
- }
-
- // If the implementation chooses not to implement a certain visit method, fall
- // back on superclass.
-#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(const CLASS##Type *T) { \
- DISPATCH(PARENT); \
-}
-#include "clang/AST/TypeNodes.def"
-
- /// \brief Method called if \c ImpClass doesn't provide specific handler
- /// for some type class.
- RetTy VisitType(const Type*) { return RetTy(); }
-};
-
-#undef DISPATCH
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
deleted file mode 100644
index 26ee1cf..0000000
--- a/include/clang/AST/UnresolvedSet.h
+++ /dev/null
@@ -1,140 +0,0 @@
-//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the UnresolvedSet class, which is used to store
-// collections of declarations in the AST.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
-#define LLVM_CLANG_AST_UNRESOLVEDSET_H
-
-#include "clang/AST/DeclAccessPair.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/iterator.h"
-
-namespace clang {
-
-/// The iterator over UnresolvedSets. Serves as both the const and
-/// non-const iterator.
-class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
- UnresolvedSetIterator, DeclAccessPair *,
- std::random_access_iterator_tag, NamedDecl *,
- std::ptrdiff_t, NamedDecl *, NamedDecl *> {
- friend class UnresolvedSetImpl;
- friend class ASTUnresolvedSet;
- friend class OverloadExpr;
-
- explicit UnresolvedSetIterator(DeclAccessPair *Iter)
- : iterator_adaptor_base(Iter) {}
- explicit UnresolvedSetIterator(const DeclAccessPair *Iter)
- : iterator_adaptor_base(const_cast<DeclAccessPair *>(Iter)) {}
-
-public:
- UnresolvedSetIterator() {}
-
- NamedDecl *getDecl() const { return I->getDecl(); }
- void setDecl(NamedDecl *ND) const { return I->setDecl(ND); }
- AccessSpecifier getAccess() const { return I->getAccess(); }
- void setAccess(AccessSpecifier AS) { I->setAccess(AS); }
- const DeclAccessPair &getPair() const { return *I; }
-
- NamedDecl *operator*() const { return getDecl(); }
- NamedDecl *operator->() const { return **this; }
-};
-
-/// \brief A set of unresolved declarations.
-class UnresolvedSetImpl {
- typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
-
- // Don't allow direct construction, and only permit subclassing by
- // UnresolvedSet.
-private:
- template <unsigned N> friend class UnresolvedSet;
- UnresolvedSetImpl() {}
- UnresolvedSetImpl(const UnresolvedSetImpl &) {}
-
-public:
- // We don't currently support assignment through this iterator, so we might
- // as well use the same implementation twice.
- typedef UnresolvedSetIterator iterator;
- typedef UnresolvedSetIterator const_iterator;
-
- iterator begin() { return iterator(decls().begin()); }
- iterator end() { return iterator(decls().end()); }
-
- const_iterator begin() const { return const_iterator(decls().begin()); }
- const_iterator end() const { return const_iterator(decls().end()); }
-
- void addDecl(NamedDecl *D) {
- addDecl(D, AS_none);
- }
-
- void addDecl(NamedDecl *D, AccessSpecifier AS) {
- decls().push_back(DeclAccessPair::make(D, AS));
- }
-
- /// Replaces the given declaration with the new one, once.
- ///
- /// \return true if the set changed
- bool replace(const NamedDecl* Old, NamedDecl *New) {
- for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
- if (I->getDecl() == Old)
- return (I->setDecl(New), true);
- return false;
- }
-
- /// Replaces the declaration at the given iterator with the new one,
- /// preserving the original access bits.
- void replace(iterator I, NamedDecl *New) { I.I->setDecl(New); }
-
- void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
- I.I->set(New, AS);
- }
-
- void erase(unsigned I) { decls()[I] = decls().pop_back_val(); }
-
- void erase(iterator I) { *I.I = decls().pop_back_val(); }
-
- void setAccess(iterator I, AccessSpecifier AS) { I.I->setAccess(AS); }
-
- void clear() { decls().clear(); }
- void set_size(unsigned N) { decls().set_size(N); }
-
- bool empty() const { return decls().empty(); }
- unsigned size() const { return decls().size(); }
-
- void append(iterator I, iterator E) { decls().append(I.I, E.I); }
-
- DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
- const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
-
-private:
- // These work because the only permitted subclass is UnresolvedSetImpl
-
- DeclsTy &decls() {
- return *reinterpret_cast<DeclsTy*>(this);
- }
- const DeclsTy &decls() const {
- return *reinterpret_cast<const DeclsTy*>(this);
- }
-};
-
-/// \brief A set of unresolved declarations.
-template <unsigned InlineCapacity> class UnresolvedSet :
- public UnresolvedSetImpl {
- SmallVector<DeclAccessPair, InlineCapacity> Decls;
-};
-
-
-} // namespace clang
-
-#endif
diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h
deleted file mode 100644
index 727bf51..0000000
--- a/include/clang/AST/VTTBuilder.h
+++ /dev/null
@@ -1,162 +0,0 @@
-//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with generation of the layout of virtual table
-// tables (VTT).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_VTTBUILDER_H
-#define LLVM_CLANG_AST_VTTBUILDER_H
-
-#include "clang/AST/BaseSubobject.h"
-#include "clang/AST/CXXInheritance.h"
-#include "clang/AST/GlobalDecl.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/ABI.h"
-#include "llvm/ADT/SetVector.h"
-#include <utility>
-
-namespace clang {
-
-class VTTVTable {
- llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
- CharUnits BaseOffset;
-
-public:
- VTTVTable() {}
- VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
- : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
- VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
- : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
- BaseOffset(Base.getBaseOffset()) {}
-
- const CXXRecordDecl *getBase() const {
- return BaseAndIsVirtual.getPointer();
- }
-
- CharUnits getBaseOffset() const {
- return BaseOffset;
- }
-
- bool isVirtual() const {
- return BaseAndIsVirtual.getInt();
- }
-
- BaseSubobject getBaseSubobject() const {
- return BaseSubobject(getBase(), getBaseOffset());
- }
-};
-
-struct VTTComponent {
- uint64_t VTableIndex;
- BaseSubobject VTableBase;
-
- VTTComponent() {}
- VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
- : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
-};
-
-/// \brief Class for building VTT layout information.
-class VTTBuilder {
-
- ASTContext &Ctx;
-
- /// \brief The most derived class for which we're building this vtable.
- const CXXRecordDecl *MostDerivedClass;
-
- typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
-
- /// \brief The VTT vtables.
- VTTVTablesVectorTy VTTVTables;
-
- typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
-
- /// \brief The VTT components.
- VTTComponentsVectorTy VTTComponents;
-
- /// \brief The AST record layout of the most derived class.
- const ASTRecordLayout &MostDerivedClassLayout;
-
- typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
-
- typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
-
- /// \brief The sub-VTT indices for the bases of the most derived class.
- llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
-
- /// \brief The secondary virtual pointer indices of all subobjects of
- /// the most derived class.
- llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
-
- /// \brief Whether the VTT builder should generate LLVM IR for the VTT.
- bool GenerateDefinition;
-
- /// \brief Add a vtable pointer to the VTT currently being built.
- void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
- const CXXRecordDecl *VTableClass);
-
- /// \brief Lay out the secondary VTTs of the given base subobject.
- void LayoutSecondaryVTTs(BaseSubobject Base);
-
- /// \brief Lay out the secondary virtual pointers for the given base
- /// subobject.
- ///
- /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
- /// or a direct or indirect base of a virtual base.
- void LayoutSecondaryVirtualPointers(BaseSubobject Base,
- bool BaseIsMorallyVirtual,
- uint64_t VTableIndex,
- const CXXRecordDecl *VTableClass,
- VisitedVirtualBasesSetTy &VBases);
-
- /// \brief Lay out the secondary virtual pointers for the given base
- /// subobject.
- void LayoutSecondaryVirtualPointers(BaseSubobject Base,
- uint64_t VTableIndex);
-
- /// \brief Lay out the VTTs for the virtual base classes of the given
- /// record declaration.
- void LayoutVirtualVTTs(const CXXRecordDecl *RD,
- VisitedVirtualBasesSetTy &VBases);
-
- /// \brief Lay out the VTT for the given subobject, including any
- /// secondary VTTs, secondary virtual pointers and virtual VTTs.
- void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
-
-public:
- VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
- bool GenerateDefinition);
-
- // \brief Returns a reference to the VTT components.
- const VTTComponentsVectorTy &getVTTComponents() const {
- return VTTComponents;
- }
-
- // \brief Returns a reference to the VTT vtables.
- const VTTVTablesVectorTy &getVTTVTables() const {
- return VTTVTables;
- }
-
- /// \brief Returns a reference to the sub-VTT indices.
- const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
- return SubVTTIndicies;
- }
-
- /// \brief Returns a reference to the secondary virtual pointer indices.
- const llvm::DenseMap<BaseSubobject, uint64_t> &
- getSecondaryVirtualPointerIndices() const {
- return SecondaryVirtualPointerIndices;
- }
-
-};
-
-}
-
-#endif
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
deleted file mode 100644
index 481fd11..0000000
--- a/include/clang/AST/VTableBuilder.h
+++ /dev/null
@@ -1,566 +0,0 @@
-//===--- VTableBuilder.h - C++ vtable layout builder --------------*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with generation of the layout of virtual tables.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_VTABLEBUILDER_H
-#define LLVM_CLANG_AST_VTABLEBUILDER_H
-
-#include "clang/AST/BaseSubobject.h"
-#include "clang/AST/CXXInheritance.h"
-#include "clang/AST/GlobalDecl.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/ABI.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SetVector.h"
-#include <memory>
-#include <utility>
-
-namespace clang {
- class CXXRecordDecl;
-
-/// \brief Represents a single component in a vtable.
-class VTableComponent {
-public:
- enum Kind {
- CK_VCallOffset,
- CK_VBaseOffset,
- CK_OffsetToTop,
- CK_RTTI,
- CK_FunctionPointer,
-
- /// \brief A pointer to the complete destructor.
- CK_CompleteDtorPointer,
-
- /// \brief A pointer to the deleting destructor.
- CK_DeletingDtorPointer,
-
- /// \brief An entry that is never used.
- ///
- /// In some cases, a vtable function pointer will end up never being
- /// called. Such vtable function pointers are represented as a
- /// CK_UnusedFunctionPointer.
- CK_UnusedFunctionPointer
- };
-
- VTableComponent() = default;
-
- static VTableComponent MakeVCallOffset(CharUnits Offset) {
- return VTableComponent(CK_VCallOffset, Offset);
- }
-
- static VTableComponent MakeVBaseOffset(CharUnits Offset) {
- return VTableComponent(CK_VBaseOffset, Offset);
- }
-
- static VTableComponent MakeOffsetToTop(CharUnits Offset) {
- return VTableComponent(CK_OffsetToTop, Offset);
- }
-
- static VTableComponent MakeRTTI(const CXXRecordDecl *RD) {
- return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD));
- }
-
- static VTableComponent MakeFunction(const CXXMethodDecl *MD) {
- assert(!isa<CXXDestructorDecl>(MD) &&
- "Don't use MakeFunction with destructors!");
-
- return VTableComponent(CK_FunctionPointer,
- reinterpret_cast<uintptr_t>(MD));
- }
-
- static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) {
- return VTableComponent(CK_CompleteDtorPointer,
- reinterpret_cast<uintptr_t>(DD));
- }
-
- static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) {
- return VTableComponent(CK_DeletingDtorPointer,
- reinterpret_cast<uintptr_t>(DD));
- }
-
- static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD) {
- assert(!isa<CXXDestructorDecl>(MD) &&
- "Don't use MakeUnusedFunction with destructors!");
- return VTableComponent(CK_UnusedFunctionPointer,
- reinterpret_cast<uintptr_t>(MD));
- }
-
- static VTableComponent getFromOpaqueInteger(uint64_t I) {
- return VTableComponent(I);
- }
-
- /// \brief Get the kind of this vtable component.
- Kind getKind() const {
- return (Kind)(Value & 0x7);
- }
-
- CharUnits getVCallOffset() const {
- assert(getKind() == CK_VCallOffset && "Invalid component kind!");
-
- return getOffset();
- }
-
- CharUnits getVBaseOffset() const {
- assert(getKind() == CK_VBaseOffset && "Invalid component kind!");
-
- return getOffset();
- }
-
- CharUnits getOffsetToTop() const {
- assert(getKind() == CK_OffsetToTop && "Invalid component kind!");
-
- return getOffset();
- }
-
- const CXXRecordDecl *getRTTIDecl() const {
- assert(isRTTIKind() && "Invalid component kind!");
- return reinterpret_cast<CXXRecordDecl *>(getPointer());
- }
-
- const CXXMethodDecl *getFunctionDecl() const {
- assert(isFunctionPointerKind() && "Invalid component kind!");
- if (isDestructorKind())
- return getDestructorDecl();
- return reinterpret_cast<CXXMethodDecl *>(getPointer());
- }
-
- const CXXDestructorDecl *getDestructorDecl() const {
- assert(isDestructorKind() && "Invalid component kind!");
- return reinterpret_cast<CXXDestructorDecl *>(getPointer());
- }
-
- const CXXMethodDecl *getUnusedFunctionDecl() const {
- assert(getKind() == CK_UnusedFunctionPointer && "Invalid component kind!");
- return reinterpret_cast<CXXMethodDecl *>(getPointer());
- }
-
- bool isDestructorKind() const { return isDestructorKind(getKind()); }
-
- bool isUsedFunctionPointerKind() const {
- return isUsedFunctionPointerKind(getKind());
- }
-
- bool isFunctionPointerKind() const {
- return isFunctionPointerKind(getKind());
- }
-
- bool isRTTIKind() const { return isRTTIKind(getKind()); }
-
-private:
- static bool isFunctionPointerKind(Kind ComponentKind) {
- return isUsedFunctionPointerKind(ComponentKind) ||
- ComponentKind == CK_UnusedFunctionPointer;
- }
- static bool isUsedFunctionPointerKind(Kind ComponentKind) {
- return ComponentKind == CK_FunctionPointer ||
- isDestructorKind(ComponentKind);
- }
- static bool isDestructorKind(Kind ComponentKind) {
- return ComponentKind == CK_CompleteDtorPointer ||
- ComponentKind == CK_DeletingDtorPointer;
- }
- static bool isRTTIKind(Kind ComponentKind) {
- return ComponentKind == CK_RTTI;
- }
-
- VTableComponent(Kind ComponentKind, CharUnits Offset) {
- assert((ComponentKind == CK_VCallOffset ||
- ComponentKind == CK_VBaseOffset ||
- ComponentKind == CK_OffsetToTop) && "Invalid component kind!");
- assert(Offset.getQuantity() < (1LL << 56) && "Offset is too big!");
- assert(Offset.getQuantity() >= -(1LL << 56) && "Offset is too small!");
-
- Value = (uint64_t(Offset.getQuantity()) << 3) | ComponentKind;
- }
-
- VTableComponent(Kind ComponentKind, uintptr_t Ptr) {
- assert((isRTTIKind(ComponentKind) || isFunctionPointerKind(ComponentKind)) &&
- "Invalid component kind!");
-
- assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!");
-
- Value = Ptr | ComponentKind;
- }
-
- CharUnits getOffset() const {
- assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset ||
- getKind() == CK_OffsetToTop) && "Invalid component kind!");
-
- return CharUnits::fromQuantity(Value >> 3);
- }
-
- uintptr_t getPointer() const {
- assert((getKind() == CK_RTTI || isFunctionPointerKind()) &&
- "Invalid component kind!");
-
- return static_cast<uintptr_t>(Value & ~7ULL);
- }
-
- explicit VTableComponent(uint64_t Value)
- : Value(Value) { }
-
- /// The kind is stored in the lower 3 bits of the value. For offsets, we
- /// make use of the facts that classes can't be larger than 2^55 bytes,
- /// so we store the offset in the lower part of the 61 bits that remain.
- /// (The reason that we're not simply using a PointerIntPair here is that we
- /// need the offsets to be 64-bit, even when on a 32-bit machine).
- int64_t Value;
-};
-
-class VTableLayout {
-public:
- typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
-
- typedef const VTableComponent *vtable_component_iterator;
- typedef const VTableThunkTy *vtable_thunk_iterator;
- typedef llvm::iterator_range<vtable_component_iterator>
- vtable_component_range;
-
- typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
-
-private:
- uint64_t NumVTableComponents;
- std::unique_ptr<VTableComponent[]> VTableComponents;
-
- /// \brief Contains thunks needed by vtables, sorted by indices.
- uint64_t NumVTableThunks;
- std::unique_ptr<VTableThunkTy[]> VTableThunks;
-
- /// \brief Address points for all vtables.
- AddressPointsMapTy AddressPoints;
-
- bool IsMicrosoftABI;
-
-public:
- VTableLayout(uint64_t NumVTableComponents,
- const VTableComponent *VTableComponents,
- uint64_t NumVTableThunks,
- const VTableThunkTy *VTableThunks,
- const AddressPointsMapTy &AddressPoints,
- bool IsMicrosoftABI);
- ~VTableLayout();
-
- uint64_t getNumVTableComponents() const {
- return NumVTableComponents;
- }
-
- vtable_component_range vtable_components() const {
- return vtable_component_range(vtable_component_begin(),
- vtable_component_end());
- }
-
- vtable_component_iterator vtable_component_begin() const {
- return VTableComponents.get();
- }
-
- vtable_component_iterator vtable_component_end() const {
- return VTableComponents.get() + NumVTableComponents;
- }
-
- uint64_t getNumVTableThunks() const { return NumVTableThunks; }
-
- vtable_thunk_iterator vtable_thunk_begin() const {
- return VTableThunks.get();
- }
-
- vtable_thunk_iterator vtable_thunk_end() const {
- return VTableThunks.get() + NumVTableThunks;
- }
-
- uint64_t getAddressPoint(BaseSubobject Base) const {
- assert(AddressPoints.count(Base) &&
- "Did not find address point!");
-
- uint64_t AddressPoint = AddressPoints.lookup(Base);
- assert(AddressPoint != 0 || IsMicrosoftABI);
- (void)IsMicrosoftABI;
-
- return AddressPoint;
- }
-
- const AddressPointsMapTy &getAddressPoints() const {
- return AddressPoints;
- }
-};
-
-class VTableContextBase {
-public:
- typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
-
- bool isMicrosoft() const { return IsMicrosoftABI; }
-
- virtual ~VTableContextBase() {}
-
-protected:
- typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
-
- /// \brief Contains all thunks that a given method decl will need.
- ThunksMapTy Thunks;
-
- /// Compute and store all vtable related information (vtable layout, vbase
- /// offset offsets, thunks etc) for the given record decl.
- virtual void computeVTableRelatedInformation(const CXXRecordDecl *RD) = 0;
-
- VTableContextBase(bool MS) : IsMicrosoftABI(MS) {}
-
-public:
- virtual const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) {
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()->getCanonicalDecl());
- computeVTableRelatedInformation(MD->getParent());
-
- // This assumes that all the destructors present in the vtable
- // use exactly the same set of thunks.
- ThunksMapTy::const_iterator I = Thunks.find(MD);
- if (I == Thunks.end()) {
- // We did not find a thunk for this method.
- return nullptr;
- }
-
- return &I->second;
- }
-
- bool IsMicrosoftABI;
-};
-
-class ItaniumVTableContext : public VTableContextBase {
-private:
-
- /// \brief Contains the index (relative to the vtable address point)
- /// where the function pointer for a virtual function is stored.
- typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
- MethodVTableIndicesTy MethodVTableIndices;
-
- typedef llvm::DenseMap<const CXXRecordDecl *, const VTableLayout *>
- VTableLayoutMapTy;
- VTableLayoutMapTy VTableLayouts;
-
- typedef std::pair<const CXXRecordDecl *,
- const CXXRecordDecl *> ClassPairTy;
-
- /// \brief vtable offsets for offsets of virtual bases of a class.
- ///
- /// Contains the vtable offset (relative to the address point) in chars
- /// where the offsets for virtual bases of a class are stored.
- typedef llvm::DenseMap<ClassPairTy, CharUnits>
- VirtualBaseClassOffsetOffsetsMapTy;
- VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
-
- void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
-
-public:
- ItaniumVTableContext(ASTContext &Context);
- ~ItaniumVTableContext() override;
-
- const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) {
- computeVTableRelatedInformation(RD);
- assert(VTableLayouts.count(RD) && "No layout for this record decl!");
-
- return *VTableLayouts[RD];
- }
-
- VTableLayout *
- createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass,
- CharUnits MostDerivedClassOffset,
- bool MostDerivedClassIsVirtual,
- const CXXRecordDecl *LayoutClass);
-
- /// \brief Locate a virtual function in the vtable.
- ///
- /// Return the index (relative to the vtable address point) where the
- /// function pointer for the given virtual function is stored.
- uint64_t getMethodVTableIndex(GlobalDecl GD);
-
- /// Return the offset in chars (relative to the vtable address point) where
- /// the offset of the virtual base that contains the given base is stored,
- /// otherwise, if no virtual base contains the given class, return 0.
- ///
- /// Base must be a virtual base class or an unambiguous base.
- CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
- const CXXRecordDecl *VBase);
-
- static bool classof(const VTableContextBase *VT) {
- return !VT->isMicrosoft();
- }
-};
-
-/// Holds information about the inheritance path to a virtual base or function
-/// table pointer. A record may contain as many vfptrs or vbptrs as there are
-/// base subobjects.
-struct VPtrInfo {
- typedef SmallVector<const CXXRecordDecl *, 1> BasePath;
-
- VPtrInfo(const CXXRecordDecl *RD)
- : ReusingBase(RD), BaseWithVPtr(RD), NextBaseToMangle(RD) {}
-
- /// The vtable will hold all of the virtual bases or virtual methods of
- /// ReusingBase. This may or may not be the same class as VPtrSubobject.Base.
- /// A derived class will reuse the vptr of the first non-virtual base
- /// subobject that has one.
- const CXXRecordDecl *ReusingBase;
-
- /// BaseWithVPtr is at this offset from its containing complete object or
- /// virtual base.
- CharUnits NonVirtualOffset;
-
- /// The vptr is stored inside this subobject.
- const CXXRecordDecl *BaseWithVPtr;
-
- /// The bases from the inheritance path that got used to mangle the vbtable
- /// name. This is not really a full path like a CXXBasePath. It holds the
- /// subset of records that need to be mangled into the vbtable symbol name in
- /// order to get a unique name.
- BasePath MangledPath;
-
- /// The next base to push onto the mangled path if this path is ambiguous in a
- /// derived class. If it's null, then it's already been pushed onto the path.
- const CXXRecordDecl *NextBaseToMangle;
-
- /// The set of possibly indirect vbases that contain this vbtable. When a
- /// derived class indirectly inherits from the same vbase twice, we only keep
- /// vtables and their paths from the first instance.
- BasePath ContainingVBases;
-
- /// This holds the base classes path from the complete type to the first base
- /// with the given vfptr offset, in the base-to-derived order. Only used for
- /// vftables.
- BasePath PathToBaseWithVPtr;
-
- /// Static offset from the top of the most derived class to this vfptr,
- /// including any virtual base offset. Only used for vftables.
- CharUnits FullOffsetInMDC;
-
- /// The vptr is stored inside the non-virtual component of this virtual base.
- const CXXRecordDecl *getVBaseWithVPtr() const {
- return ContainingVBases.empty() ? nullptr : ContainingVBases.front();
- }
-};
-
-typedef SmallVector<VPtrInfo *, 2> VPtrInfoVector;
-
-/// All virtual base related information about a given record decl. Includes
-/// information on all virtual base tables and the path components that are used
-/// to mangle them.
-struct VirtualBaseInfo {
- ~VirtualBaseInfo() { llvm::DeleteContainerPointers(VBPtrPaths); }
-
- /// A map from virtual base to vbtable index for doing a conversion from the
- /// the derived class to the a base.
- llvm::DenseMap<const CXXRecordDecl *, unsigned> VBTableIndices;
-
- /// Information on all virtual base tables used when this record is the most
- /// derived class.
- VPtrInfoVector VBPtrPaths;
-};
-
-class MicrosoftVTableContext : public VTableContextBase {
-public:
- struct MethodVFTableLocation {
- /// If nonzero, holds the vbtable index of the virtual base with the vfptr.
- uint64_t VBTableIndex;
-
- /// If nonnull, holds the last vbase which contains the vfptr that the
- /// method definition is adjusted to.
- const CXXRecordDecl *VBase;
-
- /// This is the offset of the vfptr from the start of the last vbase, or the
- /// complete type if there are no virtual bases.
- CharUnits VFPtrOffset;
-
- /// Method's index in the vftable.
- uint64_t Index;
-
- MethodVFTableLocation()
- : VBTableIndex(0), VBase(nullptr), VFPtrOffset(CharUnits::Zero()),
- Index(0) {}
-
- MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase,
- CharUnits VFPtrOffset, uint64_t Index)
- : VBTableIndex(VBTableIndex), VBase(VBase),
- VFPtrOffset(VFPtrOffset), Index(Index) {}
-
- bool operator<(const MethodVFTableLocation &other) const {
- if (VBTableIndex != other.VBTableIndex) {
- assert(VBase != other.VBase);
- return VBTableIndex < other.VBTableIndex;
- }
- return std::tie(VFPtrOffset, Index) <
- std::tie(other.VFPtrOffset, other.Index);
- }
- };
-
-private:
- ASTContext &Context;
-
- typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
- MethodVFTableLocationsTy;
- MethodVFTableLocationsTy MethodVFTableLocations;
-
- typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector *>
- VFPtrLocationsMapTy;
- VFPtrLocationsMapTy VFPtrLocations;
-
- typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
- typedef llvm::DenseMap<VFTableIdTy, const VTableLayout *> VFTableLayoutMapTy;
- VFTableLayoutMapTy VFTableLayouts;
-
- llvm::DenseMap<const CXXRecordDecl *, VirtualBaseInfo *> VBaseInfo;
-
- void enumerateVFPtrs(const CXXRecordDecl *ForClass, VPtrInfoVector &Result);
-
- void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
-
- void dumpMethodLocations(const CXXRecordDecl *RD,
- const MethodVFTableLocationsTy &NewMethods,
- raw_ostream &);
-
- const VirtualBaseInfo *
- computeVBTableRelatedInformation(const CXXRecordDecl *RD);
-
- void computeVTablePaths(bool ForVBTables, const CXXRecordDecl *RD,
- VPtrInfoVector &Paths);
-
-public:
- MicrosoftVTableContext(ASTContext &Context)
- : VTableContextBase(/*MS=*/true), Context(Context) {}
-
- ~MicrosoftVTableContext() override;
-
- const VPtrInfoVector &getVFPtrOffsets(const CXXRecordDecl *RD);
-
- const VTableLayout &getVFTableLayout(const CXXRecordDecl *RD,
- CharUnits VFPtrOffset);
-
- const MethodVFTableLocation &getMethodVFTableLocation(GlobalDecl GD);
-
- const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) override {
- // Complete destructors don't have a slot in a vftable, so no thunks needed.
- if (isa<CXXDestructorDecl>(GD.getDecl()) &&
- GD.getDtorType() == Dtor_Complete)
- return nullptr;
- return VTableContextBase::getThunkInfo(GD);
- }
-
- /// \brief Returns the index of VBase in the vbtable of Derived.
- /// VBase must be a morally virtual base of Derived.
- /// The vbtable is an array of i32 offsets. The first entry is a self entry,
- /// and the rest are offsets from the vbptr to virtual bases.
- unsigned getVBTableIndex(const CXXRecordDecl *Derived,
- const CXXRecordDecl *VBase);
-
- const VPtrInfoVector &enumerateVBTables(const CXXRecordDecl *RD);
-
- static bool classof(const VTableContextBase *VT) { return VT->isMicrosoft(); }
-};
-
-} // namespace clang
-
-#endif
OpenPOWER on IntegriCloud