summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/AST
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-11-24 18:11:16 +0000
committerdim <dim@FreeBSD.org>2014-11-24 18:11:16 +0000
commit6148c19c738a92f344008aa3f88f4e008bada0ee (patch)
treed4426858455f04d0d8c25a2f9eb9ea5582ffe1b6 /contrib/llvm/tools/clang/lib/AST
parent2c8643c6396b0a3db33430cf9380e70bbb9efce0 (diff)
parent173a4f43a911175643bda81ee675e8d9269056ea (diff)
downloadFreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.zip
FreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.tar.gz
Merge clang 3.5.0 release from ^/vendor/clang/dist, resolve conflicts,
and preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST')
-rw-r--r--contrib/llvm/tools/clang/lib/AST/APValue.cpp93
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ASTContext.cpp1554
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp357
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp379
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp678
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp16
-rw-r--r--contrib/llvm/tools/clang/lib/AST/AttrImpl.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/AST/CXXABI.h1
-rw-r--r--contrib/llvm/tools/clang/lib/AST/CXXInheritance.cpp80
-rw-r--r--contrib/llvm/tools/clang/lib/AST/Comment.cpp46
-rw-r--r--contrib/llvm/tools/clang/lib/AST/CommentCommandTraits.cpp71
-rw-r--r--contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp13
-rw-r--r--contrib/llvm/tools/clang/lib/AST/CommentParser.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/AST/CommentSema.cpp79
-rw-r--r--contrib/llvm/tools/clang/lib/AST/Decl.cpp762
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclBase.cpp182
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp387
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclFriend.cpp16
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp717
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp17
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp153
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp276
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp37
-rw-r--r--contrib/llvm/tools/clang/lib/AST/Expr.cpp274
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp140
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ExprClassification.cpp24
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp472
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp52
-rw-r--r--contrib/llvm/tools/clang/lib/AST/InheritViz.cpp15
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ItaniumCXXABI.cpp28
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp306
-rw-r--r--contrib/llvm/tools/clang/lib/AST/Mangle.cpp14
-rw-r--r--contrib/llvm/tools/clang/lib/AST/MangleNumberingContext.cpp10
-rw-r--r--contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp132
-rw-r--r--contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp1127
-rw-r--r--contrib/llvm/tools/clang/lib/AST/NSAPI.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp34
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ParentMap.cpp8
-rw-r--r--contrib/llvm/tools/clang/lib/AST/RawCommentList.cpp17
-rw-r--r--contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp25
-rw-r--r--contrib/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp1554
-rw-r--r--contrib/llvm/tools/clang/lib/AST/Stmt.cpp588
-rw-r--r--contrib/llvm/tools/clang/lib/AST/StmtIterator.cpp8
-rw-r--r--contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp457
-rw-r--r--contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp187
-rw-r--r--contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp33
-rw-r--r--contrib/llvm/tools/clang/lib/AST/TemplateName.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/AST/Type.cpp192
-rw-r--r--contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp93
-rw-r--r--contrib/llvm/tools/clang/lib/AST/VTTBuilder.cpp22
-rw-r--r--contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp855
52 files changed, 7421 insertions, 5182 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/APValue.cpp b/contrib/llvm/tools/clang/lib/AST/APValue.cpp
index 541836b21b..0fa0216 100644
--- a/contrib/llvm/tools/clang/lib/AST/APValue.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/APValue.cpp
@@ -34,7 +34,7 @@ namespace {
struct APValue::LV : LVBase {
static const unsigned InlinePathSpace =
- (MaxSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
+ (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
/// Path - The sequence of base classes, fields and array indices to follow to
/// walk from Base to the subobject. When performing GCC-style folding, there
@@ -75,7 +75,7 @@ namespace {
struct APValue::MemberPointerData : MemberPointerBase {
static const unsigned InlinePathSpace =
- (MaxSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
+ (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
typedef const CXXRecordDecl *PathElem;
union {
PathElem Path[InlinePathSpace];
@@ -117,7 +117,7 @@ APValue::StructData::~StructData() {
delete [] Elts;
}
-APValue::UnionData::UnionData() : Field(0), Value(new APValue) {}
+APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
APValue::UnionData::~UnionData () {
delete Value;
}
@@ -136,7 +136,7 @@ APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
break;
case Vector:
MakeVector();
- setVector(((const Vec *)(const char *)RHS.Data)->Elts,
+ setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
RHS.getVectorLength());
break;
case ComplexInt:
@@ -188,27 +188,27 @@ APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
void APValue::DestroyDataAndMakeUninit() {
if (Kind == Int)
- ((APSInt*)(char*)Data)->~APSInt();
+ ((APSInt*)(char*)Data.buffer)->~APSInt();
else if (Kind == Float)
- ((APFloat*)(char*)Data)->~APFloat();
+ ((APFloat*)(char*)Data.buffer)->~APFloat();
else if (Kind == Vector)
- ((Vec*)(char*)Data)->~Vec();
+ ((Vec*)(char*)Data.buffer)->~Vec();
else if (Kind == ComplexInt)
- ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
+ ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
else if (Kind == ComplexFloat)
- ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
+ ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
else if (Kind == LValue)
- ((LV*)(char*)Data)->~LV();
+ ((LV*)(char*)Data.buffer)->~LV();
else if (Kind == Array)
- ((Arr*)(char*)Data)->~Arr();
+ ((Arr*)(char*)Data.buffer)->~Arr();
else if (Kind == Struct)
- ((StructData*)(char*)Data)->~StructData();
+ ((StructData*)(char*)Data.buffer)->~StructData();
else if (Kind == Union)
- ((UnionData*)(char*)Data)->~UnionData();
+ ((UnionData*)(char*)Data.buffer)->~UnionData();
else if (Kind == MemberPointer)
- ((MemberPointerData*)(char*)Data)->~MemberPointerData();
+ ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
else if (Kind == AddrLabelDiff)
- ((AddrLabelDiffData*)(char*)Data)->~AddrLabelDiffData();
+ ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
Kind = Uninitialized;
}
@@ -239,19 +239,20 @@ bool APValue::needsCleanup() const {
"same size.");
return getComplexIntReal().needsCleanup();
case LValue:
- return reinterpret_cast<const LV *>(Data)->hasPathPtr();
+ return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
case MemberPointer:
- return reinterpret_cast<const MemberPointerData *>(Data)->hasPathPtr();
+ return reinterpret_cast<const MemberPointerData *>(Data.buffer)
+ ->hasPathPtr();
}
llvm_unreachable("Unknown APValue kind!");
}
void APValue::swap(APValue &RHS) {
std::swap(Kind, RHS.Kind);
- char TmpData[MaxSize];
- memcpy(TmpData, Data, MaxSize);
- memcpy(Data, RHS.Data, MaxSize);
- memcpy(RHS.Data, TmpData, MaxSize);
+ char TmpData[DataSize];
+ memcpy(TmpData, Data.buffer, DataSize);
+ memcpy(Data.buffer, RHS.Data.buffer, DataSize);
+ memcpy(RHS.Data.buffer, TmpData, DataSize);
}
void APValue::dump() const {
@@ -402,8 +403,13 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
Out << *VD;
- else
- Base.get<const Expr*>()->printPretty(Out, 0, Ctx.getPrintingPolicy());
+ else {
+ assert(Base.get<const Expr *>() != nullptr &&
+ "Expecting non-null Expr");
+ Base.get<const Expr*>()->printPretty(Out, nullptr,
+ Ctx.getPrintingPolicy());
+ }
+
if (!O.isZero()) {
Out << " + " << (O / S);
if (IsReference)
@@ -424,12 +430,13 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
ElemTy = VD->getType();
} else {
const Expr *E = Base.get<const Expr*>();
- E->printPretty(Out, 0, Ctx.getPrintingPolicy());
+ assert(E != nullptr && "Expecting non-null Expr");
+ E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
ElemTy = E->getType();
}
ArrayRef<LValuePathEntry> Path = getLValuePath();
- const CXXRecordDecl *CastToBase = 0;
+ const CXXRecordDecl *CastToBase = nullptr;
for (unsigned I = 0, N = Path.size(); I != N; ++I) {
if (ElemTy->getAs<RecordType>()) {
// The lvalue refers to a class type, so the next path entry is a base
@@ -498,8 +505,7 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
First = false;
}
}
- for (RecordDecl::field_iterator FI = RD->field_begin();
- FI != RD->field_end(); ++FI) {
+ for (const auto *FI : RD->fields()) {
if (!First)
Out << ", ";
if (FI->isUnnamedBitfield()) continue;
@@ -546,39 +552,39 @@ std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
const APValue::LValueBase APValue::getLValueBase() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getPointer();
+ return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
}
bool APValue::isLValueOnePastTheEnd() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getInt();
+ return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
}
CharUnits &APValue::getLValueOffset() {
assert(isLValue() && "Invalid accessor");
- return ((LV*)(void*)Data)->Offset;
+ return ((LV*)(void*)Data.buffer)->Offset;
}
bool APValue::hasLValuePath() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const char*)Data)->hasPath();
+ return ((const LV*)(const char*)Data.buffer)->hasPath();
}
ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
assert(isLValue() && hasLValuePath() && "Invalid accessor");
- const LV &LVal = *((const LV*)(const char*)Data);
+ const LV &LVal = *((const LV*)(const char*)Data.buffer);
return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength);
}
unsigned APValue::getLValueCallIndex() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const char*)Data)->CallIndex;
+ return ((const LV*)(const char*)Data.buffer)->CallIndex;
}
void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
unsigned CallIndex) {
assert(isLValue() && "Invalid accessor");
- LV &LVal = *((LV*)(char*)Data);
+ LV &LVal = *((LV*)(char*)Data.buffer);
LVal.BaseAndIsOnePastTheEnd.setPointer(B);
LVal.BaseAndIsOnePastTheEnd.setInt(false);
LVal.Offset = O;
@@ -590,7 +596,7 @@ void APValue::setLValue(LValueBase B, const CharUnits &O,
ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
unsigned CallIndex) {
assert(isLValue() && "Invalid accessor");
- LV &LVal = *((LV*)(char*)Data);
+ LV &LVal = *((LV*)(char*)Data.buffer);
LVal.BaseAndIsOnePastTheEnd.setPointer(B);
LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
LVal.Offset = O;
@@ -601,39 +607,42 @@ void APValue::setLValue(LValueBase B, const CharUnits &O,
const ValueDecl *APValue::getMemberPointerDecl() const {
assert(isMemberPointer() && "Invalid accessor");
- const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
+ const MemberPointerData &MPD =
+ *((const MemberPointerData *)(const char *)Data.buffer);
return MPD.MemberAndIsDerivedMember.getPointer();
}
bool APValue::isMemberPointerToDerivedMember() const {
assert(isMemberPointer() && "Invalid accessor");
- const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
+ const MemberPointerData &MPD =
+ *((const MemberPointerData *)(const char *)Data.buffer);
return MPD.MemberAndIsDerivedMember.getInt();
}
ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
assert(isMemberPointer() && "Invalid accessor");
- const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
+ const MemberPointerData &MPD =
+ *((const MemberPointerData *)(const char *)Data.buffer);
return ArrayRef<const CXXRecordDecl*>(MPD.getPath(), MPD.PathLength);
}
void APValue::MakeLValue() {
assert(isUninit() && "Bad state change");
- assert(sizeof(LV) <= MaxSize && "LV too big");
- new ((void*)(char*)Data) LV();
+ static_assert(sizeof(LV) <= DataSize, "LV too big");
+ new ((void*)(char*)Data.buffer) LV();
Kind = LValue;
}
void APValue::MakeArray(unsigned InitElts, unsigned Size) {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) Arr(InitElts, Size);
+ new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
Kind = Array;
}
void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
ArrayRef<const CXXRecordDecl*> Path) {
assert(isUninit() && "Bad state change");
- MemberPointerData *MPD = new ((void*)(char*)Data) MemberPointerData;
+ MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
Kind = MemberPointer;
MPD->MemberAndIsDerivedMember.setPointer(Member);
MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp
index a03cf9e7..bccdae9 100644
--- a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp
@@ -29,6 +29,7 @@
#include "clang/AST/RecordLayout.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/AST/VTableBuilder.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -62,6 +63,13 @@ enum FloatingRank {
RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
if (!CommentsLoaded && ExternalSource) {
ExternalSource->ReadComments();
+
+#ifndef NDEBUG
+ ArrayRef<RawComment *> RawComments = Comments.getComments();
+ assert(std::is_sorted(RawComments.begin(), RawComments.end(),
+ BeforeThanCompare<RawComment>(SourceMgr)));
+#endif
+
CommentsLoaded = true;
}
@@ -69,23 +77,23 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// User can not attach documentation to implicit declarations.
if (D->isImplicit())
- return NULL;
+ return nullptr;
// User can not attach documentation to implicit instantiations.
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
- return NULL;
+ return nullptr;
}
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (VD->isStaticDataMember() &&
VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
- return NULL;
+ return nullptr;
}
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
- return NULL;
+ return nullptr;
}
if (const ClassTemplateSpecializationDecl *CTSD =
@@ -93,35 +101,35 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
TemplateSpecializationKind TSK = CTSD->getSpecializationKind();
if (TSK == TSK_ImplicitInstantiation ||
TSK == TSK_Undeclared)
- return NULL;
+ return nullptr;
}
if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
- return NULL;
+ return nullptr;
}
if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
// When tag declaration (but not definition!) is part of the
// decl-specifier-seq of some other declaration, it doesn't get comment
if (TD->isEmbeddedInDeclarator() && !TD->isCompleteDefinition())
- return NULL;
+ return nullptr;
}
// TODO: handle comments for function parameters properly.
if (isa<ParmVarDecl>(D))
- return NULL;
+ return nullptr;
// TODO: we could look up template parameter documentation in the template
// documentation.
if (isa<TemplateTypeParmDecl>(D) ||
isa<NonTypeTemplateParmDecl>(D) ||
isa<TemplateTemplateParmDecl>(D))
- return NULL;
+ return nullptr;
ArrayRef<RawComment *> RawComments = Comments.getComments();
// If there are no comments anywhere, we won't find anything.
if (RawComments.empty())
- return NULL;
+ return nullptr;
// Find declaration location.
// For Objective-C declarations we generally don't expect to have multiple
@@ -137,17 +145,29 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
DeclLoc = D->getLocStart();
else {
DeclLoc = D->getLocation();
- // If location of the typedef name is in a macro, it is because being
- // declared via a macro. Try using declaration's starting location
- // as the "declaration location".
- if (DeclLoc.isMacroID() && isa<TypedefDecl>(D))
- DeclLoc = D->getLocStart();
+ if (DeclLoc.isMacroID()) {
+ if (isa<TypedefDecl>(D)) {
+ // If location of the typedef name is in a macro, it is because being
+ // declared via a macro. Try using declaration's starting location as
+ // the "declaration location".
+ DeclLoc = D->getLocStart();
+ } else if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
+ // If location of the tag decl is inside a macro, but the spelling of
+ // the tag name comes from a macro argument, it looks like a special
+ // macro like NS_ENUM is being used to define the tag decl. In that
+ // case, adjust the source location to the expansion loc so that we can
+ // attach the comment to the tag decl.
+ if (SourceMgr.isMacroArgExpansion(DeclLoc) &&
+ TD->isCompleteDefinition())
+ DeclLoc = SourceMgr.getExpansionLoc(DeclLoc);
+ }
+ }
}
// If the declaration doesn't map directly to a location in a file, we
// can't find the comment.
if (DeclLoc.isInvalid() || !DeclLoc.isFileID())
- return NULL;
+ return nullptr;
// Find the comment that occurs just after this declaration.
ArrayRef<RawComment *>::iterator Comment;
@@ -201,12 +221,12 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// The comment just after the declaration was not a trailing comment.
// Let's look at the previous comment.
if (Comment == RawComments.begin())
- return NULL;
+ return nullptr;
--Comment;
// Check that we actually have a non-member Doxygen comment.
if (!(*Comment)->isDocumentation() || (*Comment)->isTrailingComment())
- return NULL;
+ return nullptr;
// Decompose the end of the comment.
std::pair<FileID, unsigned> CommentEndDecomp
@@ -215,14 +235,14 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// If the comment and the declaration aren't in the same file, then they
// aren't related.
if (DeclLocDecomp.first != CommentEndDecomp.first)
- return NULL;
+ return nullptr;
// Get the corresponding buffer.
bool Invalid = false;
const char *Buffer = SourceMgr.getBufferData(DeclLocDecomp.first,
&Invalid).data();
if (Invalid)
- return NULL;
+ return nullptr;
// Extract text between the comment and declaration.
StringRef Text(Buffer + CommentEndDecomp.second,
@@ -231,7 +251,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// There should be no other declarations or preprocessor directives between
// comment and declaration.
if (Text.find_first_of(";{}#@") != StringRef::npos)
- return NULL;
+ return nullptr;
return *Comment;
}
@@ -329,13 +349,11 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
}
// Search for comments attached to declarations in the redeclaration chain.
- const RawComment *RC = NULL;
- const Decl *OriginalDeclForRC = NULL;
- for (Decl::redecl_iterator I = D->redecls_begin(),
- E = D->redecls_end();
- I != E; ++I) {
+ const RawComment *RC = nullptr;
+ const Decl *OriginalDeclForRC = nullptr;
+ for (auto I : D->redecls()) {
llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos =
- RedeclComments.find(*I);
+ RedeclComments.find(I);
if (Pos != RedeclComments.end()) {
const RawCommentAndCacheFlags &Raw = Pos->second;
if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) {
@@ -344,16 +362,16 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
break;
}
} else {
- RC = getRawCommentForDeclNoCache(*I);
- OriginalDeclForRC = *I;
+ RC = getRawCommentForDeclNoCache(I);
+ OriginalDeclForRC = I;
RawCommentAndCacheFlags Raw;
if (RC) {
Raw.setRaw(RC);
Raw.setKind(RawCommentAndCacheFlags::FromDecl);
} else
Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl);
- Raw.setOriginalDecl(*I);
- RedeclComments[*I] = Raw;
+ Raw.setOriginalDecl(I);
+ RedeclComments[I] = Raw;
if (RC)
break;
}
@@ -371,10 +389,8 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
Raw.setKind(RawCommentAndCacheFlags::FromRedecl);
Raw.setOriginalDecl(OriginalDeclForRC);
- for (Decl::redecl_iterator I = D->redecls_begin(),
- E = D->redecls_end();
- I != E; ++I) {
- RawCommentAndCacheFlags &R = RedeclComments[*I];
+ for (auto I : D->redecls()) {
+ RawCommentAndCacheFlags &R = RedeclComments[I];
if (R.getKind() == RawCommentAndCacheFlags::NoCommentInDecl)
R = Raw;
}
@@ -390,10 +406,7 @@ static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,
if (!ID)
return;
// Add redeclared method here.
- for (ObjCInterfaceDecl::known_extensions_iterator
- Ext = ID->known_extensions_begin(),
- ExtEnd = ID->known_extensions_end();
- Ext != ExtEnd; ++Ext) {
+ for (const auto *Ext : ID->known_extensions()) {
if (ObjCMethodDecl *RedeclaredMethod =
Ext->getMethod(ObjCMethod->getSelector(),
ObjCMethod->isInstanceMethod()))
@@ -409,6 +422,8 @@ comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,
ThisDeclInfo->IsFilled = false;
ThisDeclInfo->fill();
ThisDeclInfo->CommentDecl = FC->getDecl();
+ if (!ThisDeclInfo->TemplateParameters)
+ ThisDeclInfo->TemplateParameters = FC->getDeclInfo()->TemplateParameters;
comments::FullComment *CFC =
new (*this) comments::FullComment(FC->getBlocks(),
ThisDeclInfo);
@@ -418,14 +433,14 @@ comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,
comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const {
const RawComment *RC = getRawCommentForDeclNoCache(D);
- return RC ? RC->parse(*this, 0, D) : 0;
+ return RC ? RC->parse(*this, nullptr, D) : nullptr;
}
comments::FullComment *ASTContext::getCommentForDecl(
const Decl *D,
const Preprocessor *PP) const {
if (D->isInvalidDecl())
- return NULL;
+ return nullptr;
D = adjustDeclToTemplate(D);
const Decl *Canonical = D->getCanonicalDecl();
@@ -482,13 +497,12 @@ comments::FullComment *ASTContext::getCommentForDecl(
}
else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
if (!(RD = RD->getDefinition()))
- return NULL;
+ return nullptr;
// Check non-virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I =
- RD->bases_begin(), E = RD->bases_end(); I != E; ++I) {
- if (I->isVirtual() || (I->getAccessSpecifier() != AS_public))
+ for (const auto &I : RD->bases()) {
+ if (I.isVirtual() || (I.getAccessSpecifier() != AS_public))
continue;
- QualType Ty = I->getType();
+ QualType Ty = I.getType();
if (Ty.isNull())
continue;
if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) {
@@ -500,11 +514,10 @@ comments::FullComment *ASTContext::getCommentForDecl(
}
}
// Check virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I =
- RD->vbases_begin(), E = RD->vbases_end(); I != E; ++I) {
- if (I->getAccessSpecifier() != AS_public)
+ for (const auto &I : RD->vbases()) {
+ if (I.getAccessSpecifier() != AS_public)
continue;
- QualType Ty = I->getType();
+ QualType Ty = I.getType();
if (Ty.isNull())
continue;
if (const CXXRecordDecl *VirtualBase = Ty->getAsCXXRecordDecl()) {
@@ -515,7 +528,7 @@ comments::FullComment *ASTContext::getCommentForDecl(
}
}
}
- return NULL;
+ return nullptr;
}
// If the RawComment was attached to other redeclaration of this Decl, we
@@ -576,7 +589,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
// Check if we already have a canonical template template parameter.
llvm::FoldingSetNodeID ID;
CanonicalTemplateTemplateParm::Profile(ID, TTP);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
CanonicalTemplateTemplateParm *Canonical
= CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
if (Canonical)
@@ -595,7 +608,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
SourceLocation(),
SourceLocation(),
TTP->getDepth(),
- TTP->getIndex(), 0, false,
+ TTP->getIndex(), nullptr, false,
TTP->isParameterPack()));
else if (NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(*P)) {
@@ -615,7 +628,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
SourceLocation(),
SourceLocation(),
NTTP->getDepth(),
- NTTP->getPosition(), 0,
+ NTTP->getPosition(), nullptr,
T,
TInfo,
ExpandedTypes.data(),
@@ -626,7 +639,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
SourceLocation(),
SourceLocation(),
NTTP->getDepth(),
- NTTP->getPosition(), 0,
+ NTTP->getPosition(), nullptr,
T,
NTTP->isParameterPack(),
TInfo);
@@ -643,7 +656,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
SourceLocation(), TTP->getDepth(),
TTP->getPosition(),
TTP->isParameterPack(),
- 0,
+ nullptr,
TemplateParameterList::Create(*this, SourceLocation(),
SourceLocation(),
CanonParams.data(),
@@ -652,7 +665,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
// Get the new insert position for the node we care about.
Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
- assert(Canonical == 0 && "Shouldn't be in the map!");
+ assert(!Canonical && "Shouldn't be in the map!");
(void)Canonical;
// Create the canonical template template parameter entry.
@@ -662,13 +675,13 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
}
CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {
- if (!LangOpts.CPlusPlus) return 0;
+ if (!LangOpts.CPlusPlus) return nullptr;
switch (T.getCXXABI().getKind()) {
- case TargetCXXABI::GenericARM:
+ case TargetCXXABI::GenericARM: // Same as Itanium at this level
case TargetCXXABI::iOS:
- return CreateARMCXXABI(*this);
- case TargetCXXABI::GenericAArch64: // Same as Itanium at this level
+ case TargetCXXABI::iOS64:
+ case TargetCXXABI::GenericAArch64:
case TargetCXXABI::GenericItanium:
return CreateItaniumCXXABI(*this);
case TargetCXXABI::Microsoft:
@@ -710,47 +723,40 @@ static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI,
}
ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,
- const TargetInfo *t,
IdentifierTable &idents, SelectorTable &sels,
- Builtin::Context &builtins,
- unsigned size_reserve,
- bool DelayInitialization)
+ Builtin::Context &builtins)
: FunctionProtoTypes(this_()),
TemplateSpecializationTypes(this_()),
DependentTemplateSpecializationTypes(this_()),
SubstTemplateTemplateParmPacks(this_()),
- GlobalNestedNameSpecifier(0),
- Int128Decl(0), UInt128Decl(0), Float128StubDecl(0),
- BuiltinVaListDecl(0),
- ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), ObjCProtocolClassDecl(0),
- BOOLDecl(0),
- CFConstantStringTypeDecl(0), ObjCInstanceTypeDecl(0),
- FILEDecl(0),
- jmp_bufDecl(0), sigjmp_bufDecl(0), ucontext_tDecl(0),
- BlockDescriptorType(0), BlockDescriptorExtendedType(0),
- cudaConfigureCallDecl(0),
+ GlobalNestedNameSpecifier(nullptr),
+ Int128Decl(nullptr), UInt128Decl(nullptr), Float128StubDecl(nullptr),
+ BuiltinVaListDecl(nullptr),
+ ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr),
+ ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr),
+ CFConstantStringTypeDecl(nullptr), ObjCInstanceTypeDecl(nullptr),
+ FILEDecl(nullptr),
+ jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr),
+ BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr),
+ cudaConfigureCallDecl(nullptr),
NullTypeSourceInfo(QualType()),
FirstLocalImport(), LastLocalImport(),
SourceMgr(SM), LangOpts(LOpts),
- AddrSpaceMap(0), Target(t), PrintingPolicy(LOpts),
+ AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts),
Idents(idents), Selectors(sels),
BuiltinInfo(builtins),
DeclarationNames(*this),
- ExternalSource(0), Listener(0),
+ ExternalSource(nullptr), Listener(nullptr),
Comments(SM), CommentsLoaded(false),
CommentCommandTraits(BumpAlloc, LOpts.CommentOpts),
- LastSDM(0, 0)
+ LastSDM(nullptr, 0)
{
- if (size_reserve > 0) Types.reserve(size_reserve);
TUDecl = TranslationUnitDecl::Create(*this);
-
- if (!DelayInitialization) {
- assert(t && "No target supplied for ASTContext initialization");
- InitBuiltinTypes(*t);
- }
}
ASTContext::~ASTContext() {
+ ReleaseParentMapEntries();
+
// Release the DenseMaps associated with DeclContext objects.
// FIXME: Is this the ideal solution?
ReleaseDeclContextMaps();
@@ -782,11 +788,19 @@ ASTContext::~ASTContext() {
A != AEnd; ++A)
A->second->~AttrVec();
- for (llvm::DenseMap<const DeclContext *, MangleNumberingContext *>::iterator
- I = MangleNumberingContexts.begin(),
- E = MangleNumberingContexts.end();
- I != E; ++I)
- delete I->second;
+ llvm::DeleteContainerSeconds(MangleNumberingContexts);
+}
+
+void ASTContext::ReleaseParentMapEntries() {
+ if (!AllParents) return;
+ for (const auto &Entry : *AllParents) {
+ if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
+ delete Entry.second.get<ast_type_traits::DynTypedNode *>();
+ } else {
+ assert(Entry.second.is<ParentVector *>());
+ delete Entry.second.get<ParentVector *>();
+ }
+ }
}
void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
@@ -794,8 +808,8 @@ void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
}
void
-ASTContext::setExternalSource(OwningPtr<ExternalASTSource> &Source) {
- ExternalSource.reset(Source.take());
+ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) {
+ ExternalSource = Source;
}
void ASTContext::PrintStats() const {
@@ -849,7 +863,7 @@ void ASTContext::PrintStats() const {
<< NumImplicitDestructors
<< " implicit destructors created\n";
- if (ExternalSource.get()) {
+ if (ExternalSource) {
llvm::errs() << "\n";
ExternalSource->PrintStats();
}
@@ -857,45 +871,47 @@ void ASTContext::PrintStats() const {
BumpAlloc.PrintStats();
}
+RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
+ RecordDecl::TagKind TK) const {
+ SourceLocation Loc;
+ RecordDecl *NewDecl;
+ if (getLangOpts().CPlusPlus)
+ NewDecl = CXXRecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc,
+ Loc, &Idents.get(Name));
+ else
+ NewDecl = RecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, Loc,
+ &Idents.get(Name));
+ NewDecl->setImplicit();
+ return NewDecl;
+}
+
+TypedefDecl *ASTContext::buildImplicitTypedef(QualType T,
+ StringRef Name) const {
+ TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T);
+ TypedefDecl *NewDecl = TypedefDecl::Create(
+ const_cast<ASTContext &>(*this), getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(), &Idents.get(Name), TInfo);
+ NewDecl->setImplicit();
+ return NewDecl;
+}
+
TypedefDecl *ASTContext::getInt128Decl() const {
- if (!Int128Decl) {
- TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(Int128Ty);
- Int128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- &Idents.get("__int128_t"),
- TInfo);
- }
-
+ if (!Int128Decl)
+ Int128Decl = buildImplicitTypedef(Int128Ty, "__int128_t");
return Int128Decl;
}
TypedefDecl *ASTContext::getUInt128Decl() const {
- if (!UInt128Decl) {
- TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(UnsignedInt128Ty);
- UInt128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- &Idents.get("__uint128_t"),
- TInfo);
- }
-
+ if (!UInt128Decl)
+ UInt128Decl = buildImplicitTypedef(UnsignedInt128Ty, "__uint128_t");
return UInt128Decl;
}
TypeDecl *ASTContext::getFloat128StubType() const {
assert(LangOpts.CPlusPlus && "should only be called for c++");
- if (!Float128StubDecl) {
- Float128StubDecl = CXXRecordDecl::Create(const_cast<ASTContext &>(*this),
- TTK_Struct,
- getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- &Idents.get("__float128"));
- }
-
+ if (!Float128StubDecl)
+ Float128StubDecl = buildImplicitRecord("__float128");
+
return Float128StubDecl;
}
@@ -1106,7 +1122,7 @@ FunctionDecl *ASTContext::getClassScopeSpecializationPattern(
llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos
= ClassScopeSpecializationPattern.find(FD);
if (Pos == ClassScopeSpecializationPattern.end())
- return 0;
+ return nullptr;
return Pos->second;
}
@@ -1123,7 +1139,7 @@ ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) {
llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
= InstantiatedFromUsingDecl.find(UUD);
if (Pos == InstantiatedFromUsingDecl.end())
- return 0;
+ return nullptr;
return Pos->second;
}
@@ -1143,7 +1159,7 @@ ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) {
llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos
= InstantiatedFromUsingShadowDecl.find(Inst);
if (Pos == InstantiatedFromUsingShadowDecl.end())
- return 0;
+ return nullptr;
return Pos->second;
}
@@ -1159,7 +1175,7 @@ FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {
llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos
= InstantiatedFromUnnamedFieldDecl.find(Field);
if (Pos == InstantiatedFromUnnamedFieldDecl.end())
- return 0;
+ return nullptr;
return Pos->second;
}
@@ -1179,7 +1195,7 @@ ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
= OverriddenMethods.find(Method->getCanonicalDecl());
if (Pos == OverriddenMethods.end())
- return 0;
+ return nullptr;
return Pos->second.begin();
}
@@ -1189,7 +1205,7 @@ ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const {
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
= OverriddenMethods.find(Method->getCanonicalDecl());
if (Pos == OverriddenMethods.end())
- return 0;
+ return nullptr;
return Pos->second.end();
}
@@ -1293,13 +1309,14 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
} else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
- if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
+ if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
if (ForAlignof)
T = RT->getPointeeType();
else
T = getPointerType(RT->getPointeeType());
}
- if (!T->isIncompleteType() && !T->isFunctionType()) {
+ QualType BaseT = getBaseElementType(T);
+ if (!BaseT->isIncompleteType() && !T->isFunctionType()) {
// Adjust alignments of declarations with array type by the
// large-array alignment on the target.
if (const ArrayType *arrayType = getAsArrayType(T)) {
@@ -1311,9 +1328,6 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType)))
Align = std::max(Align, Target->getLargeArrayAlign());
}
-
- // Walk through any array types while we're at it.
- T = getBaseElementType(arrayType);
}
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
@@ -1618,7 +1632,7 @@ ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::MemberPointer: {
const MemberPointerType *MPT = cast<MemberPointerType>(T);
- llvm::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT);
+ std::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT);
break;
}
case Type::Complex: {
@@ -1632,8 +1646,9 @@ ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::ObjCObject:
return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());
+ case Type::Adjusted:
case Type::Decayed:
- return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr());
+ return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr());
case Type::ObjCInterface: {
const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@@ -1761,13 +1776,19 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
if (Target->getTriple().getArch() == llvm::Triple::xcore)
return ABIAlign; // Never overalign on XCore.
+ const TypedefType *TT = T->getAs<TypedefType>();
+
// Double and long long should be naturally aligned if possible.
- if (const ComplexType* CT = T->getAs<ComplexType>())
+ T = T->getBaseElementTypeUnsafe();
+ if (const ComplexType *CT = T->getAs<ComplexType>())
T = CT->getElementType().getTypePtr();
if (T->isSpecificBuiltinType(BuiltinType::Double) ||
T->isSpecificBuiltinType(BuiltinType::LongLong) ||
T->isSpecificBuiltinType(BuiltinType::ULongLong))
- return std::max(ABIAlign, (unsigned)getTypeSize(T));
+ // Don't increase the alignment if an alignment attribute was specified on a
+ // typedef declaration.
+ if (!TT || !TT->getDecl()->getMaxAlignment())
+ return std::max(ABIAlign, (unsigned)getTypeSize(T));
return ABIAlign;
}
@@ -1796,9 +1817,8 @@ void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
DeepCollectObjCIvars(SuperClass, false, Ivars);
if (!leafClass) {
- for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
- E = OI->ivar_end(); I != E; ++I)
- Ivars.push_back(*I);
+ for (const auto *I : OI->ivars())
+ Ivars.push_back(I);
} else {
ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
@@ -1814,24 +1834,17 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
// We can use protocol_iterator here instead of
// all_referenced_protocol_iterator since we are walking all categories.
- for (ObjCInterfaceDecl::all_protocol_iterator P = OI->all_referenced_protocol_begin(),
- PE = OI->all_referenced_protocol_end(); P != PE; ++P) {
- ObjCProtocolDecl *Proto = (*P);
+ for (auto *Proto : OI->all_referenced_protocols()) {
Protocols.insert(Proto->getCanonicalDecl());
- for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
- PE = Proto->protocol_end(); P != PE; ++P) {
- Protocols.insert((*P)->getCanonicalDecl());
- CollectInheritedProtocols(*P, Protocols);
+ for (auto *P : Proto->protocols()) {
+ Protocols.insert(P->getCanonicalDecl());
+ CollectInheritedProtocols(P, Protocols);
}
}
// Categories of this Interface.
- for (ObjCInterfaceDecl::visible_categories_iterator
- Cat = OI->visible_categories_begin(),
- CatEnd = OI->visible_categories_end();
- Cat != CatEnd; ++Cat) {
- CollectInheritedProtocols(*Cat, Protocols);
- }
+ for (const auto *Cat : OI->visible_categories())
+ CollectInheritedProtocols(Cat, Protocols);
if (ObjCInterfaceDecl *SD = OI->getSuperClass())
while (SD) {
@@ -1839,22 +1852,16 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
SD = SD->getSuperClass();
}
} else if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
- for (ObjCCategoryDecl::protocol_iterator P = OC->protocol_begin(),
- PE = OC->protocol_end(); P != PE; ++P) {
- ObjCProtocolDecl *Proto = (*P);
+ for (auto *Proto : OC->protocols()) {
Protocols.insert(Proto->getCanonicalDecl());
- for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
- PE = Proto->protocol_end(); P != PE; ++P)
- CollectInheritedProtocols(*P, Protocols);
+ for (const auto *P : Proto->protocols())
+ CollectInheritedProtocols(P, Protocols);
}
} else if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
- for (ObjCProtocolDecl::protocol_iterator P = OP->protocol_begin(),
- PE = OP->protocol_end(); P != PE; ++P) {
- ObjCProtocolDecl *Proto = (*P);
+ for (auto *Proto : OP->protocols()) {
Protocols.insert(Proto->getCanonicalDecl());
- for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
- PE = Proto->protocol_end(); P != PE; ++P)
- CollectInheritedProtocols(*P, Protocols);
+ for (const auto *P : Proto->protocols())
+ CollectInheritedProtocols(P, Protocols);
}
}
}
@@ -1862,12 +1869,8 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const {
unsigned count = 0;
// Count ivars declared in class extension.
- for (ObjCInterfaceDecl::known_extensions_iterator
- Ext = OI->known_extensions_begin(),
- ExtEnd = OI->known_extensions_end();
- Ext != ExtEnd; ++Ext) {
+ for (const auto *Ext : OI->known_extensions())
count += Ext->ivar_size();
- }
// Count ivar defined in this class's implementation. This
// includes synthesized ivars.
@@ -1901,7 +1904,7 @@ ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D)
I = ObjCImpls.find(D);
if (I != ObjCImpls.end())
return cast<ObjCImplementationDecl>(I->second);
- return 0;
+ return nullptr;
}
/// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
@@ -1909,7 +1912,7 @@ ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
I = ObjCImpls.find(D);
if (I != ObjCImpls.end())
return cast<ObjCCategoryImplDecl>(I->second);
- return 0;
+ return nullptr;
}
/// \brief Set the implementation of ObjCInterfaceDecl.
@@ -1937,7 +1940,7 @@ const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(
dyn_cast<ObjCImplDecl>(ND->getDeclContext()))
return IMD->getClassInterface();
- return 0;
+ return nullptr;
}
/// \brief Get the copy initialization expression of VarDecl,or NULL if
@@ -1948,7 +1951,7 @@ Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) {
"getBlockVarCopyInits - not __block var");
llvm::DenseMap<const VarDecl*, Expr*>::iterator
I = BlockVarCopyInits.find(VD);
- return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : 0;
+ return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : nullptr;
}
/// \brief Set the copy inialization expression of a block var decl.
@@ -1982,7 +1985,7 @@ TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,
const ASTRecordLayout &
ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const {
- return getObjCLayout(D, 0);
+ return getObjCLayout(D, nullptr);
}
const ASTRecordLayout &
@@ -2003,7 +2006,7 @@ ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const {
// Check if we've already instantiated this type.
llvm::FoldingSetNodeID ID;
ExtQuals::Profile(ID, baseType, quals);
- void *insertPos = 0;
+ void *insertPos = nullptr;
if (ExtQuals *eq = ExtQualNodes.FindNodeOrInsertPos(ID, insertPos)) {
assert(eq->getQualifiers() == quals);
return QualType(eq, fastQuals);
@@ -2080,12 +2083,12 @@ const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T,
QualType Result;
if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(T)) {
- Result = getFunctionNoProtoType(FNPT->getResultType(), Info);
+ Result = getFunctionNoProtoType(FNPT->getReturnType(), Info);
} else {
const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.ExtInfo = Info;
- Result = getFunctionType(FPT->getResultType(), FPT->getArgTypes(), EPI);
+ Result = getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI);
}
return cast<FunctionType>(Result.getTypePtr());
@@ -2097,7 +2100,7 @@ void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD,
while (true) {
const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>();
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
- FD->setType(getFunctionType(ResultType, FPT->getArgTypes(), EPI));
+ FD->setType(getFunctionType(ResultType, FPT->getParamTypes(), EPI));
if (FunctionDecl *Next = FD->getPreviousDecl())
FD = Next;
else
@@ -2115,7 +2118,7 @@ QualType ASTContext::getComplexType(QualType T) const {
llvm::FoldingSetNodeID ID;
ComplexType::Profile(ID, T);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(CT, 0);
@@ -2127,7 +2130,7 @@ QualType ASTContext::getComplexType(QualType T) const {
// Get the new insert position for the node we care about.
ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
ComplexType *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
Types.push_back(New);
@@ -2143,7 +2146,7 @@ QualType ASTContext::getPointerType(QualType T) const {
llvm::FoldingSetNodeID ID;
PointerType::Profile(ID, T);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
@@ -2155,7 +2158,7 @@ QualType ASTContext::getPointerType(QualType T) const {
// Get the new insert position for the node we care about.
PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
PointerType *New = new (*this, TypeAlignment) PointerType(T, Canonical);
Types.push_back(New);
@@ -2163,15 +2166,30 @@ QualType ASTContext::getPointerType(QualType T) const {
return QualType(New, 0);
}
+QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const {
+ llvm::FoldingSetNodeID ID;
+ AdjustedType::Profile(ID, Orig, New);
+ void *InsertPos = nullptr;
+ AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+ if (AT)
+ return QualType(AT, 0);
+
+ QualType Canonical = getCanonicalType(New);
+
+ // Get the new insert position for the node we care about.
+ AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!AT && "Shouldn't be in the map!");
+
+ AT = new (*this, TypeAlignment)
+ AdjustedType(Type::Adjusted, Orig, New, Canonical);
+ Types.push_back(AT);
+ AdjustedTypes.InsertNode(AT, InsertPos);
+ return QualType(AT, 0);
+}
+
QualType ASTContext::getDecayedType(QualType T) const {
assert((T->isArrayType() || T->isFunctionType()) && "T does not decay");
- llvm::FoldingSetNodeID ID;
- DecayedType::Profile(ID, T);
- void *InsertPos = 0;
- if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(DT, 0);
-
QualType Decayed;
// C99 6.7.5.3p7:
@@ -2189,17 +2207,23 @@ QualType ASTContext::getDecayedType(QualType T) const {
if (T->isFunctionType())
Decayed = getPointerType(T);
+ llvm::FoldingSetNodeID ID;
+ AdjustedType::Profile(ID, T, Decayed);
+ void *InsertPos = nullptr;
+ AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+ if (AT)
+ return QualType(AT, 0);
+
QualType Canonical = getCanonicalType(Decayed);
// Get the new insert position for the node we care about.
- DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!AT && "Shouldn't be in the map!");
- DecayedType *New =
- new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);
- Types.push_back(New);
- DecayedTypes.InsertNode(New, InsertPos);
- return QualType(New, 0);
+ AT = new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);
+ Types.push_back(AT);
+ AdjustedTypes.InsertNode(AT, InsertPos);
+ return QualType(AT, 0);
}
/// getBlockPointerType - Return the uniqued reference to the type for
@@ -2211,7 +2235,7 @@ QualType ASTContext::getBlockPointerType(QualType T) const {
llvm::FoldingSetNodeID ID;
BlockPointerType::Profile(ID, T);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (BlockPointerType *PT =
BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
@@ -2225,7 +2249,7 @@ QualType ASTContext::getBlockPointerType(QualType T) const {
// Get the new insert position for the node we care about.
BlockPointerType *NewIP =
BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
BlockPointerType *New
= new (*this, TypeAlignment) BlockPointerType(T, Canonical);
@@ -2246,7 +2270,7 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
llvm::FoldingSetNodeID ID;
ReferenceType::Profile(ID, T, SpelledAsLValue);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (LValueReferenceType *RT =
LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(RT, 0);
@@ -2263,7 +2287,7 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
// Get the new insert position for the node we care about.
LValueReferenceType *NewIP =
LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
LValueReferenceType *New
@@ -2283,7 +2307,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
llvm::FoldingSetNodeID ID;
ReferenceType::Profile(ID, T, false);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (RValueReferenceType *RT =
RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(RT, 0);
@@ -2300,7 +2324,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
// Get the new insert position for the node we care about.
RValueReferenceType *NewIP =
RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
RValueReferenceType *New
@@ -2318,7 +2342,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
llvm::FoldingSetNodeID ID;
MemberPointerType::Profile(ID, T, Cls);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (MemberPointerType *PT =
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
@@ -2332,7 +2356,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
// Get the new insert position for the node we care about.
MemberPointerType *NewIP =
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
MemberPointerType *New
= new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
@@ -2360,7 +2384,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
llvm::FoldingSetNodeID ID;
ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, IndexTypeQuals);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (ConstantArrayType *ATP =
ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(ATP, 0);
@@ -2377,7 +2401,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
// Get the new insert position for the node we care about.
ConstantArrayType *NewIP =
ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
ConstantArrayType *New = new(*this,TypeAlignment)
@@ -2495,7 +2519,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
const IncompleteArrayType *iat = cast<IncompleteArrayType>(ty);
result = getVariableArrayType(
getVariableArrayDecayedType(iat->getElementType()),
- /*size*/ 0,
+ /*size*/ nullptr,
ArrayType::Normal,
iat->getIndexTypeCVRQualifiers(),
SourceRange());
@@ -2507,7 +2531,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
const VariableArrayType *vat = cast<VariableArrayType>(ty);
result = getVariableArrayType(
getVariableArrayDecayedType(vat->getElementType()),
- /*size*/ 0,
+ /*size*/ nullptr,
ArrayType::Star,
vat->getIndexTypeCVRQualifiers(),
vat->getBracketsRange());
@@ -2577,7 +2601,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType,
SplitQualType canonElementType = getCanonicalType(elementType).split();
- void *insertPos = 0;
+ void *insertPos = nullptr;
llvm::FoldingSetNodeID ID;
DependentSizedArrayType::Profile(ID, *this,
QualType(canonElementType.Ty, 0),
@@ -2622,7 +2646,7 @@ QualType ASTContext::getIncompleteArrayType(QualType elementType,
llvm::FoldingSetNodeID ID;
IncompleteArrayType::Profile(ID, elementType, ASM, elementTypeQuals);
- void *insertPos = 0;
+ void *insertPos = nullptr;
if (IncompleteArrayType *iat =
IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos))
return QualType(iat, 0);
@@ -2662,7 +2686,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
llvm::FoldingSetNodeID ID;
VectorType::Profile(ID, vecType, NumElts, Type::Vector, VecKind);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
@@ -2674,7 +2698,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
// Get the new insert position for the node we care about.
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
VectorType *New = new (*this, TypeAlignment)
VectorType(vecType, NumElts, Canonical, VecKind);
@@ -2693,7 +2717,7 @@ ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const {
llvm::FoldingSetNodeID ID;
VectorType::Profile(ID, vecType, NumElts, Type::ExtVector,
VectorType::GenericVector);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
@@ -2705,7 +2729,7 @@ ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const {
// Get the new insert position for the node we care about.
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
ExtVectorType *New = new (*this, TypeAlignment)
ExtVectorType(vecType, NumElts, Canonical);
@@ -2722,7 +2746,7 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType,
DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType),
SizeExpr);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentSizedExtVectorType *Canon
= DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
DependentSizedExtVectorType *New;
@@ -2768,7 +2792,7 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy,
llvm::FoldingSetNodeID ID;
FunctionNoProtoType::Profile(ID, ResultTy, Info);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (FunctionNoProtoType *FT =
FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(FT, 0);
@@ -2780,7 +2804,7 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy,
// Get the new insert position for the node we care about.
FunctionNoProtoType *NewIP =
FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
FunctionProtoType::ExtInfo newInfo = Info.withCallingConv(CallConv);
@@ -2798,8 +2822,6 @@ static bool isCanonicalResultType(QualType T) {
T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone);
}
-/// getFunctionType - Return a normal function type with a typed argument
-/// list. isVariadic indicates whether the argument list includes '...'.
QualType
ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
const FunctionProtoType::ExtProtoInfo &EPI) const {
@@ -2811,7 +2833,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI,
*this);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (FunctionProtoType *FTP =
FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(FTP, 0);
@@ -2851,7 +2873,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
// Get the new insert position for the node we care about.
FunctionProtoType *NewIP =
FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
// FunctionProtoType objects are allocated with extra bytes after
@@ -2873,7 +2895,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
} else if (EPI.ExceptionSpecType == EST_Unevaluated) {
Size += sizeof(FunctionDecl*);
}
- if (EPI.ConsumedArguments)
+ if (EPI.ConsumedParameters)
Size += NumArgs * sizeof(bool);
FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment);
@@ -2995,7 +3017,7 @@ QualType ASTContext::getAttributedType(AttributedType::Kind attrKind,
llvm::FoldingSetNodeID id;
AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
- void *insertPos = 0;
+ void *insertPos = nullptr;
AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
if (type) return QualType(type, 0);
@@ -3019,7 +3041,7 @@ ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
llvm::FoldingSetNodeID ID;
SubstTemplateTypeParmType::Profile(ID, Parm, Replacement);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
SubstTemplateTypeParmType *SubstParm
= SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -3038,17 +3060,15 @@ QualType ASTContext::getSubstTemplateTypeParmPackType(
const TemplateTypeParmType *Parm,
const TemplateArgument &ArgPack) {
#ifndef NDEBUG
- for (TemplateArgument::pack_iterator P = ArgPack.pack_begin(),
- PEnd = ArgPack.pack_end();
- P != PEnd; ++P) {
- assert(P->getKind() == TemplateArgument::Type &&"Pack contains a non-type");
- assert(P->getAsType().isCanonical() && "Pack contains non-canonical type");
+ for (const auto &P : ArgPack.pack_elements()) {
+ assert(P.getKind() == TemplateArgument::Type &&"Pack contains a non-type");
+ assert(P.getAsType().isCanonical() && "Pack contains non-canonical type");
}
#endif
llvm::FoldingSetNodeID ID;
SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (SubstTemplateTypeParmPackType *SubstParm
= SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(SubstParm, 0);
@@ -3077,7 +3097,7 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
TemplateTypeParmDecl *TTPDecl) const {
llvm::FoldingSetNodeID ID;
TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
TemplateTypeParmType *TypeParm
= TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -3218,7 +3238,7 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template,
TemplateSpecializationType::Profile(ID, CanonTemplate,
CanonArgs.data(), NumArgs, *this);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
TemplateSpecializationType *Spec
= TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -3246,7 +3266,7 @@ ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
llvm::FoldingSetNodeID ID;
ElaboratedType::Profile(ID, Keyword, NNS, NamedType);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
return QualType(T, 0);
@@ -3270,7 +3290,7 @@ ASTContext::getParenType(QualType InnerType) const {
llvm::FoldingSetNodeID ID;
ParenType::Profile(ID, InnerType);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
ParenType *T = ParenTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
return QualType(T, 0);
@@ -3293,8 +3313,6 @@ QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
QualType Canon) const {
- assert(NNS->isDependent() && "nested-name-specifier must be dependent");
-
if (Canon.isNull()) {
NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
ElaboratedTypeKeyword CanonKeyword = Keyword;
@@ -3308,7 +3326,7 @@ QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
llvm::FoldingSetNodeID ID;
DependentNameType::Profile(ID, Keyword, NNS, Name);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentNameType *T
= DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
@@ -3349,7 +3367,7 @@ ASTContext::getDependentTemplateSpecializationType(
DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,
Name, NumArgs, Args);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentTemplateSpecializationType *T
= DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
@@ -3395,7 +3413,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,
assert(Pattern->containsUnexpandedParameterPack() &&
"Pack expansions must expand one or more parameter packs");
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
PackExpansionType *T
= PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
@@ -3408,7 +3426,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,
// contains an alias template specialization which ignores one of its
// parameters.
if (Canon->containsUnexpandedParameterPack()) {
- Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions);
+ Canon = getPackExpansionType(Canon, NumExpansions);
// Find the insert position again, in case we inserted an element into
// PackExpansionTypes and invalidated our insert position.
@@ -3419,7 +3437,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,
T = new (*this) PackExpansionType(Pattern, Canon, NumExpansions);
Types.push_back(T);
PackExpansionTypes.InsertNode(T, InsertPos);
- return QualType(T, 0);
+ return QualType(T, 0);
}
/// CmpProtocolNames - Comparison predicate for sorting protocols
@@ -3470,7 +3488,7 @@ QualType ASTContext::getObjCObjectType(QualType BaseType,
// Look in the folding set for an existing type.
llvm::FoldingSetNodeID ID;
ObjCObjectTypeImpl::Profile(ID, BaseType, Protocols, NumProtocols);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(QT, 0);
@@ -3507,13 +3525,79 @@ QualType ASTContext::getObjCObjectType(QualType BaseType,
return QualType(T, 0);
}
+/// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's
+/// protocol list adopt all protocols in QT's qualified-id protocol
+/// list.
+bool ASTContext::ObjCObjectAdoptsQTypeProtocols(QualType QT,
+ ObjCInterfaceDecl *IC) {
+ if (!QT->isObjCQualifiedIdType())
+ return false;
+
+ if (const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>()) {
+ // If both the right and left sides have qualifiers.
+ for (auto *Proto : OPT->quals()) {
+ if (!IC->ClassImplementsProtocol(Proto, false))
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
+/// QT's qualified-id protocol list adopt all protocols in IDecl's list
+/// of protocols.
+bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
+ ObjCInterfaceDecl *IDecl) {
+ if (!QT->isObjCQualifiedIdType())
+ return false;
+ const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();
+ if (!OPT)
+ return false;
+ if (!IDecl->hasDefinition())
+ return false;
+ llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocols;
+ CollectInheritedProtocols(IDecl, InheritedProtocols);
+ if (InheritedProtocols.empty())
+ return false;
+ // Check that if every protocol in list of id<plist> conforms to a protcol
+ // of IDecl's, then bridge casting is ok.
+ bool Conforms = false;
+ for (auto *Proto : OPT->quals()) {
+ Conforms = false;
+ for (auto *PI : InheritedProtocols) {
+ if (ProtocolCompatibleWithProtocol(Proto, PI)) {
+ Conforms = true;
+ break;
+ }
+ }
+ if (!Conforms)
+ break;
+ }
+ if (Conforms)
+ return true;
+
+ for (auto *PI : InheritedProtocols) {
+ // If both the right and left sides have qualifiers.
+ bool Adopts = false;
+ for (auto *Proto : OPT->quals()) {
+ // return 'true' if 'PI' is in the inheritance hierarchy of Proto
+ if ((Adopts = ProtocolCompatibleWithProtocol(PI, Proto)))
+ break;
+ }
+ if (!Adopts)
+ return false;
+ }
+ return true;
+}
+
/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
/// the given object type.
QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const {
llvm::FoldingSetNodeID ID;
ObjCObjectPointerType::Profile(ID, ObjectT);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (ObjCObjectPointerType *QT =
ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(QT, 0);
@@ -3572,7 +3656,7 @@ QualType ASTContext::getTypeOfExprType(Expr *tofExpr) const {
llvm::FoldingSetNodeID ID;
DependentTypeOfExprType::Profile(ID, *this, tofExpr);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentTypeOfExprType *Canon
= DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos);
if (Canon) {
@@ -3596,10 +3680,10 @@ QualType ASTContext::getTypeOfExprType(Expr *tofExpr) const {
}
/// getTypeOfType - Unlike many "get<Type>" functions, we don't unique
-/// TypeOfType AST's. The only motivation to unique these nodes would be
+/// TypeOfType nodes. The only motivation to unique these nodes would be
/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical type's (which are always unique).
+/// an issue. This doesn't affect the type checker, since it operates
+/// on canonical types (which are always unique).
QualType ASTContext::getTypeOfType(QualType tofType) const {
QualType Canonical = getCanonicalType(tofType);
TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
@@ -3608,39 +3692,34 @@ QualType ASTContext::getTypeOfType(QualType tofType) const {
}
-/// getDecltypeType - Unlike many "get<Type>" functions, we don't unique
-/// DecltypeType AST's. The only motivation to unique these nodes would be
-/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical types (which are always unique).
+/// \brief Unlike many "get<Type>" functions, we don't unique DecltypeType
+/// nodes. This would never be helpful, since each such type has its own
+/// expression, and would not give a significant memory saving, since there
+/// is an Expr tree under each such type.
QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
DecltypeType *dt;
-
- // C++0x [temp.type]p2:
+
+ // C++11 [temp.type]p2:
// If an expression e involves a template parameter, decltype(e) denotes a
- // unique dependent type. Two such decltype-specifiers refer to the same
- // type only if their expressions are equivalent (14.5.6.1).
+ // unique dependent type. Two such decltype-specifiers refer to the same
+ // type only if their expressions are equivalent (14.5.6.1).
if (e->isInstantiationDependent()) {
llvm::FoldingSetNodeID ID;
DependentDecltypeType::Profile(ID, *this, e);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentDecltypeType *Canon
= DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);
- if (Canon) {
- // We already have a "canonical" version of an equivalent, dependent
- // decltype type. Use that as our canonical type.
- dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
- QualType((DecltypeType*)Canon, 0));
- } else {
+ if (!Canon) {
// Build a new, canonical typeof(expr) type.
Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e);
DependentDecltypeTypes.InsertNode(Canon, InsertPos);
- dt = Canon;
}
+ dt = new (*this, TypeAlignment)
+ DecltypeType(e, UnderlyingType, QualType((DecltypeType *)Canon, 0));
} else {
- dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
- getCanonicalType(UnderlyingType));
+ dt = new (*this, TypeAlignment)
+ DecltypeType(e, UnderlyingType, getCanonicalType(UnderlyingType));
}
Types.push_back(dt);
return QualType(dt, 0);
@@ -3670,7 +3749,7 @@ QualType ASTContext::getAutoType(QualType DeducedType, bool IsDecltypeAuto,
return getAutoDeductType();
// Look in the folding set for an existing type.
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
llvm::FoldingSetNodeID ID;
AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent);
if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
@@ -3693,7 +3772,7 @@ QualType ASTContext::getAtomicType(QualType T) const {
llvm::FoldingSetNodeID ID;
AtomicType::Profile(ID, T);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (AtomicType *AT = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(AT, 0);
@@ -3705,7 +3784,7 @@ QualType ASTContext::getAtomicType(QualType T) const {
// Get the new insert position for the node we care about.
AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
AtomicType *New = new (*this, TypeAlignment) AtomicType(T, Canonical);
Types.push_back(New);
@@ -4064,7 +4143,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
NestedNameSpecifier *
ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
if (!NNS)
- return 0;
+ return nullptr;
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
@@ -4076,13 +4155,13 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
case NestedNameSpecifier::Namespace:
// A namespace is canonical; build a nested-name-specifier with
// this namespace and no prefix.
- return NestedNameSpecifier::Create(*this, 0,
+ return NestedNameSpecifier::Create(*this, nullptr,
NNS->getAsNamespace()->getOriginalNamespace());
case NestedNameSpecifier::NamespaceAlias:
// A namespace is canonical; build a nested-name-specifier with
// this namespace and no prefix.
- return NestedNameSpecifier::Create(*this, 0,
+ return NestedNameSpecifier::Create(*this, nullptr,
NNS->getAsNamespaceAlias()->getNamespace()
->getOriginalNamespace());
@@ -4104,8 +4183,8 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
// Otherwise, just canonicalize the type, and force it to be a TypeSpec.
// FIXME: Why are TypeSpec and TypeSpecWithTemplate distinct in the
// first place?
- return NestedNameSpecifier::Create(*this, 0, false,
- const_cast<Type*>(T.getTypePtr()));
+ return NestedNameSpecifier::Create(*this, nullptr, false,
+ const_cast<Type *>(T.getTypePtr()));
}
case NestedNameSpecifier::Global:
@@ -4127,7 +4206,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// Handle the common negative case fast.
if (!isa<ArrayType>(T.getCanonicalType()))
- return 0;
+ return nullptr;
// Apply any qualifiers from the array type to the element type. This
// implements C99 6.7.3p8: "If the specification of an array type includes
@@ -4142,7 +4221,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// If we have a simple case, just return now.
const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty);
- if (ATy == 0 || qs.empty())
+ if (!ATy || qs.empty())
return ATy;
// Otherwise, we have an array and we have qualifiers on it. Push the
@@ -4428,7 +4507,7 @@ static const Type *getIntegerTypeForEnum(const EnumType *ET) {
// FIXME: In C++, enum types are never integer types.
if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
return ET->getDecl()->getIntegerType().getTypePtr();
- return NULL;
+ return nullptr;
}
/// getIntegerTypeOrder - Returns the highest ranked integer type:
@@ -4479,22 +4558,10 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {
return 1;
}
-static RecordDecl *
-CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK,
- DeclContext *DC, IdentifierInfo *Id) {
- SourceLocation Loc;
- if (Ctx.getLangOpts().CPlusPlus)
- return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
- else
- return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
-}
-
// getCFConstantStringType - Return the type used for constant CFStrings.
QualType ASTContext::getCFConstantStringType() const {
if (!CFConstantStringTypeDecl) {
- CFConstantStringTypeDecl =
- CreateRecordDecl(*this, TTK_Struct, TUDecl,
- &Idents.get("NSConstantString"));
+ CFConstantStringTypeDecl = buildImplicitRecord("NSConstantString");
CFConstantStringTypeDecl->startDefinition();
QualType FieldTypes[4];
@@ -4512,9 +4579,9 @@ QualType ASTContext::getCFConstantStringType() const {
for (unsigned i = 0; i < 4; ++i) {
FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl,
SourceLocation(),
- SourceLocation(), 0,
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ SourceLocation(), nullptr,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -4529,8 +4596,7 @@ QualType ASTContext::getCFConstantStringType() const {
QualType ASTContext::getObjCSuperType() const {
if (ObjCSuperType.isNull()) {
- RecordDecl *ObjCSuperTypeDecl =
- CreateRecordDecl(*this, TTK_Struct, TUDecl, &Idents.get("objc_super"));
+ RecordDecl *ObjCSuperTypeDecl = buildImplicitRecord("objc_super");
TUDecl->addDecl(ObjCSuperTypeDecl);
ObjCSuperType = getTagDeclType(ObjCSuperTypeDecl);
}
@@ -4547,12 +4613,11 @@ QualType ASTContext::getBlockDescriptorType() const {
if (BlockDescriptorType)
return getTagDeclType(BlockDescriptorType);
- RecordDecl *T;
+ RecordDecl *RD;
// FIXME: Needs the FlagAppleBlock bit.
- T = CreateRecordDecl(*this, TTK_Struct, TUDecl,
- &Idents.get("__block_descriptor"));
- T->startDefinition();
-
+ RD = buildImplicitRecord("__block_descriptor");
+ RD->startDefinition();
+
QualType FieldTypes[] = {
UnsignedLongTy,
UnsignedLongTy,
@@ -4564,20 +4629,17 @@ QualType ASTContext::getBlockDescriptorType() const {
};
for (size_t i = 0; i < 2; ++i) {
- FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
- SourceLocation(),
- &Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
- /*Mutable=*/false,
- ICIS_NoInit);
+ FieldDecl *Field = FieldDecl::Create(
+ *this, RD, SourceLocation(), SourceLocation(),
+ &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
Field->setAccess(AS_public);
- T->addDecl(Field);
+ RD->addDecl(Field);
}
- T->completeDefinition();
+ RD->completeDefinition();
- BlockDescriptorType = T;
+ BlockDescriptorType = RD;
return getTagDeclType(BlockDescriptorType);
}
@@ -4586,12 +4648,11 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
if (BlockDescriptorExtendedType)
return getTagDeclType(BlockDescriptorExtendedType);
- RecordDecl *T;
+ RecordDecl *RD;
// FIXME: Needs the FlagAppleBlock bit.
- T = CreateRecordDecl(*this, TTK_Struct, TUDecl,
- &Idents.get("__block_descriptor_withcopydispose"));
- T->startDefinition();
-
+ RD = buildImplicitRecord("__block_descriptor_withcopydispose");
+ RD->startDefinition();
+
QualType FieldTypes[] = {
UnsignedLongTy,
UnsignedLongTy,
@@ -4607,21 +4668,18 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
};
for (size_t i = 0; i < 4; ++i) {
- FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
- SourceLocation(),
- &Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
- /*Mutable=*/false,
- ICIS_NoInit);
+ FieldDecl *Field = FieldDecl::Create(
+ *this, RD, SourceLocation(), SourceLocation(),
+ &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
+ /*Mutable=*/false, ICIS_NoInit);
Field->setAccess(AS_public);
- T->addDecl(Field);
+ RD->addDecl(Field);
}
- T->completeDefinition();
-
- BlockDescriptorExtendedType = T;
+ RD->completeDefinition();
+ BlockDescriptorExtendedType = RD;
return getTagDeclType(BlockDescriptorExtendedType);
}
@@ -4691,12 +4749,8 @@ bool ASTContext::getByrefLifetime(QualType Ty,
TypedefDecl *ASTContext::getObjCInstanceTypeDecl() {
if (!ObjCInstanceTypeDecl)
- ObjCInstanceTypeDecl = TypedefDecl::Create(*this,
- getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- &Idents.get("instancetype"),
- getTrivialTypeSourceInfo(getObjCIdType()));
+ ObjCInstanceTypeDecl =
+ buildImplicitTypedef(getObjCIdType(), "instancetype");
return ObjCInstanceTypeDecl;
}
@@ -4727,6 +4781,12 @@ CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const {
return sz;
}
+bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const {
+ return getLangOpts().MSVCCompat && VD->isStaticDataMember() &&
+ VD->getType()->isIntegralOrEnumerationType() &&
+ !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit();
+}
+
static inline
std::string charUnitsToString(const CharUnits &CU) {
return llvm::itostr(CU.getQuantity());
@@ -4742,21 +4802,19 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
Expr->getType()->getAs<BlockPointerType>()->getPointeeType();
// Encode result type.
if (getLangOpts().EncodeExtendedBlockSig)
- getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None,
- BlockTy->getAs<FunctionType>()->getResultType(),
- S, true /*Extended*/);
+ getObjCEncodingForMethodParameter(
+ Decl::OBJC_TQ_None, BlockTy->getAs<FunctionType>()->getReturnType(), S,
+ true /*Extended*/);
else
- getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getResultType(),
- S);
+ getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getReturnType(), S);
// Compute size of all parameters.
// Start with computing size of a pointer in number of bytes.
// FIXME: There might(should) be a better way of doing this computation!
SourceLocation Loc;
CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);
CharUnits ParmOffset = PtrSize;
- for (BlockDecl::param_const_iterator PI = Decl->param_begin(),
- E = Decl->param_end(); PI != E; ++PI) {
- QualType PType = (*PI)->getType();
+ for (auto PI : Decl->params()) {
+ QualType PType = PI->getType();
CharUnits sz = getObjCEncodingTypeSize(PType);
if (sz.isZero())
continue;
@@ -4770,9 +4828,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
// Argument types.
ParmOffset = PtrSize;
- for (BlockDecl::param_const_iterator PI = Decl->param_begin(), E =
- Decl->param_end(); PI != E; ++PI) {
- ParmVarDecl *PVDecl = *PI;
+ for (auto PVDecl : Decl->params()) {
QualType PType = PVDecl->getOriginalType();
if (const ArrayType *AT =
dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
@@ -4797,12 +4853,11 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl,
std::string& S) {
// Encode result type.
- getObjCEncodingForType(Decl->getResultType(), S);
+ getObjCEncodingForType(Decl->getReturnType(), S);
CharUnits ParmOffset;
// Compute size of all parameters.
- for (FunctionDecl::param_const_iterator PI = Decl->param_begin(),
- E = Decl->param_end(); PI != E; ++PI) {
- QualType PType = (*PI)->getType();
+ for (auto PI : Decl->params()) {
+ QualType PType = PI->getType();
CharUnits sz = getObjCEncodingTypeSize(PType);
if (sz.isZero())
continue;
@@ -4815,9 +4870,7 @@ bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl,
ParmOffset = CharUnits::Zero();
// Argument types.
- for (FunctionDecl::param_const_iterator PI = Decl->param_begin(),
- E = Decl->param_end(); PI != E; ++PI) {
- ParmVarDecl *PVDecl = *PI;
+ for (auto PVDecl : Decl->params()) {
QualType PType = PVDecl->getOriginalType();
if (const ArrayType *AT =
dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
@@ -4844,7 +4897,7 @@ void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
// Encode type qualifer, 'in', 'inout', etc. for the parameter.
getObjCEncodingForTypeQualifier(QT, S);
// Encode parameter type.
- getObjCEncodingForTypeImpl(T, S, true, true, 0,
+ getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
true /*OutermostType*/,
false /*EncodingProperty*/,
false /*StructField*/,
@@ -4859,8 +4912,8 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
bool Extended) const {
// FIXME: This is not very efficient.
// Encode return type.
- getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(),
- Decl->getResultType(), S, Extended);
+ getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(),
+ Decl->getReturnType(), S, Extended);
// Compute size of all parameters.
// Start with computing size of a pointer in number of bytes.
// FIXME: There might(should) be a better way of doing this computation!
@@ -4907,6 +4960,26 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
return false;
}
+ObjCPropertyImplDecl *
+ASTContext::getObjCPropertyImplDeclForPropertyDecl(
+ const ObjCPropertyDecl *PD,
+ const Decl *Container) const {
+ if (!Container)
+ return nullptr;
+ if (const ObjCCategoryImplDecl *CID =
+ dyn_cast<ObjCCategoryImplDecl>(Container)) {
+ for (auto *PID : CID->property_impls())
+ if (PID->getPropertyDecl() == PD)
+ return PID;
+ } else {
+ const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
+ for (auto *PID : OID->property_impls())
+ if (PID->getPropertyDecl() == PD)
+ return PID;
+ }
+ return nullptr;
+}
+
/// getObjCEncodingForPropertyDecl - Return the encoded type for this
/// property declaration. If non-NULL, Container must be either an
/// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be
@@ -4937,39 +5010,14 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
std::string& S) const {
// Collect information from the property implementation decl(s).
bool Dynamic = false;
- ObjCPropertyImplDecl *SynthesizePID = 0;
-
- // FIXME: Duplicated code due to poor abstraction.
- if (Container) {
- if (const ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(Container)) {
- for (ObjCCategoryImplDecl::propimpl_iterator
- i = CID->propimpl_begin(), e = CID->propimpl_end();
- i != e; ++i) {
- ObjCPropertyImplDecl *PID = *i;
- if (PID->getPropertyDecl() == PD) {
- if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
- Dynamic = true;
- } else {
- SynthesizePID = PID;
- }
- }
- }
- } else {
- const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
- for (ObjCCategoryImplDecl::propimpl_iterator
- i = OID->propimpl_begin(), e = OID->propimpl_end();
- i != e; ++i) {
- ObjCPropertyImplDecl *PID = *i;
- if (PID->getPropertyDecl() == PD) {
- if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
- Dynamic = true;
- } else {
- SynthesizePID = PID;
- }
- }
- }
- }
+ ObjCPropertyImplDecl *SynthesizePID = nullptr;
+
+ if (ObjCPropertyImplDecl *PropertyImpDecl =
+ getObjCPropertyImplDeclForPropertyDecl(PD, Container)) {
+ if (PropertyImpDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+ Dynamic = true;
+ else
+ SynthesizePID = PropertyImpDecl;
}
// FIXME: This is not very efficient.
@@ -4978,9 +5026,7 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
// Encode result type.
// GCC has some special rules regarding encoding of properties which
// closely resembles encoding of ivars.
- getObjCEncodingForTypeImpl(PD->getType(), S, true, true, 0,
- true /* outermost type */,
- true /* encoding for property */);
+ getObjCEncodingForPropertyType(PD->getType(), S);
if (PD->isReadOnly()) {
S += ",R";
@@ -4988,6 +5034,8 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
S += ",C";
if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain)
S += ",&";
+ if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
+ S += ",W";
} else {
switch (PD->getSetterKind()) {
case ObjCPropertyDecl::Assign: break;
@@ -5051,6 +5099,16 @@ void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
true /* outermost type */);
}
+void ASTContext::getObjCEncodingForPropertyType(QualType T,
+ std::string& S) const {
+ // Encode result type.
+ // GCC has some special rules regarding encoding of properties which
+ // closely resembles encoding of ivars.
+ getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
+ true /* outermost type */,
+ true /* encoding property */);
+}
+
static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
BuiltinType::Kind kind) {
switch (kind) {
@@ -5180,15 +5238,15 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::Complex: {
const ComplexType *CT = T->castAs<ComplexType>();
S += 'j';
- getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, 0, false,
- false);
+ getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr,
+ false, false);
return;
}
case Type::Atomic: {
const AtomicType *AT = T->castAs<AtomicType>();
S += 'A';
- getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, 0,
+ getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr,
false, false);
return;
}
@@ -5260,7 +5318,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
getLegacyIntegralTypeEncoding(PointeeTy);
getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures,
- NULL);
+ nullptr);
return;
}
@@ -5322,9 +5380,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
if (!RDecl->isUnion()) {
getObjCEncodingForStructureImpl(RDecl, S, FD);
} else {
- for (RecordDecl::field_iterator Field = RDecl->field_begin(),
- FieldEnd = RDecl->field_end();
- Field != FieldEnd; ++Field) {
+ for (const auto *Field : RDecl->fields()) {
if (FD) {
S += '"';
S += Field->getNameAsString();
@@ -5334,7 +5390,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Special case bit-fields.
if (Field->isBitField()) {
getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
- *Field);
+ Field);
} else {
QualType qt = Field->getType();
getLegacyIntegralTypeEncoding(qt);
@@ -5358,37 +5414,38 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += '<';
// Block return type
- getObjCEncodingForTypeImpl(FT->getResultType(), S,
- ExpandPointedToStructures, ExpandStructures,
- FD,
- false /* OutermostType */,
- EncodingProperty,
- false /* StructField */,
- EncodeBlockParameters,
- EncodeClassNames);
+ getObjCEncodingForTypeImpl(
+ FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures,
+ FD, false /* OutermostType */, EncodingProperty,
+ false /* StructField */, EncodeBlockParameters, EncodeClassNames);
// Block self
S += "@?";
// Block parameters
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
- for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(),
- E = FPT->arg_type_end(); I && (I != E); ++I) {
- getObjCEncodingForTypeImpl(*I, S,
- ExpandPointedToStructures,
- ExpandStructures,
- FD,
- false /* OutermostType */,
- EncodingProperty,
- false /* StructField */,
- EncodeBlockParameters,
- EncodeClassNames);
- }
+ for (const auto &I : FPT->param_types())
+ getObjCEncodingForTypeImpl(
+ I, S, ExpandPointedToStructures, ExpandStructures, FD,
+ false /* OutermostType */, EncodingProperty,
+ false /* StructField */, EncodeBlockParameters, EncodeClassNames);
}
S += '>';
}
return;
}
- case Type::ObjCObject:
+ case Type::ObjCObject: {
+ // hack to match legacy encoding of *id and *Class
+ QualType Ty = getObjCObjectPointerType(CT);
+ if (Ty->isObjCIdType()) {
+ S += "{objc_object=}";
+ return;
+ }
+ else if (Ty->isObjCClassType()) {
+ S += "{objc_class=}";
+ return;
+ }
+ }
+
case Type::ObjCInterface: {
// Ignore protocol qualifiers when mangling at this level.
T = T->castAs<ObjCObjectType>()->getBaseType();
@@ -5440,10 +5497,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Note that we do extended encoding of protocol qualifer list
// Only when doing ivar or property encoding.
S += '"';
- for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
- E = OPT->qual_end(); I != E; ++I) {
+ for (const auto *I : OPT->quals()) {
S += '<';
- S += (*I)->getNameAsString();
+ S += I->getNameAsString();
S += '>';
}
S += '"';
@@ -5475,7 +5531,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
getObjCEncodingForTypeImpl(PointeeTy, S,
false, ExpandPointedToStructures,
- NULL,
+ nullptr,
false, false, false, false, false,
/*EncodePointerToObjCTypedef*/true);
return;
@@ -5486,10 +5542,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
(FD || EncodingProperty || EncodeClassNames)) {
S += '"';
S += OPT->getInterfaceDecl()->getIdentifier()->getName();
- for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
- E = OPT->qual_end(); I != E; ++I) {
+ for (const auto *I : OPT->quals()) {
S += '<';
- S += (*I)->getNameAsString();
+ S += I->getNameAsString();
S += '>';
}
S += '"';
@@ -5542,11 +5597,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
const ASTRecordLayout &layout = getASTRecordLayout(RDecl);
if (CXXRec) {
- for (CXXRecordDecl::base_class_iterator
- BI = CXXRec->bases_begin(),
- BE = CXXRec->bases_end(); BI != BE; ++BI) {
- if (!BI->isVirtual()) {
- CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
+ for (const auto &BI : CXXRec->bases()) {
+ if (!BI.isVirtual()) {
+ CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl();
if (base->isEmpty())
continue;
uint64_t offs = toBits(layout.getBaseClassOffset(base));
@@ -5566,10 +5619,8 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
}
if (CXXRec && includeVBases) {
- for (CXXRecordDecl::base_class_iterator
- BI = CXXRec->vbases_begin(),
- BE = CXXRec->vbases_end(); BI != BE; ++BI) {
- CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
+ for (const auto &BI : CXXRec->vbases()) {
+ CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl();
if (base->isEmpty())
continue;
uint64_t offs = toBits(layout.getVBaseClassOffset(base));
@@ -5587,7 +5638,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
size = layout.getSize();
}
+#ifndef NDEBUG
uint64_t CurOffs = 0;
+#endif
std::multimap<uint64_t, NamedDecl *>::iterator
CurLayObj = FieldOrBaseOffsets.begin();
@@ -5601,19 +5654,21 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
S += '"';
}
S += "^^?";
+#ifndef NDEBUG
CurOffs += getTypeSize(VoidPtrTy);
+#endif
}
if (!RDecl->hasFlexibleArrayMember()) {
// Mark the end of the structure.
uint64_t offs = toBits(size);
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
- std::make_pair(offs, (NamedDecl*)0));
+ std::make_pair(offs, nullptr));
}
for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) {
+#ifndef NDEBUG
assert(CurOffs <= CurLayObj->first);
-
if (CurOffs < CurLayObj->first) {
uint64_t padding = CurLayObj->first - CurOffs;
// FIXME: There doesn't seem to be a way to indicate in the encoding that
@@ -5625,9 +5680,10 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
// longer then though.
CurOffs += padding;
}
+#endif
NamedDecl *dcl = CurLayObj->second;
- if (dcl == 0)
+ if (!dcl)
break; // reached end of structure.
if (CXXRecordDecl *base = dyn_cast<CXXRecordDecl>(dcl)) {
@@ -5637,7 +5693,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
// making the encoding type bigger than it really is.
getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false);
assert(!base->isEmpty());
+#ifndef NDEBUG
CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize());
+#endif
} else {
FieldDecl *field = cast<FieldDecl>(dcl);
if (FD) {
@@ -5648,7 +5706,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
if (field->isBitField()) {
EncodeBitField(this, S, field->getType(), field);
+#ifndef NDEBUG
CurOffs += field->getBitWidthValue(*this);
+#endif
} else {
QualType qt = field->getType();
getLegacyIntegralTypeEncoding(qt);
@@ -5656,7 +5716,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
/*OutermostType*/false,
/*EncodingProperty*/false,
/*StructField*/true);
+#ifndef NDEBUG
CurOffs += getTypeSize(field->getType());
+#endif
}
}
}
@@ -5680,41 +5742,27 @@ void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
TypedefDecl *ASTContext::getObjCIdDecl() const {
if (!ObjCIdDecl) {
- QualType T = getObjCObjectType(ObjCBuiltinIdTy, 0, 0);
+ QualType T = getObjCObjectType(ObjCBuiltinIdTy, nullptr, 0);
T = getObjCObjectPointerType(T);
- TypeSourceInfo *IdInfo = getTrivialTypeSourceInfo(T);
- ObjCIdDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Idents.get("id"), IdInfo);
+ ObjCIdDecl = buildImplicitTypedef(T, "id");
}
-
return ObjCIdDecl;
}
TypedefDecl *ASTContext::getObjCSelDecl() const {
if (!ObjCSelDecl) {
- QualType SelT = getPointerType(ObjCBuiltinSelTy);
- TypeSourceInfo *SelInfo = getTrivialTypeSourceInfo(SelT);
- ObjCSelDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Idents.get("SEL"), SelInfo);
+ QualType T = getPointerType(ObjCBuiltinSelTy);
+ ObjCSelDecl = buildImplicitTypedef(T, "SEL");
}
return ObjCSelDecl;
}
TypedefDecl *ASTContext::getObjCClassDecl() const {
if (!ObjCClassDecl) {
- QualType T = getObjCObjectType(ObjCBuiltinClassTy, 0, 0);
+ QualType T = getObjCObjectType(ObjCBuiltinClassTy, nullptr, 0);
T = getObjCObjectPointerType(T);
- TypeSourceInfo *ClassInfo = getTrivialTypeSourceInfo(T);
- ObjCClassDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Idents.get("Class"), ClassInfo);
+ ObjCClassDecl = buildImplicitTypedef(T, "Class");
}
-
return ObjCClassDecl;
}
@@ -5724,7 +5772,7 @@ ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const {
= ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(),
SourceLocation(),
&Idents.get("Protocol"),
- /*PrevDecl=*/0,
+ /*PrevDecl=*/nullptr,
SourceLocation(), true);
}
@@ -5737,56 +5785,30 @@ ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const {
static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) {
// typedef char* __builtin_va_list;
- QualType CharPtrType = Context->getPointerType(Context->CharTy);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(CharPtrType);
-
- TypedefDecl *VaListTypeDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
- return VaListTypeDecl;
+ QualType T = Context->getPointerType(Context->CharTy);
+ return Context->buildImplicitTypedef(T, "__builtin_va_list");
}
static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) {
// typedef void* __builtin_va_list;
- QualType VoidPtrType = Context->getPointerType(Context->VoidTy);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(VoidPtrType);
-
- TypedefDecl *VaListTypeDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
- return VaListTypeDecl;
+ QualType T = Context->getPointerType(Context->VoidTy);
+ return Context->buildImplicitTypedef(T, "__builtin_va_list");
}
static TypedefDecl *
CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
- RecordDecl *VaListTagDecl;
+ // struct __va_list
+ RecordDecl *VaListTagDecl = Context->buildImplicitRecord("__va_list");
if (Context->getLangOpts().CPlusPlus) {
// namespace std { struct __va_list {
NamespaceDecl *NS;
NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context),
Context->getTranslationUnitDecl(),
- /*Inline*/false, SourceLocation(),
+ /*Inline*/ false, SourceLocation(),
SourceLocation(), &Context->Idents.get("std"),
- /*PrevDecl*/0);
-
- VaListTagDecl = CXXRecordDecl::Create(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list"));
+ /*PrevDecl*/ nullptr);
+ NS->setImplicit();
VaListTagDecl->setDeclContext(NS);
- } else {
- // struct __va_list
- VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list"));
}
VaListTagDecl->startDefinition();
@@ -5822,8 +5844,8 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
SourceLocation(),
&Context->Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -5834,23 +5856,14 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
Context->VaListTagTy = VaListTagType;
// } __builtin_va_list;
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- Context->getTrivialTypeSourceInfo(VaListTagType));
-
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");
}
static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
// typedef struct __va_list_tag {
RecordDecl *VaListTagDecl;
- VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list_tag"));
+ VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
VaListTagDecl->startDefinition();
const size_t NumFields = 5;
@@ -5883,8 +5896,8 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
SourceLocation(),
&Context->Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -5895,12 +5908,9 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
Context->VaListTagTy = VaListTagType;
// } __va_list_tag;
- TypedefDecl *VaListTagTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list_tag"),
- Context->getTrivialTypeSourceInfo(VaListTagType));
+ TypedefDecl *VaListTagTypedefDecl =
+ Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
+
QualType VaListTagTypedefType =
Context->getTypedefType(VaListTagTypedefDecl);
@@ -5909,25 +5919,14 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
QualType VaListTagArrayType
= Context->getConstantArrayType(VaListTagTypedefType,
Size, ArrayType::Normal, 0);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
-
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
}
static TypedefDecl *
CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
// typedef struct __va_list_tag {
RecordDecl *VaListTagDecl;
- VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list_tag"));
+ VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
VaListTagDecl->startDefinition();
const size_t NumFields = 4;
@@ -5957,8 +5956,8 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
SourceLocation(),
&Context->Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -5969,12 +5968,9 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
Context->VaListTagTy = VaListTagType;
// } __va_list_tag;
- TypedefDecl *VaListTagTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list_tag"),
- Context->getTrivialTypeSourceInfo(VaListTagType));
+ TypedefDecl *VaListTagTypedefDecl =
+ Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
+
QualType VaListTagTypedefType =
Context->getTypedefType(VaListTagTypedefDecl);
@@ -5983,16 +5979,7 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
QualType VaListTagArrayType
= Context->getConstantArrayType(VaListTagTypedefType,
Size, ArrayType::Normal,0);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
-
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
}
static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) {
@@ -6001,19 +5988,13 @@ static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) {
QualType IntArrayType
= Context->getConstantArrayType(Context->IntTy,
Size, ArrayType::Normal, 0);
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- Context->getTrivialTypeSourceInfo(IntArrayType));
-
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(IntArrayType, "__builtin_va_list");
}
static TypedefDecl *
CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
- RecordDecl *VaListDecl;
+ // struct __va_list
+ RecordDecl *VaListDecl = Context->buildImplicitRecord("__va_list");
if (Context->getLangOpts().CPlusPlus) {
// namespace std { struct __va_list {
NamespaceDecl *NS;
@@ -6021,20 +6002,9 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
Context->getTranslationUnitDecl(),
/*Inline*/false, SourceLocation(),
SourceLocation(), &Context->Idents.get("std"),
- /*PrevDecl*/0);
-
- VaListDecl = CXXRecordDecl::Create(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list"));
-
+ /*PrevDecl*/ nullptr);
+ NS->setImplicit();
VaListDecl->setDeclContext(NS);
-
- } else {
- // struct __va_list {
- VaListDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list"));
}
VaListDecl->startDefinition();
@@ -6046,8 +6016,8 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
&Context->Idents.get("__ap"),
Context->getPointerType(Context->VoidTy),
- /*TInfo=*/0,
- /*BitWidth=*/0,
+ /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -6057,26 +6027,15 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
VaListDecl->completeDefinition();
// typedef struct __va_list __builtin_va_list;
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(Context->getRecordType(VaListDecl));
-
- TypedefDecl *VaListTypeDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
-
- return VaListTypeDecl;
+ QualType T = Context->getRecordType(VaListDecl);
+ return Context->buildImplicitTypedef(T, "__builtin_va_list");
}
static TypedefDecl *
CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
// typedef struct __va_list_tag {
RecordDecl *VaListTagDecl;
- VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list_tag"));
+ VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
VaListTagDecl->startDefinition();
const size_t NumFields = 4;
@@ -6106,8 +6065,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
SourceLocation(),
&Context->Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -6118,12 +6077,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
Context->VaListTagTy = VaListTagType;
// } __va_list_tag;
- TypedefDecl *VaListTagTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list_tag"),
- Context->getTrivialTypeSourceInfo(VaListTagType));
+ TypedefDecl *VaListTagTypedefDecl =
+ Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
QualType VaListTagTypedefType =
Context->getTypedefType(VaListTagTypedefDecl);
@@ -6132,16 +6087,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
QualType VaListTagArrayType
= Context->getConstantArrayType(VaListTagTypedefType,
Size, ArrayType::Normal,0);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
}
static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
@@ -6169,8 +6116,10 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
}
TypedefDecl *ASTContext::getBuiltinVaListDecl() const {
- if (!BuiltinVaListDecl)
+ if (!BuiltinVaListDecl) {
BuiltinVaListDecl = CreateVaListDecl(this, Target->getBuiltinVaListKind());
+ assert(BuiltinVaListDecl->isImplicit());
+ }
return BuiltinVaListDecl;
}
@@ -6227,7 +6176,7 @@ ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
llvm::FoldingSetNodeID ID;
QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
QualifiedTemplateName *QTN =
QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
if (!QTN) {
@@ -6250,7 +6199,7 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
llvm::FoldingSetNodeID ID;
DependentTemplateName::Profile(ID, NNS, Name);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentTemplateName *QTN =
DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
@@ -6285,8 +6234,8 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
llvm::FoldingSetNodeID ID;
DependentTemplateName::Profile(ID, NNS, Operator);
-
- void *InsertPos = 0;
+
+ void *InsertPos = nullptr;
DependentTemplateName *QTN
= DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
@@ -6317,8 +6266,8 @@ ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
TemplateName replacement) const {
llvm::FoldingSetNodeID ID;
SubstTemplateTemplateParmStorage::Profile(ID, param, replacement);
-
- void *insertPos = 0;
+
+ void *insertPos = nullptr;
SubstTemplateTemplateParmStorage *subst
= SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos);
@@ -6336,8 +6285,8 @@ ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
ASTContext &Self = const_cast<ASTContext &>(*this);
llvm::FoldingSetNodeID ID;
SubstTemplateTemplateParmPackStorage::Profile(ID, Self, Param, ArgPack);
-
- void *InsertPos = 0;
+
+ void *InsertPos = nullptr;
SubstTemplateTemplateParmPackStorage *Subst
= SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos);
@@ -6454,9 +6403,8 @@ ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
ObjCProtocolDecl *rProto) const {
if (declaresSameEntity(lProto, rProto))
return true;
- for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(),
- E = rProto->protocol_end(); PI != E; ++PI)
- if (ProtocolCompatibleWithProtocol(lProto, *PI))
+ for (auto *PI : rProto->protocols())
+ if (ProtocolCompatibleWithProtocol(lProto, PI))
return true;
return false;
}
@@ -6469,13 +6417,9 @@ bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs,
const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");
- for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
- E = lhsQID->qual_end(); I != E; ++I) {
+ for (auto *lhsProto : lhsQID->quals()) {
bool match = false;
- ObjCProtocolDecl *lhsProto = *I;
- for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
- E = rhsOPT->qual_end(); J != E; ++J) {
- ObjCProtocolDecl *rhsProto = *J;
+ for (auto *rhsProto : rhsOPT->quals()) {
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) {
match = true;
break;
@@ -6508,12 +6452,11 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
// If the RHS is a unqualified interface pointer "NSString*",
// make sure we check the class hierarchy.
if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
- for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
- E = lhsQID->qual_end(); I != E; ++I) {
+ for (auto *I : lhsQID->quals()) {
// when comparing an id<P> on lhs with a static type on rhs,
// see if static class implements all of id's protocols, directly or
// through its super class and categories.
- if (!rhsID->ClassImplementsProtocol(*I, true))
+ if (!rhsID->ClassImplementsProtocol(I, true))
return false;
}
}
@@ -6521,17 +6464,13 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
return true;
}
// Both the right and left sides have qualifiers.
- for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
- E = lhsQID->qual_end(); I != E; ++I) {
- ObjCProtocolDecl *lhsProto = *I;
+ for (auto *lhsProto : lhsQID->quals()) {
bool match = false;
// when comparing an id<P> on lhs with a static type on rhs,
// see if static class implements all of id's protocols, directly or
// through its super class and categories.
- for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
- E = rhsOPT->qual_end(); J != E; ++J) {
- ObjCProtocolDecl *rhsProto = *J;
+ for (auto *rhsProto : rhsOPT->quals()) {
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
match = true;
@@ -6541,12 +6480,11 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
// If the RHS is a qualified interface pointer "NSString<P>*",
// make sure we check the class hierarchy.
if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
- for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
- E = lhsQID->qual_end(); I != E; ++I) {
+ for (auto *I : lhsQID->quals()) {
// when comparing an id<P> on lhs with a static type on rhs,
// see if static class implements all of id's protocols, directly or
// through its super class and categories.
- if (rhsID->ClassImplementsProtocol(*I, true)) {
+ if (rhsID->ClassImplementsProtocol(I, true)) {
match = true;
break;
}
@@ -6565,9 +6503,7 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
if (const ObjCObjectPointerType *lhsOPT =
lhs->getAsObjCInterfacePointerType()) {
// If both the right and left sides have qualifiers.
- for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(),
- E = lhsOPT->qual_end(); I != E; ++I) {
- ObjCProtocolDecl *lhsProto = *I;
+ for (auto *lhsProto : lhsOPT->quals()) {
bool match = false;
// when comparing an id<P> on rhs with a static type on lhs,
@@ -6575,9 +6511,7 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
// through its super class and categories.
// First, lhs protocols in the qualifier list must be found, direct
// or indirect in rhs's qualifier list or it is a mismatch.
- for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
- E = rhsQID->qual_end(); J != E; ++J) {
- ObjCProtocolDecl *rhsProto = *J;
+ for (auto *rhsProto : rhsQID->quals()) {
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
match = true;
@@ -6598,14 +6532,9 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
// assume that it is mismatch.
if (LHSInheritedProtocols.empty() && lhsOPT->qual_empty())
return false;
- for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I =
- LHSInheritedProtocols.begin(),
- E = LHSInheritedProtocols.end(); I != E; ++I) {
+ for (auto *lhsProto : LHSInheritedProtocols) {
bool match = false;
- ObjCProtocolDecl *lhsProto = (*I);
- for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
- E = rhsQID->qual_end(); J != E; ++J) {
- ObjCProtocolDecl *rhsProto = *J;
+ for (auto *rhsProto : rhsQID->quals()) {
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
match = true;
@@ -6798,16 +6727,9 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
if (SuperClassInheritedProtocols.empty())
return false;
- for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(),
- LHSPE = LHS->qual_end();
- LHSPI != LHSPE; LHSPI++) {
- bool SuperImplementsProtocol = false;
- ObjCProtocolDecl *LHSProto = (*LHSPI);
-
- for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I =
- SuperClassInheritedProtocols.begin(),
- E = SuperClassInheritedProtocols.end(); I != E; ++I) {
- ObjCProtocolDecl *SuperClassProto = (*I);
+ for (const auto *LHSProto : LHS->quals()) {
+ bool SuperImplementsProtocol = false;
+ for (auto *SuperClassProto : SuperClassInheritedProtocols) {
if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) {
SuperImplementsProtocol = true;
break;
@@ -6821,17 +6743,13 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
return false;
}
- for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(),
- LHSPE = LHS->qual_end();
- LHSPI != LHSPE; LHSPI++) {
+ for (const auto *LHSPI : LHS->quals()) {
bool RHSImplementsProtocol = false;
// If the RHS doesn't implement the protocol on the left, the types
// are incompatible.
- for (ObjCObjectType::qual_iterator RHSPI = RHS->qual_begin(),
- RHSPE = RHS->qual_end();
- RHSPI != RHSPE; RHSPI++) {
- if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) {
+ for (auto *RHSPI : RHS->quals()) {
+ if (RHSPI->lookupProtocolNamed(LHSPI->getIdentifier())) {
RHSImplementsProtocol = true;
break;
}
@@ -6891,9 +6809,8 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,
if (const RecordType *UT = T->getAsUnionType()) {
RecordDecl *UD = UT->getDecl();
if (UD->hasAttr<TransparentUnionAttr>()) {
- for (RecordDecl::field_iterator it = UD->field_begin(),
- itend = UD->field_end(); it != itend; ++it) {
- QualType ET = it->getType().getUnqualifiedType();
+ for (const auto *I : UD->fields()) {
+ QualType ET = I->getType().getUnqualifiedType();
QualType MT = mergeTypes(ET, SubType, OfBlockPointer, Unqualified);
if (!MT.isNull())
return MT;
@@ -6904,11 +6821,11 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,
return QualType();
}
-/// mergeFunctionArgumentTypes - merge two types which appear as function
-/// argument types
-QualType ASTContext::mergeFunctionArgumentTypes(QualType lhs, QualType rhs,
- bool OfBlockPointer,
- bool Unqualified) {
+/// mergeFunctionParameterTypes - merge two types which appear as function
+/// parameter types
+QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs,
+ bool OfBlockPointer,
+ bool Unqualified) {
// GNU extension: two types are compatible if they appear as a function
// argument, one of the types is a transparent union type and the other
// type is compatible with a union member
@@ -6938,23 +6855,23 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
// Check return type
QualType retType;
if (OfBlockPointer) {
- QualType RHS = rbase->getResultType();
- QualType LHS = lbase->getResultType();
+ QualType RHS = rbase->getReturnType();
+ QualType LHS = lbase->getReturnType();
bool UnqualifiedResult = Unqualified;
if (!UnqualifiedResult)
UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers());
retType = mergeTypes(LHS, RHS, true, UnqualifiedResult, true);
}
else
- retType = mergeTypes(lbase->getResultType(), rbase->getResultType(), false,
+ retType = mergeTypes(lbase->getReturnType(), rbase->getReturnType(), false,
Unqualified);
if (retType.isNull()) return QualType();
if (Unqualified)
retType = retType.getUnqualifiedType();
- CanQualType LRetType = getCanonicalType(lbase->getResultType());
- CanQualType RRetType = getCanonicalType(rbase->getResultType());
+ CanQualType LRetType = getCanonicalType(lbase->getReturnType());
+ CanQualType RRetType = getCanonicalType(rbase->getReturnType());
if (Unqualified) {
LRetType = LRetType.getUnqualifiedType();
RRetType = RRetType.getUnqualifiedType();
@@ -6998,11 +6915,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (lproto && rproto) { // two C99 style function prototypes
assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() &&
"C++ shouldn't be here");
- unsigned lproto_nargs = lproto->getNumArgs();
- unsigned rproto_nargs = rproto->getNumArgs();
-
- // Compatible functions must have the same number of arguments
- if (lproto_nargs != rproto_nargs)
+ // Compatible functions must have the same number of parameters
+ if (lproto->getNumParams() != rproto->getNumParams())
return QualType();
// Variadic and non-variadic functions aren't compatible
@@ -7015,29 +6929,29 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (LangOpts.ObjCAutoRefCount &&
!FunctionTypesMatchOnNSConsumedAttrs(rproto, lproto))
return QualType();
-
- // Check argument compatibility
+
+ // Check parameter type compatibility
SmallVector<QualType, 10> types;
- for (unsigned i = 0; i < lproto_nargs; i++) {
- QualType largtype = lproto->getArgType(i).getUnqualifiedType();
- QualType rargtype = rproto->getArgType(i).getUnqualifiedType();
- QualType argtype = mergeFunctionArgumentTypes(largtype, rargtype,
- OfBlockPointer,
- Unqualified);
- if (argtype.isNull()) return QualType();
-
+ for (unsigned i = 0, n = lproto->getNumParams(); i < n; i++) {
+ QualType lParamType = lproto->getParamType(i).getUnqualifiedType();
+ QualType rParamType = rproto->getParamType(i).getUnqualifiedType();
+ QualType paramType = mergeFunctionParameterTypes(
+ lParamType, rParamType, OfBlockPointer, Unqualified);
+ if (paramType.isNull())
+ return QualType();
+
if (Unqualified)
- argtype = argtype.getUnqualifiedType();
-
- types.push_back(argtype);
+ paramType = paramType.getUnqualifiedType();
+
+ types.push_back(paramType);
if (Unqualified) {
- largtype = largtype.getUnqualifiedType();
- rargtype = rargtype.getUnqualifiedType();
+ lParamType = lParamType.getUnqualifiedType();
+ rParamType = rParamType.getUnqualifiedType();
}
-
- if (getCanonicalType(argtype) != getCanonicalType(largtype))
+
+ if (getCanonicalType(paramType) != getCanonicalType(lParamType))
allLTypes = false;
- if (getCanonicalType(argtype) != getCanonicalType(rargtype))
+ if (getCanonicalType(paramType) != getCanonicalType(rParamType))
allRTypes = false;
}
@@ -7061,20 +6975,19 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
// The only types actually affected are promotable integer
// types and floats, which would be passed as a different
// type depending on whether the prototype is visible.
- unsigned proto_nargs = proto->getNumArgs();
- for (unsigned i = 0; i < proto_nargs; ++i) {
- QualType argTy = proto->getArgType(i);
-
+ for (unsigned i = 0, n = proto->getNumParams(); i < n; ++i) {
+ QualType paramTy = proto->getParamType(i);
+
// Look at the converted type of enum types, since that is the type used
// to pass enum values.
- if (const EnumType *Enum = argTy->getAs<EnumType>()) {
- argTy = Enum->getDecl()->getIntegerType();
- if (argTy.isNull())
+ if (const EnumType *Enum = paramTy->getAs<EnumType>()) {
+ paramTy = Enum->getDecl()->getIntegerType();
+ if (paramTy.isNull())
return QualType();
}
-
- if (argTy->isPromotableIntegerType() ||
- getCanonicalType(argTy).getUnqualifiedType() == FloatTy)
+
+ if (paramTy->isPromotableIntegerType() ||
+ getCanonicalType(paramTy).getUnqualifiedType() == FloatTy)
return QualType();
}
@@ -7083,7 +6996,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
FunctionProtoType::ExtProtoInfo EPI = proto->getExtProtoInfo();
EPI.ExtInfo = einfo;
- return getFunctionType(retType, proto->getArgTypes(), EPI);
+ return getFunctionType(retType, proto->getParamTypes(), EPI);
}
if (allLTypes) return lhs;
@@ -7387,18 +7300,16 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs(
const FunctionProtoType *FromFunctionType,
const FunctionProtoType *ToFunctionType) {
- if (FromFunctionType->hasAnyConsumedArgs() !=
- ToFunctionType->hasAnyConsumedArgs())
+ if (FromFunctionType->hasAnyConsumedParams() !=
+ ToFunctionType->hasAnyConsumedParams())
return false;
FunctionProtoType::ExtProtoInfo FromEPI =
FromFunctionType->getExtProtoInfo();
FunctionProtoType::ExtProtoInfo ToEPI =
ToFunctionType->getExtProtoInfo();
- if (FromEPI.ConsumedArguments && ToEPI.ConsumedArguments)
- for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
- ArgIdx != NumArgs; ++ArgIdx) {
- if (FromEPI.ConsumedArguments[ArgIdx] !=
- ToEPI.ConsumedArguments[ArgIdx])
+ if (FromEPI.ConsumedParameters && ToEPI.ConsumedParameters)
+ for (unsigned i = 0, n = FromFunctionType->getNumParams(); i != n; ++i) {
+ if (FromEPI.ConsumedParameters[i] != ToEPI.ConsumedParameters[i])
return false;
}
return true;
@@ -7416,10 +7327,10 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
if (RHSCan->isFunctionType()) {
if (!LHSCan->isFunctionType())
return QualType();
- QualType OldReturnType =
- cast<FunctionType>(RHSCan.getTypePtr())->getResultType();
+ QualType OldReturnType =
+ cast<FunctionType>(RHSCan.getTypePtr())->getReturnType();
QualType NewReturnType =
- cast<FunctionType>(LHSCan.getTypePtr())->getResultType();
+ cast<FunctionType>(LHSCan.getTypePtr())->getReturnType();
QualType ResReturnType =
mergeObjCGCQualifiers(NewReturnType, OldReturnType);
if (ResReturnType.isNull())
@@ -7432,7 +7343,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.ExtInfo = getFunctionExtInfo(LHS);
QualType ResultType =
- getFunctionType(OldReturnType, FPT->getArgTypes(), EPI);
+ getFunctionType(OldReturnType, FPT->getParamTypes(), EPI);
return ResultType;
}
}
@@ -7573,6 +7484,19 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
assert(HowLong <= 2 && "Can't have LLLL modifier");
++HowLong;
break;
+ case 'W':
+ // This modifier represents int64 type.
+ assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!");
+ switch (Context.getTargetInfo().getInt64Type()) {
+ default:
+ llvm_unreachable("Unexpected integer type");
+ case TargetInfo::SignedLong:
+ HowLong = 1;
+ break;
+ case TargetInfo::SignedLongLong:
+ HowLong = 2;
+ break;
+ }
}
}
@@ -7834,7 +7758,8 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
return getFunctionType(ResType, ArgTypes, EPI);
}
-GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {
+static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
+ const FunctionDecl *FD) {
if (!FD->isExternallyVisible())
return GVA_Internal;
@@ -7846,68 +7771,126 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {
break;
case TSK_ExplicitInstantiationDefinition:
- return GVA_ExplicitTemplateInstantiation;
+ return GVA_StrongODR;
+ // C++11 [temp.explicit]p10:
+ // [ Note: The intent is that an inline function that is the subject of
+ // an explicit instantiation declaration will still be implicitly
+ // instantiated when used so that the body can be considered for
+ // inlining, but that no out-of-line copy of the inline function would be
+ // generated in the translation unit. -- end note ]
case TSK_ExplicitInstantiationDeclaration:
+ return GVA_AvailableExternally;
+
case TSK_ImplicitInstantiation:
- External = GVA_TemplateInstantiation;
+ External = GVA_DiscardableODR;
break;
}
if (!FD->isInlined())
return External;
- if ((!getLangOpts().CPlusPlus && !getLangOpts().MicrosoftMode) ||
+ if ((!Context.getLangOpts().CPlusPlus && !Context.getLangOpts().MSVCCompat &&
+ !FD->hasAttr<DLLExportAttr>()) ||
FD->hasAttr<GNUInlineAttr>()) {
+ // FIXME: This doesn't match gcc's behavior for dllexport inline functions.
+
// GNU or C99 inline semantics. Determine whether this symbol should be
// externally visible.
if (FD->isInlineDefinitionExternallyVisible())
return External;
// C99 inline semantics, where the symbol is not externally visible.
- return GVA_C99Inline;
+ return GVA_AvailableExternally;
}
- // C++0x [temp.explicit]p9:
- // [ Note: The intent is that an inline function that is the subject of
- // an explicit instantiation declaration will still be implicitly
- // instantiated when used so that the body can be considered for
- // inlining, but that no out-of-line copy of the inline function would be
- // generated in the translation unit. -- end note ]
- if (FD->getTemplateSpecializationKind()
- == TSK_ExplicitInstantiationDeclaration)
- return GVA_C99Inline;
+ // Functions specified with extern and inline in -fms-compatibility mode
+ // forcibly get emitted. While the body of the function cannot be later
+ // replaced, the function definition cannot be discarded.
+ if (FD->getMostRecentDecl()->isMSExternInline())
+ return GVA_StrongODR;
- return GVA_CXXInline;
+ return GVA_DiscardableODR;
}
-GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
+static GVALinkage adjustGVALinkageForDLLAttribute(GVALinkage L, const Decl *D) {
+ // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx
+ // dllexport/dllimport on inline functions.
+ if (D->hasAttr<DLLImportAttr>()) {
+ if (L == GVA_DiscardableODR || L == GVA_StrongODR)
+ return GVA_AvailableExternally;
+ } else if (D->hasAttr<DLLExportAttr>()) {
+ if (L == GVA_DiscardableODR)
+ return GVA_StrongODR;
+ }
+ return L;
+}
+
+GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
+ return adjustGVALinkageForDLLAttribute(basicGVALinkageForFunction(*this, FD),
+ FD);
+}
+
+static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
+ const VarDecl *VD) {
if (!VD->isExternallyVisible())
return GVA_Internal;
+ if (VD->isStaticLocal()) {
+ GVALinkage StaticLocalLinkage = GVA_DiscardableODR;
+ const DeclContext *LexicalContext = VD->getParentFunctionOrMethod();
+ while (LexicalContext && !isa<FunctionDecl>(LexicalContext))
+ LexicalContext = LexicalContext->getLexicalParent();
+
+ // Let the static local variable inherit it's linkage from the nearest
+ // enclosing function.
+ if (LexicalContext)
+ StaticLocalLinkage =
+ Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
+
+ // GVA_StrongODR function linkage is stronger than what we need,
+ // downgrade to GVA_DiscardableODR.
+ // This allows us to discard the variable if we never end up needing it.
+ return StaticLocalLinkage == GVA_StrongODR ? GVA_DiscardableODR
+ : StaticLocalLinkage;
+ }
+
+ // MSVC treats in-class initialized static data members as definitions.
+ // By giving them non-strong linkage, out-of-line definitions won't
+ // cause link errors.
+ if (Context.isMSStaticDataMemberInlineDefinition(VD))
+ return GVA_DiscardableODR;
+
switch (VD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
return GVA_StrongExternal;
- case TSK_ExplicitInstantiationDeclaration:
- llvm_unreachable("Variable should not be instantiated");
- // Fall through to treat this like any other instantiation.
-
case TSK_ExplicitInstantiationDefinition:
- return GVA_ExplicitTemplateInstantiation;
+ return GVA_StrongODR;
+
+ case TSK_ExplicitInstantiationDeclaration:
+ return GVA_AvailableExternally;
case TSK_ImplicitInstantiation:
- return GVA_TemplateInstantiation;
+ return GVA_DiscardableODR;
}
llvm_unreachable("Invalid Linkage!");
}
+GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
+ return adjustGVALinkageForDLLAttribute(basicGVALinkageForVariable(*this, VD),
+ VD);
+}
+
bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (!VD->isFileVarDecl())
return false;
+ // Global named register variables (GNU extension) are never emitted.
+ if (VD->getStorageClass() == SC_Register)
+ return false;
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// We never need to emit an uninstantiated function template.
if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
@@ -7954,8 +7937,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// static, static inline, always_inline, and extern inline functions can
// always be deferred. Normal inline functions can be deferred in C99/C++.
// Implicit template instantiations can also be deferred in C++.
- if (Linkage == GVA_Internal || Linkage == GVA_C99Inline ||
- Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation)
+ if (Linkage == GVA_Internal || Linkage == GVA_AvailableExternally ||
+ Linkage == GVA_DiscardableODR)
return false;
return true;
}
@@ -7963,12 +7946,14 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
const VarDecl *VD = cast<VarDecl>(D);
assert(VD->isFileVarDecl() && "Expected file scoped var");
- if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly)
+ if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly &&
+ !isMSStaticDataMemberInlineDefinition(VD))
return false;
// Variables that can be needed in other TUs are required.
GVALinkage L = GetGVALinkageForVariable(VD);
- if (L != GVA_Internal && L != GVA_TemplateInstantiation)
+ if (L != GVA_Internal && L != GVA_AvailableExternally &&
+ L != GVA_DiscardableODR)
return true;
// Variables that have destruction with side-effects are required.
@@ -7996,12 +7981,23 @@ bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const {
return ABI->isNearlyEmpty(RD);
}
+VTableContextBase *ASTContext::getVTableContext() {
+ if (!VTContext.get()) {
+ if (Target->getCXXABI().isMicrosoft())
+ VTContext.reset(new MicrosoftVTableContext(*this));
+ else
+ VTContext.reset(new ItaniumVTableContext(*this));
+ }
+ return VTContext.get();
+}
+
MangleContext *ASTContext::createMangleContext() {
switch (Target->getCXXABI().getKind()) {
case TargetCXXABI::GenericAArch64:
case TargetCXXABI::GenericItanium:
case TargetCXXABI::GenericARM:
case TargetCXXABI::iOS:
+ case TargetCXXABI::iOS64:
return ItaniumMangleContext::create(*this, getDiagnostics());
case TargetCXXABI::Microsoft:
return MicrosoftMangleContext::create(*this, getDiagnostics());
@@ -8071,6 +8067,17 @@ unsigned ASTContext::getManglingNumber(const NamedDecl *ND) const {
return I != MangleNumbers.end() ? I->second : 1;
}
+void ASTContext::setStaticLocalNumber(const VarDecl *VD, unsigned Number) {
+ if (Number > 1)
+ StaticLocalNumbers[VD] = Number;
+}
+
+unsigned ASTContext::getStaticLocalNumber(const VarDecl *VD) const {
+ llvm::DenseMap<const VarDecl *, unsigned>::const_iterator I =
+ StaticLocalNumbers.find(VD);
+ return I != StaticLocalNumbers.end() ? I->second : 1;
+}
+
MangleNumberingContext &
ASTContext::getManglingNumberContext(const DeclContext *DC) {
assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C.
@@ -8105,7 +8112,7 @@ ASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
llvm::DenseMap<const MaterializeTemporaryExpr *, APValue>::iterator I =
MaterializedTemporaryValues.find(E);
- return I == MaterializedTemporaryValues.end() ? 0 : &I->second;
+ return I == MaterializedTemporaryValues.end() ? nullptr : &I->second;
}
bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
@@ -8168,18 +8175,45 @@ namespace {
template <typename T>
bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) {
- if (Node == NULL)
+ if (!Node)
return true;
- if (ParentStack.size() > 0)
- // FIXME: Currently we add the same parent multiple times, for example
- // when we visit all subexpressions of template instantiations; this is
- // suboptimal, bug benign: the only way to visit those is with
- // hasAncestor / hasParent, and those do not create new matches.
+ if (ParentStack.size() > 0) {
+ // FIXME: Currently we add the same parent multiple times, but only
+ // when no memoization data is available for the type.
+ // For example when we visit all subexpressions of template
+ // instantiations; this is suboptimal, but benign: the only way to
+ // visit those is with hasAncestor / hasParent, and those do not create
+ // new matches.
// The plan is to enable DynTypedNode to be storable in a map or hash
// map. The main problem there is to implement hash functions /
// comparison operators for all types that DynTypedNode supports that
// do not have pointer identity.
- (*Parents)[Node].push_back(ParentStack.back());
+ auto &NodeOrVector = (*Parents)[Node];
+ if (NodeOrVector.isNull()) {
+ NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back());
+ } else {
+ if (NodeOrVector.template is<ast_type_traits::DynTypedNode *>()) {
+ auto *Node =
+ NodeOrVector.template get<ast_type_traits::DynTypedNode *>();
+ auto *Vector = new ASTContext::ParentVector(1, *Node);
+ NodeOrVector = Vector;
+ delete Node;
+ }
+ assert(NodeOrVector.template is<ASTContext::ParentVector *>());
+
+ auto *Vector =
+ NodeOrVector.template get<ASTContext::ParentVector *>();
+ // Skip duplicates for types that have memoization data.
+ // We must check that the type has memoization data before calling
+ // std::find() because DynTypedNode::operator== can't compare all
+ // types.
+ bool Found = ParentStack.back().getMemoizationData() &&
+ std::find(Vector->begin(), Vector->end(),
+ ParentStack.back()) != Vector->end();
+ if (!Found)
+ Vector->push_back(ParentStack.back());
+ }
+ }
ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
bool Result = (this ->* traverse) (Node);
ParentStack.pop_back();
@@ -8217,7 +8251,11 @@ ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) {
if (I == AllParents->end()) {
return ParentVector();
}
- return I->second;
+ if (I->second.is<ast_type_traits::DynTypedNode *>()) {
+ return ParentVector(1, *I->second.get<ast_type_traits::DynTypedNode *>());
+ }
+ const auto &Parents = *I->second.get<ParentVector *>();
+ return ParentVector(Parents.begin(), Parents.end());
}
bool
@@ -8230,8 +8268,7 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
if (MethodDecl->getObjCDeclQualifier() !=
MethodImpl->getObjCDeclQualifier())
return false;
- if (!hasSameType(MethodDecl->getResultType(),
- MethodImpl->getResultType()))
+ if (!hasSameType(MethodDecl->getReturnType(), MethodImpl->getReturnType()))
return false;
if (MethodDecl->param_size() != MethodImpl->param_size())
@@ -8251,3 +8288,12 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
return (MethodDecl->isVariadic() == MethodImpl->isVariadic());
}
+
+// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
+// doesn't include ASTContext.h
+template
+clang::LazyGenerationalUpdatePtr<
+ const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::ValueType
+clang::LazyGenerationalUpdatePtr<
+ const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue(
+ const clang::ASTContext &Ctx, Decl *Value);
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp
index fce8f64..8c8b1df 100644
--- a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp
@@ -12,6 +12,8 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
@@ -51,6 +53,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
QT = AT->desugar();
continue;
}
+ // ...or an adjusted type...
+ if (const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) {
+ QT = AT->desugar();
+ continue;
+ }
// ... or an auto type.
if (const AutoType *AT = dyn_cast<AutoType>(Ty)) {
if (!AT->isSugared())
@@ -155,9 +162,8 @@ break; \
/// diagnostic message
static std::string
ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
- const DiagnosticsEngine::ArgumentValue *PrevArgs,
- unsigned NumPrevArgs,
- ArrayRef<intptr_t> QualTypeVals) {
+ ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
+ ArrayRef<intptr_t> QualTypeVals) {
// FIXME: Playing with std::string is really slow.
bool ForceAKA = false;
QualType CanTy = Ty.getCanonicalType();
@@ -195,7 +201,7 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
// Check to see if we already desugared this type in this
// diagnostic. If so, don't do it again.
bool Repeated = false;
- for (unsigned i = 0; i != NumPrevArgs; ++i) {
+ for (unsigned i = 0, e = PrevArgs.size(); i != e; ++i) {
// TODO: Handle ak_declcontext case.
if (PrevArgs[i].first == DiagnosticsEngine::ak_qualtype) {
void *Ptr = (void*)PrevArgs[i].second;
@@ -222,6 +228,20 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
return S;
}
}
+
+ // Give some additional info on vector types. These are either not desugared
+ // or displaying complex __attribute__ expressions so add details of the
+ // type and element count.
+ if (Ty->isVectorType()) {
+ const VectorType *VTy = Ty->getAs<VectorType>();
+ std::string DecoratedString;
+ llvm::raw_string_ostream OS(DecoratedString);
+ const char *Values = VTy->getNumElements() > 1 ? "values" : "value";
+ OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '"
+ << VTy->getElementType().getAsString(Context.getPrintingPolicy())
+ << "' " << Values << ")";
+ return OS.str();
+ }
}
S = "'" + S + "'";
@@ -236,12 +256,9 @@ static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType,
void clang::FormatASTNodeDiagnosticArgument(
DiagnosticsEngine::ArgumentKind Kind,
intptr_t Val,
- const char *Modifier,
- unsigned ModLen,
- const char *Argument,
- unsigned ArgLen,
- const DiagnosticsEngine::ArgumentValue *PrevArgs,
- unsigned NumPrevArgs,
+ StringRef Modifier,
+ StringRef Argument,
+ ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
SmallVectorImpl<char> &Output,
void *Cookie,
ArrayRef<intptr_t> QualTypeVals) {
@@ -276,28 +293,26 @@ void clang::FormatASTNodeDiagnosticArgument(
// Attempting to do a template diff on non-templates. Set the variables
// and continue with regular type printing of the appropriate type.
Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType;
- ModLen = 0;
- ArgLen = 0;
+ Modifier = StringRef();
+ Argument = StringRef();
// Fall through
}
case DiagnosticsEngine::ak_qualtype: {
- assert(ModLen == 0 && ArgLen == 0 &&
+ assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for QualType argument");
QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
- OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, NumPrevArgs,
- QualTypeVals);
+ OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals);
NeedQuotes = false;
break;
}
case DiagnosticsEngine::ak_declarationname: {
- if (ModLen == 9 && !memcmp(Modifier, "objcclass", 9) && ArgLen == 0)
+ if (Modifier == "objcclass" && Argument.empty())
OS << '+';
- else if (ModLen == 12 && !memcmp(Modifier, "objcinstance", 12)
- && ArgLen==0)
+ else if (Modifier == "objcinstance" && Argument.empty())
OS << '-';
else
- assert(ModLen == 0 && ArgLen == 0 &&
+ assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for DeclarationName argument");
OS << DeclarationName::getFromOpaqueInteger(Val);
@@ -305,10 +320,10 @@ void clang::FormatASTNodeDiagnosticArgument(
}
case DiagnosticsEngine::ak_nameddecl: {
bool Qualified;
- if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0)
+ if (Modifier == "q" && Argument.empty())
Qualified = true;
else {
- assert(ModLen == 0 && ArgLen == 0 &&
+ assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for NamedDecl* argument");
Qualified = false;
}
@@ -325,7 +340,8 @@ void clang::FormatASTNodeDiagnosticArgument(
case DiagnosticsEngine::ak_declcontext: {
DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
assert(DC && "Should never have a null declaration context");
-
+ NeedQuotes = false;
+
if (DC->isTranslationUnit()) {
// FIXME: Get these strings from some localized place
if (Context.getLangOpts().CPlusPlus)
@@ -335,10 +351,17 @@ void clang::FormatASTNodeDiagnosticArgument(
} else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
OS << ConvertTypeToDiagnosticString(Context,
Context.getTypeDeclType(Type),
- PrevArgs, NumPrevArgs,
- QualTypeVals);
+ PrevArgs, QualTypeVals);
} else {
// FIXME: Get these strings from some localized place
+ if (isa<BlockDecl>(DC)) {
+ OS << "block literal";
+ break;
+ }
+ if (isLambdaCallOperator(DC)) {
+ OS << "lambda expression";
+ break;
+ }
NamedDecl *ND = cast<NamedDecl>(DC);
if (isa<NamespaceDecl>(ND))
OS << "namespace ";
@@ -351,9 +374,16 @@ void clang::FormatASTNodeDiagnosticArgument(
ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true);
OS << '\'';
}
+ break;
+ }
+ case DiagnosticsEngine::ak_attr: {
+ const Attr *At = reinterpret_cast<Attr *>(Val);
+ assert(At && "Received null Attr object!");
+ OS << '\'' << At->getSpelling() << '\'';
NeedQuotes = false;
break;
}
+
}
OS.flush();
@@ -442,6 +472,9 @@ class TemplateDiff {
/// FromExpr, ToExpr - The expression arguments.
Expr *FromExpr, *ToExpr;
+ /// FromNullPtr, ToNullPtr - If the template argument is a nullptr
+ bool FromNullPtr, ToNullPtr;
+
/// FromTD, ToTD - The template decl for template template
/// arguments or the type arguments that are templates.
TemplateDecl *FromTD, *ToTD;
@@ -470,10 +503,12 @@ class TemplateDiff {
DiffNode(unsigned ParentNode = 0)
: Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode),
- FromType(), ToType(), FromExpr(0), ToExpr(0), FromTD(0), ToTD(0),
- IsValidFromInt(false), IsValidToInt(false), FromValueDecl(0),
- ToValueDecl(0), FromAddressOf(false), ToAddressOf(false),
- FromDefault(false), ToDefault(false), Same(false) { }
+ FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr),
+ FromNullPtr(false), ToNullPtr(false),
+ FromTD(nullptr), ToTD(nullptr), IsValidFromInt(false),
+ IsValidToInt(false), FromValueDecl(nullptr), ToValueDecl(nullptr),
+ FromAddressOf(false), ToAddressOf(false), FromDefault(false),
+ ToDefault(false), Same(false) {}
};
/// FlatTree - A flattened tree used to store the DiffNodes.
@@ -543,6 +578,12 @@ class TemplateDiff {
FlatTree[CurrentNode].Same = Same;
}
+ /// SetNullPtr - Sets the NullPtr flags of the current node.
+ void SetNullPtr(bool FromNullPtr, bool ToNullPtr) {
+ FlatTree[CurrentNode].FromNullPtr = FromNullPtr;
+ FlatTree[CurrentNode].ToNullPtr = ToNullPtr;
+ }
+
/// SetDefault - Sets FromDefault and ToDefault flags of the current node.
void SetDefault(bool FromDefault, bool ToDefault) {
FlatTree[CurrentNode].FromDefault = FromDefault;
@@ -665,6 +706,16 @@ class TemplateDiff {
return FlatTree[ReadNode].NextNode != 0;
}
+ /// FromNullPtr - Returns true if the from argument is null.
+ bool FromNullPtr() {
+ return FlatTree[ReadNode].FromNullPtr;
+ }
+
+ /// ToNullPtr - Returns true if the to argument is null.
+ bool ToNullPtr() {
+ return FlatTree[ReadNode].ToNullPtr;
+ }
+
/// FromDefault - Return true if the from argument is the default.
bool FromDefault() {
return FlatTree[ReadNode].FromDefault;
@@ -718,7 +769,7 @@ class TemplateDiff {
TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
: TST(TST),
DesugarTST(GetTemplateSpecializationType(Context, TST->desugar())),
- Index(0), CurrentTA(0), EndTA(0) {
+ Index(0), CurrentTA(nullptr), EndTA(nullptr) {
if (isEnd()) return;
// Set to first template argument. If not a parameter pack, done.
@@ -809,13 +860,13 @@ class TemplateDiff {
const RecordType *RT = Ty->getAs<RecordType>();
if (!RT)
- return 0;
+ return nullptr;
const ClassTemplateSpecializationDecl *CTSD =
dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
if (!CTSD)
- return 0;
+ return nullptr;
Ty = Context.getTemplateSpecializationType(
TemplateName(CTSD->getSpecializedTemplate()),
@@ -887,9 +938,9 @@ class TemplateDiff {
// Handle Expressions
if (NonTypeTemplateParmDecl *DefaultNTTPD =
dyn_cast<NonTypeTemplateParmDecl>(ParamND)) {
- Expr *FromExpr = 0, *ToExpr = 0;
+ Expr *FromExpr = nullptr, *ToExpr = nullptr;
llvm::APSInt FromInt, ToInt;
- ValueDecl *FromValueDecl = 0, *ToValueDecl = 0;
+ ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr;
unsigned ParamWidth = 128; // Safe default
if (DefaultNTTPD->getType()->isIntegralOrEnumerationType())
ParamWidth = Context.getIntWidth(DefaultNTTPD->getType());
@@ -903,6 +954,10 @@ class TemplateDiff {
bool HasToValueDecl =
!ToIter.isEnd() &&
ToIter->getKind() == TemplateArgument::Declaration;
+ bool FromNullPtr = !FromIter.isEnd() &&
+ FromIter->getKind() == TemplateArgument::NullPtr;
+ bool ToNullPtr =
+ !ToIter.isEnd() && ToIter->getKind() == TemplateArgument::NullPtr;
assert(((!HasFromInt && !HasToInt) ||
(!HasFromValueDecl && !HasToValueDecl)) &&
@@ -912,41 +967,54 @@ class TemplateDiff {
FromInt = FromIter->getAsIntegral();
else if (HasFromValueDecl)
FromValueDecl = FromIter->getAsDecl();
- else
+ else if (!FromNullPtr)
FromExpr = GetExpr(FromIter, DefaultNTTPD);
if (HasToInt)
ToInt = ToIter->getAsIntegral();
else if (HasToValueDecl)
ToValueDecl = ToIter->getAsDecl();
- else
+ else if (!ToNullPtr)
ToExpr = GetExpr(ToIter, DefaultNTTPD);
+ bool TemplateArgumentIsPointerType =
+ DefaultNTTPD->getType()->isPointerType();
+ if (FromExpr && TemplateArgumentIsPointerType) {
+ FromNullPtr = CheckForNullPtr(FromExpr);
+ }
+ if (ToExpr && TemplateArgumentIsPointerType) {
+ ToNullPtr = CheckForNullPtr(ToExpr);
+ }
+
if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {
Tree.SetNode(FromExpr, ToExpr);
Tree.SetDefault(FromIter.isEnd() && FromExpr,
ToIter.isEnd() && ToExpr);
if (DefaultNTTPD->getType()->isIntegralOrEnumerationType()) {
if (FromExpr)
- FromInt = GetInt(FromIter, FromExpr);
+ HasFromInt = GetInt(FromIter, FromExpr, FromInt);
if (ToExpr)
- ToInt = GetInt(ToIter, ToExpr);
- Tree.SetNode(FromInt, ToInt, FromExpr, ToExpr);
+ HasToInt = GetInt(ToIter, ToExpr, ToInt);
+ }
+ if (HasFromInt && HasToInt) {
+ Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetKind(DiffTree::Integer);
+ } else if (HasFromInt || HasToInt) {
+ Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
+ Tree.SetSame(false);
+ Tree.SetKind(DiffTree::Integer);
} else {
- Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr));
+ Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr) ||
+ (FromNullPtr && ToNullPtr));
+ Tree.SetNullPtr(FromNullPtr, ToNullPtr);
Tree.SetKind(DiffTree::Expression);
}
} else if (HasFromInt || HasToInt) {
- if (!HasFromInt && FromExpr) {
- FromInt = GetInt(FromIter, FromExpr);
- HasFromInt = true;
- }
- if (!HasToInt && ToExpr) {
- ToInt = GetInt(ToIter, ToExpr);
- HasToInt = true;
- }
+ if (!HasFromInt && FromExpr)
+ HasFromInt = GetInt(FromIter, FromExpr, FromInt);
+ if (!HasToInt && ToExpr)
+ HasToInt = GetInt(ToIter, ToExpr, ToInt);
Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetDefault(FromIter.isEnd() && HasFromInt,
@@ -958,12 +1026,36 @@ class TemplateDiff {
if (!HasToValueDecl && ToExpr)
ToValueDecl = GetValueDecl(ToIter, ToExpr);
QualType ArgumentType = DefaultNTTPD->getType();
- bool FromAddressOf = FromValueDecl &&
- !ArgumentType->isReferenceType() &&
- !FromValueDecl->getType()->isArrayType();
- bool ToAddressOf = ToValueDecl &&
- !ArgumentType->isReferenceType() &&
- !ToValueDecl->getType()->isArrayType();
+ bool FromAddressOf = false;
+ if (FromValueDecl) {
+ if (FromExpr) {
+ if (UnaryOperator *UO =
+ dyn_cast<UnaryOperator>(FromExpr->IgnoreParens())) {
+ if (UO->getOpcode() == UO_AddrOf)
+ FromAddressOf = true;
+ }
+ } else {
+ if (!ArgumentType->isReferenceType()) {
+ FromAddressOf = true;
+ }
+ }
+ }
+ bool ToAddressOf = false;
+ if (ToValueDecl) {
+ if (ToExpr) {
+ if (UnaryOperator *UO =
+ dyn_cast<UnaryOperator>(ToExpr->IgnoreParens())) {
+ if (UO->getOpcode() == UO_AddrOf) {
+ ToAddressOf = true;
+ }
+ }
+ } else {
+ if (!ArgumentType->isReferenceType()) {
+ ToAddressOf = true;
+ }
+ }
+ }
+ Tree.SetNullPtr(FromNullPtr, ToNullPtr);
Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
Tree.SetSame(FromValueDecl && ToValueDecl &&
FromValueDecl->getCanonicalDecl() ==
@@ -984,6 +1076,7 @@ class TemplateDiff {
Tree.SetSame(
FromDecl && ToDecl &&
FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl());
+ Tree.SetDefault(FromIter.isEnd() && FromDecl, ToIter.isEnd() && ToDecl);
Tree.SetKind(DiffTree::TemplateTemplate);
}
@@ -1072,7 +1165,7 @@ class TemplateDiff {
/// GetExpr - Retrieves the template expression argument, including default
/// arguments.
Expr *GetExpr(const TSTiterator &Iter, NonTypeTemplateParmDecl *DefaultNTTPD) {
- Expr *ArgExpr = 0;
+ Expr *ArgExpr = nullptr;
bool isVariadic = DefaultNTTPD->isParameterPack();
if (!Iter.isEnd())
@@ -1090,20 +1183,28 @@ class TemplateDiff {
/// GetInt - Retrieves the template integer argument, including evaluating
/// default arguments.
- llvm::APInt GetInt(const TSTiterator &Iter, Expr *ArgExpr) {
+ bool GetInt(const TSTiterator &Iter, Expr *ArgExpr, llvm::APInt &Int) {
// Default, value-depenedent expressions require fetching
- // from the desugared TemplateArgument
- if (Iter.isEnd() && ArgExpr->isValueDependent())
+ // from the desugared TemplateArgument, otherwise expression needs to
+ // be evaluatable.
+ if (Iter.isEnd() && ArgExpr->isValueDependent()) {
switch (Iter.getDesugar().getKind()) {
case TemplateArgument::Integral:
- return Iter.getDesugar().getAsIntegral();
+ Int = Iter.getDesugar().getAsIntegral();
+ return true;
case TemplateArgument::Expression:
ArgExpr = Iter.getDesugar().getAsExpr();
- return ArgExpr->EvaluateKnownConstInt(Context);
+ Int = ArgExpr->EvaluateKnownConstInt(Context);
+ return true;
default:
- assert(0 && "Unexpected template argument kind");
+ llvm_unreachable("Unexpected template argument kind");
}
- return ArgExpr->EvaluateKnownConstInt(Context);
+ } else if (ArgExpr->isEvaluatable(Context)) {
+ Int = ArgExpr->EvaluateKnownConstInt(Context);
+ return true;
+ }
+
+ return false;
}
/// GetValueDecl - Retrieves the template Decl argument, including
@@ -1119,16 +1220,40 @@ class TemplateDiff {
ArgExpr = Iter.getDesugar().getAsExpr();
return cast<DeclRefExpr>(ArgExpr)->getDecl();
default:
- assert(0 && "Unexpected template argument kind");
+ llvm_unreachable("Unexpected template argument kind");
}
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);
if (!DRE) {
- DRE = cast<DeclRefExpr>(cast<UnaryOperator>(ArgExpr)->getSubExpr());
+ UnaryOperator *UO = dyn_cast<UnaryOperator>(ArgExpr->IgnoreParens());
+ if (!UO)
+ return nullptr;
+ DRE = cast<DeclRefExpr>(UO->getSubExpr());
}
return DRE->getDecl();
}
+ /// CheckForNullPtr - returns true if the expression can be evaluated as
+ /// a null pointer
+ bool CheckForNullPtr(Expr *E) {
+ assert(E && "Expected expression");
+
+ E = E->IgnoreParenCasts();
+ if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
+ return true;
+
+ DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
+ if (!DRE)
+ return false;
+
+ VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
+ if (!VD || !VD->hasInit())
+ return false;
+
+ return VD->getInit()->IgnoreParenCasts()->isNullPointerConstant(
+ Context, Expr::NPC_ValueDependentIsNull);
+ }
+
/// GetTemplateDecl - Retrieves the template template arguments, including
/// default arguments.
TemplateDecl *GetTemplateDecl(const TSTiterator &Iter,
@@ -1136,7 +1261,7 @@ class TemplateDiff {
bool isVariadic = DefaultTTPD->isParameterPack();
TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument();
- TemplateDecl *DefaultTD = 0;
+ TemplateDecl *DefaultTD = nullptr;
if (TA.getKind() != TemplateArgument::Null)
DefaultTD = TA.getAsTemplate().getAsTemplateDecl();
@@ -1145,7 +1270,7 @@ class TemplateDiff {
if (!isVariadic)
return DefaultTD;
- return 0;
+ return nullptr;
}
/// IsSameConvertedInt - Returns true if both integers are equal when
@@ -1166,11 +1291,8 @@ class TemplateDiff {
if (!FromExpr || !ToExpr)
return false;
- FromExpr = FromExpr->IgnoreParens();
- ToExpr = ToExpr->IgnoreParens();
-
- DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr),
- *ToDRE = dyn_cast<DeclRefExpr>(ToExpr);
+ DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr->IgnoreParens()),
+ *ToDRE = dyn_cast<DeclRefExpr>(ToExpr->IgnoreParens());
if (FromDRE || ToDRE) {
if (!FromDRE || !ToDRE)
@@ -1180,8 +1302,12 @@ class TemplateDiff {
Expr::EvalResult FromResult, ToResult;
if (!FromExpr->EvaluateAsRValue(FromResult, Context) ||
- !ToExpr->EvaluateAsRValue(ToResult, Context))
- return false;
+ !ToExpr->EvaluateAsRValue(ToResult, Context)) {
+ llvm::FoldingSetNodeID FromID, ToID;
+ FromExpr->Profile(FromID, Context, true);
+ ToExpr->Profile(ToID, Context, true);
+ return FromID == ToID;
+ }
APValue &FromVal = FromResult.Val;
APValue &ToVal = ToResult.Val;
@@ -1235,8 +1361,8 @@ class TemplateDiff {
case DiffTree::Expression: {
Expr *FromExpr, *ToExpr;
Tree.GetNode(FromExpr, ToExpr);
- PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
- Tree.NodeIsSame());
+ PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(),
+ Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
return;
}
case DiffTree::TemplateTemplate: {
@@ -1262,7 +1388,8 @@ class TemplateDiff {
bool FromAddressOf, ToAddressOf;
Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
- Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
+ Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(),
+ Tree.ToDefault(), Tree.NodeIsSame());
return;
}
case DiffTree::Template: {
@@ -1341,7 +1468,7 @@ class TemplateDiff {
"Only one template argument may be missing.");
if (Same) {
- OS << FromType.getAsString();
+ OS << FromType.getAsString(Policy);
return;
}
@@ -1349,22 +1476,22 @@ class TemplateDiff {
FromType.getLocalUnqualifiedType() ==
ToType.getLocalUnqualifiedType()) {
Qualifiers FromQual = FromType.getLocalQualifiers(),
- ToQual = ToType.getLocalQualifiers(),
- CommonQual;
+ ToQual = ToType.getLocalQualifiers();
PrintQualifiers(FromQual, ToQual);
FromType.getLocalUnqualifiedType().print(OS, Policy);
return;
}
std::string FromTypeStr = FromType.isNull() ? "(no argument)"
- : FromType.getAsString();
+ : FromType.getAsString(Policy);
std::string ToTypeStr = ToType.isNull() ? "(no argument)"
- : ToType.getAsString();
+ : ToType.getAsString(Policy);
// Switch to canonical typename if it is better.
// TODO: merge this with other aka printing above.
if (FromTypeStr == ToTypeStr) {
- std::string FromCanTypeStr = FromType.getCanonicalType().getAsString();
- std::string ToCanTypeStr = ToType.getCanonicalType().getAsString();
+ std::string FromCanTypeStr =
+ FromType.getCanonicalType().getAsString(Policy);
+ std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(Policy);
if (FromCanTypeStr != ToCanTypeStr) {
FromTypeStr = FromCanTypeStr;
ToTypeStr = ToCanTypeStr;
@@ -1388,36 +1515,41 @@ class TemplateDiff {
/// PrintExpr - Prints out the expr template arguments, highlighting argument
/// differences.
- void PrintExpr(const Expr *FromExpr, const Expr *ToExpr,
- bool FromDefault, bool ToDefault, bool Same) {
+ void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromNullPtr,
+ bool ToNullPtr, bool FromDefault, bool ToDefault, bool Same) {
assert((FromExpr || ToExpr) &&
"Only one template argument may be missing.");
if (Same) {
- PrintExpr(FromExpr);
+ PrintExpr(FromExpr, FromNullPtr);
} else if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
Bold();
- PrintExpr(FromExpr);
+ PrintExpr(FromExpr, FromNullPtr);
Unbold();
} else {
OS << (FromDefault ? "[(default) " : "[");
Bold();
- PrintExpr(FromExpr);
+ PrintExpr(FromExpr, FromNullPtr);
Unbold();
OS << " != " << (ToDefault ? "(default) " : "");
Bold();
- PrintExpr(ToExpr);
+ PrintExpr(ToExpr, ToNullPtr);
Unbold();
OS << ']';
}
}
/// PrintExpr - Actual formatting and printing of expressions.
- void PrintExpr(const Expr *E) {
- if (!E)
- OS << "(no argument)";
- else
- E->printPretty(OS, 0, Policy); return;
+ void PrintExpr(const Expr *E, bool NullPtr = false) {
+ if (E) {
+ E->printPretty(OS, nullptr, Policy);
+ return;
+ }
+ if (NullPtr) {
+ OS << "nullptr";
+ return;
+ }
+ OS << "(no argument)";
}
/// PrintTemplateTemplate - Handles printing of template template arguments,
@@ -1487,6 +1619,8 @@ class TemplateDiff {
Bold();
}
OS << Val.toString(10);
+ } else if (E) {
+ PrintExpr(E);
} else {
OS << "(no argument)";
}
@@ -1507,35 +1641,46 @@ class TemplateDiff {
return true;
}
+ void PrintValueDecl(ValueDecl *VD, bool AddressOf, bool NullPtr) {
+ if (VD) {
+ if (AddressOf)
+ OS << "&";
+ OS << VD->getName();
+ return;
+ }
+
+ if (NullPtr) {
+ OS << "nullptr";
+ return;
+ }
+
+ OS << "(no argument)";
+ }
+
/// PrintDecl - Handles printing of Decl arguments, highlighting
/// argument differences.
void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
- bool FromAddressOf, bool ToAddressOf, bool FromDefault,
- bool ToDefault, bool Same) {
- assert((FromValueDecl || ToValueDecl) &&
+ bool FromAddressOf, bool ToAddressOf, bool FromNullPtr,
+ bool ToNullPtr, bool FromDefault, bool ToDefault,
+ bool Same) {
+ assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
"Only one Decl argument may be NULL");
if (Same) {
- OS << FromValueDecl->getName();
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
} else if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
Bold();
- if (FromAddressOf)
- OS << "&";
- OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
Unbold();
} else {
OS << (FromDefault ? "[(default) " : "[");
Bold();
- if (FromAddressOf)
- OS << "&";
- OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
Unbold();
OS << " != " << (ToDefault ? "(default) " : "");
Bold();
- if (ToAddressOf)
- OS << "&";
- OS << (ToValueDecl ? ToValueDecl->getName() : "(no argument)");
+ PrintValueDecl(ToValueDecl, ToAddressOf, ToNullPtr);
Unbold();
OS << ']';
}
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp b/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp
index 670fd0e..df7a2cb 100644
--- a/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp
@@ -149,11 +149,43 @@ namespace {
}
};
+ class ChildDumper {
+ ASTDumper &Dumper;
+
+ const Decl *Prev;
+ bool PrevRef;
+ public:
+ ChildDumper(ASTDumper &Dumper) : Dumper(Dumper), Prev(nullptr) {}
+ ~ChildDumper() {
+ if (Prev) {
+ Dumper.lastChild();
+ dump(nullptr);
+ }
+ }
+
+ // FIXME: This should take an arbitrary callable as the dumping action.
+ void dump(const Decl *D, bool Ref = false) {
+ if (Prev) {
+ if (PrevRef)
+ Dumper.dumpDeclRef(Prev);
+ else
+ Dumper.dumpDecl(Prev);
+ }
+ Prev = D;
+ PrevRef = Ref;
+ }
+ void dumpRef(const Decl *D) { dump(D, true); }
+
+ // Give up ownership of the children of the node. By calling this,
+ // the caller takes back responsibility for calling lastChild().
+ void release() { dump(nullptr); }
+ };
+
public:
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
const SourceManager *SM)
: OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false),
- LastLocFilename(""), LastLocLine(~0U), FC(0),
+ LastLocFilename(""), LastLocLine(~0U), FC(nullptr),
ShowColors(SM && SM->getDiagnostics().getShowColors()) { }
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
@@ -184,7 +216,7 @@ namespace {
void dumpBareType(QualType T);
void dumpType(QualType T);
void dumpBareDeclRef(const Decl *Node);
- void dumpDeclRef(const Decl *Node, const char *Label = 0);
+ void dumpDeclRef(const Decl *Node, const char *Label = nullptr);
void dumpName(const NamedDecl *D);
bool hasNodes(const DeclContext *DC);
void dumpDeclContext(const DeclContext *DC);
@@ -222,6 +254,13 @@ namespace {
void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
void VisitCXXRecordDecl(const CXXRecordDecl *D);
void VisitStaticAssertDecl(const StaticAssertDecl *D);
+ template<typename SpecializationDecl>
+ void VisitTemplateDeclSpecialization(ChildDumper &Children,
+ const SpecializationDecl *D,
+ bool DumpExplicitInst,
+ bool DumpRefOnly);
+ template<typename TemplateDecl>
+ void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
void VisitClassTemplateDecl(const ClassTemplateDecl *D);
void VisitClassTemplateSpecializationDecl(
@@ -276,6 +315,7 @@ namespace {
void VisitIntegerLiteral(const IntegerLiteral *Node);
void VisitFloatingLiteral(const FloatingLiteral *Node);
void VisitStringLiteral(const StringLiteral *Str);
+ void VisitInitListExpr(const InitListExpr *ILE);
void VisitUnaryOperator(const UnaryOperator *Node);
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
void VisitMemberExpr(const MemberExpr *Node);
@@ -405,6 +445,9 @@ void ASTDumper::dumpPointer(const void *Ptr) {
}
void ASTDumper::dumpLocation(SourceLocation Loc) {
+ if (!SM)
+ return;
+
ColorScope Color(*this, LocationColor);
SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
@@ -511,17 +554,14 @@ bool ASTDumper::hasNodes(const DeclContext *DC) {
void ASTDumper::dumpDeclContext(const DeclContext *DC) {
if (!DC)
return;
- bool HasUndeserializedDecls = DC->hasExternalLexicalStorage();
- for (DeclContext::decl_iterator I = DC->noload_decls_begin(),
- E = DC->noload_decls_end();
- I != E; ++I) {
- DeclContext::decl_iterator Next = I;
- ++Next;
- if (Next == E && !HasUndeserializedDecls)
- lastChild();
- dumpDecl(*I);
- }
- if (HasUndeserializedDecls) {
+
+ ChildDumper Children(*this);
+ for (auto *D : DC->noload_decls())
+ Children.dump(D);
+
+ if (DC->hasExternalLexicalStorage()) {
+ Children.release();
+
lastChild();
IndentScope Indent(*this);
ColorScope Color(*this, UndeserializedColor);
@@ -580,6 +620,7 @@ void ASTDumper::dumpAttr(const Attr *A) {
IndentScope Indent(*this);
{
ColorScope Color(*this, AttrColor);
+
switch (A->getKind()) {
#define ATTR(X) case attr::X: OS << #X; break;
#include "clang/Basic/AttrList.inc"
@@ -589,6 +630,10 @@ void ASTDumper::dumpAttr(const Attr *A) {
}
dumpPointer(A);
dumpSourceRange(A->getRange());
+ if (A->isInherited())
+ OS << " Inherited";
+ if (A->isImplicit())
+ OS << " Implicit";
#include "clang/AST/AttrDump.inc"
}
@@ -753,13 +798,23 @@ void ASTDumper::dumpDecl(const Decl *D) {
OS << " parent " << cast<Decl>(D->getDeclContext());
dumpPreviousDecl(OS, D);
dumpSourceRange(D->getSourceRange());
+ OS << ' ';
+ dumpLocation(D->getLocation());
if (Module *M = D->getOwningModule())
OS << " in " << M->getFullModuleName();
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
if (ND->isHidden())
OS << " hidden";
+ if (D->isImplicit())
+ OS << " implicit";
+ if (D->isUsed())
+ OS << " used";
+ else if (D->isReferenced())
+ OS << " referenced";
+ if (D->isInvalidDecl())
+ OS << " invalid";
- bool HasAttrs = D->attr_begin() != D->attr_end();
+ bool HasAttrs = D->hasAttrs();
const FullComment *Comment =
D->getASTContext().getLocalCommentForDeclUncached(D);
// Decls within functions are visited by the body
@@ -781,9 +836,6 @@ void ASTDumper::dumpDecl(const Decl *D) {
lastChild();
dumpFullComment(Comment);
- if (D->isInvalidDecl())
- OS << " invalid";
-
setMoreChildren(false);
if (HasDeclContext)
dumpDeclContext(cast<DeclContext>(D));
@@ -835,13 +887,10 @@ void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
dumpName(D);
dumpType(D->getType());
- for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
- E = D->chain_end();
- I != E; ++I) {
- if (I + 1 == E)
- lastChild();
- dumpDeclRef(*I);
- }
+
+ ChildDumper Children(*this);
+ for (auto *Child : D->chain())
+ Children.dumpRef(Child);
}
void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
@@ -975,6 +1024,11 @@ void ASTDumper::VisitVarDecl(const VarDecl *D) {
if (D->isNRVOVariable())
OS << " nrvo";
if (D->hasInit()) {
+ switch (D->getInitStyle()) {
+ case VarDecl::CInit: OS << " cinit"; break;
+ case VarDecl::CallInit: OS << " callinit"; break;
+ case VarDecl::ListInit: OS << " listinit"; break;
+ }
lastChild();
dumpStmt(D->getInit());
}
@@ -1027,15 +1081,13 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
if (!D->isCompleteDefinition())
return;
- for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(),
- E = D->bases_end();
- I != E; ++I) {
+ for (const auto &I : D->bases()) {
IndentScope Indent(*this);
- if (I->isVirtual())
+ if (I.isVirtual())
OS << "virtual ";
- dumpAccessSpecifier(I->getAccessSpecifier());
- dumpType(I->getType());
- if (I->isPackExpansion())
+ dumpAccessSpecifier(I.getAccessSpecifier());
+ dumpType(I.getType());
+ if (I.isPackExpansion())
OS << "...";
}
}
@@ -1046,63 +1098,69 @@ void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
dumpStmt(D->getMessage());
}
-void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
- dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
- dumpDecl(D->getTemplatedDecl());
- for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(),
- E = D->spec_end();
- I != E; ++I) {
- FunctionTemplateDecl::spec_iterator Next = I;
- ++Next;
- if (Next == E)
- lastChild();
- switch (I->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
+template<typename SpecializationDecl>
+void ASTDumper::VisitTemplateDeclSpecialization(ChildDumper &Children,
+ const SpecializationDecl *D,
+ bool DumpExplicitInst,
+ bool DumpRefOnly) {
+ bool DumpedAny = false;
+ for (auto *RedeclWithBadType : D->redecls()) {
+ // FIXME: The redecls() range sometimes has elements of a less-specific
+ // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
+ // us TagDecls, and should give CXXRecordDecls).
+ auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
+ if (!Redecl) {
+ // Found the injected-class-name for a class template. This will be dumped
+ // as part of its surrounding class so we don't need to dump it here.
+ assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
+ "expected an injected-class-name");
+ continue;
+ }
+
+ switch (Redecl->getTemplateSpecializationKind()) {
case TSK_ExplicitInstantiationDeclaration:
case TSK_ExplicitInstantiationDefinition:
- if (D == D->getCanonicalDecl())
- dumpDecl(*I);
- else
- dumpDeclRef(*I);
+ if (!DumpExplicitInst)
+ break;
+ // Fall through.
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ Children.dump(Redecl, DumpRefOnly);
+ DumpedAny = true;
break;
case TSK_ExplicitSpecialization:
- dumpDeclRef(*I);
break;
}
}
+
+ // Ensure we dump at least one decl for each specialization.
+ if (!DumpedAny)
+ Children.dumpRef(D);
}
-void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
+template<typename TemplateDecl>
+void ASTDumper::VisitTemplateDecl(const TemplateDecl *D,
+ bool DumpExplicitInst) {
dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
- ClassTemplateDecl::spec_iterator I = D->spec_begin();
- ClassTemplateDecl::spec_iterator E = D->spec_end();
- if (I == E)
- lastChild();
- dumpDecl(D->getTemplatedDecl());
- for (; I != E; ++I) {
- ClassTemplateDecl::spec_iterator Next = I;
- ++Next;
- if (Next == E)
- lastChild();
- switch (I->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- if (D == D->getCanonicalDecl())
- dumpDecl(*I);
- else
- dumpDeclRef(*I);
- break;
- case TSK_ExplicitSpecialization:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- dumpDeclRef(*I);
- break;
- }
- }
+ ChildDumper Children(*this);
+ Children.dump(D->getTemplatedDecl());
+
+ for (auto *Child : D->specializations())
+ VisitTemplateDeclSpecialization(Children, Child, DumpExplicitInst,
+ !D->isCanonicalDecl());
+}
+
+void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
+ // FIXME: We don't add a declaration of a function template specialization
+ // to its context when it's explicitly instantiated, so dump explicit
+ // instantiations when we dump the template itself.
+ VisitTemplateDecl(D, true);
+}
+
+void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
+ VisitTemplateDecl(D, false);
}
void ASTDumper::VisitClassTemplateSpecializationDecl(
@@ -1125,34 +1183,7 @@ void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
}
void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
- dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
-
- VarTemplateDecl::spec_iterator I = D->spec_begin();
- VarTemplateDecl::spec_iterator E = D->spec_end();
- if (I == E)
- lastChild();
- dumpDecl(D->getTemplatedDecl());
- for (; I != E; ++I) {
- VarTemplateDecl::spec_iterator Next = I;
- ++Next;
- if (Next == E)
- lastChild();
- switch (I->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- if (D == D->getCanonicalDecl())
- dumpDecl(*I);
- else
- dumpDeclRef(*I);
- break;
- case TSK_ExplicitSpecialization:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- dumpDeclRef(*I);
- break;
- }
- }
+ VisitTemplateDecl(D, false);
}
void ASTDumper::VisitVarTemplateSpecializationDecl(
@@ -1175,8 +1206,10 @@ void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
if (D->isParameterPack())
OS << " ...";
dumpName(D);
- if (D->hasDefaultArgument())
- dumpType(D->getDefaultArgument());
+ if (D->hasDefaultArgument()) {
+ lastChild();
+ dumpTemplateArgument(D->getDefaultArgument());
+ }
}
void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
@@ -1184,8 +1217,10 @@ void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
if (D->isParameterPack())
OS << " ...";
dumpName(D);
- if (D->hasDefaultArgument())
- dumpStmt(D->getDefaultArgument());
+ if (D->hasDefaultArgument()) {
+ lastChild();
+ dumpTemplateArgument(D->getDefaultArgument());
+ }
}
void ASTDumper::VisitTemplateTemplateParmDecl(
@@ -1194,8 +1229,10 @@ void ASTDumper::VisitTemplateTemplateParmDecl(
OS << " ...";
dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
- if (D->hasDefaultArgument())
+ if (D->hasDefaultArgument()) {
+ lastChild();
dumpTemplateArgumentLoc(D->getDefaultArgument());
+ }
}
void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
@@ -1252,8 +1289,6 @@ void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
dumpType(D->getType());
if (D->getSynthesize())
OS << " synthesize";
- if (D->getBackingIvarReferencedInAccessor())
- OS << " BackingIvarReferencedInAccessor";
switch (D->getAccessControl()) {
case ObjCIvarDecl::None:
@@ -1280,7 +1315,7 @@ void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
else
OS << " +";
dumpName(D);
- dumpType(D->getResultType());
+ dumpType(D->getReturnType());
bool OldMoreChildren = hasMoreChildren();
bool IsVariadic = D->isVariadic();
@@ -1338,28 +1373,20 @@ void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
dumpName(D);
- for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
- E = D->protocol_end();
- I != E; ++I) {
- if (I + 1 == E)
- lastChild();
- dumpDeclRef(*I);
- }
+
+ ChildDumper Children(*this);
+ for (auto *Child : D->protocols())
+ Children.dumpRef(Child);
}
void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
dumpName(D);
dumpDeclRef(D->getSuperClass(), "super");
- if (D->protocol_begin() == D->protocol_end())
- lastChild();
- dumpDeclRef(D->getImplementation());
- for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
- E = D->protocol_end();
- I != E; ++I) {
- if (I + 1 == E)
- lastChild();
- dumpDeclRef(*I);
- }
+
+ ChildDumper Children(*this);
+ Children.dumpRef(D->getImplementation());
+ for (auto *Child : D->protocols())
+ Children.dumpRef(Child);
}
void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
@@ -1438,9 +1465,8 @@ void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
}
void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
- for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end();
- I != E; ++I)
- dumpDecl(*I);
+ for (auto I : D->params())
+ dumpDecl(I);
if (D->isVariadic()) {
IndentScope Indent(*this);
@@ -1451,20 +1477,19 @@ void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
IndentScope Indent(*this);
OS << "capture this";
}
- for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end();
- I != E; ++I) {
+ for (const auto &I : D->captures()) {
IndentScope Indent(*this);
OS << "capture";
- if (I->isByRef())
+ if (I.isByRef())
OS << " byref";
- if (I->isNested())
+ if (I.isNested())
OS << " nested";
- if (I->getVariable()) {
+ if (I.getVariable()) {
OS << ' ';
- dumpBareDeclRef(I->getVariable());
+ dumpBareDeclRef(I.getVariable());
}
- if (I->hasCopyExpr())
- dumpStmt(I->getCopyExpr());
+ if (I.hasCopyExpr())
+ dumpStmt(I.getCopyExpr());
}
lastChild();
dumpStmt(D->getBody());
@@ -1675,6 +1700,7 @@ void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
case PredefinedExpr::FuncDName: OS << " __FUNCDNAME__"; break;
case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break;
case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break;
+ case PredefinedExpr::FuncSig: OS << " __FUNCSIG__"; break;
}
}
@@ -1705,6 +1731,22 @@ void ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
Str->outputString(OS);
}
+void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
+ VisitExpr(ILE);
+ if (auto *Filler = ILE->getArrayFiller()) {
+ if (!ILE->getNumInits())
+ lastChild();
+ IndentScope Indent(*this);
+ OS << "array filler";
+ lastChild();
+ dumpStmt(Filler);
+ }
+ if (auto *Field = ILE->getInitializedFieldInUnion()) {
+ OS << " field ";
+ dumpBareDeclRef(Field);
+ }
+}
+
void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
VisitExpr(Node);
OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
@@ -1849,7 +1891,8 @@ void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
VisitExpr(Node);
- OS << " selector=" << Node->getSelector().getAsString();
+ OS << " selector=";
+ Node->getSelector().print(OS);
switch (Node->getReceiverKind()) {
case ObjCMessageExpr::Instance:
break;
@@ -1871,7 +1914,8 @@ void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
VisitExpr(Node);
- OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString();
+ OS << " selector=";
+ Node->getBoxingMethod()->getSelector().print(OS);
}
void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
@@ -1890,7 +1934,8 @@ void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
VisitExpr(Node);
- OS << " " << Node->getSelector().getAsString();
+ OS << " ";
+ Node->getSelector().print(OS);
}
void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
@@ -1904,13 +1949,13 @@ void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
if (Node->isImplicitProperty()) {
OS << " Kind=MethodRef Getter=\"";
if (Node->getImplicitPropertyGetter())
- OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
+ Node->getImplicitPropertyGetter()->getSelector().print(OS);
else
OS << "(null)";
OS << "\" Setter=\"";
if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
- OS << Setter->getSelector().getAsString();
+ Setter->getSelector().print(OS);
else
OS << "(null)";
OS << "\"";
@@ -1937,7 +1982,7 @@ void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
else
OS << " Kind=DictionarySubscript GetterForDictionary=\"";
if (Node->getAtIndexMethodDecl())
- OS << Node->getAtIndexMethodDecl()->getSelector().getAsString();
+ Node->getAtIndexMethodDecl()->getSelector().print(OS);
else
OS << "(null)";
@@ -1946,7 +1991,7 @@ void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
else
OS << "\" SetterForDictionary=\"";
if (Node->setAtIndexMethodDecl())
- OS << Node->setAtIndexMethodDecl()->getSelector().getAsString();
+ Node->setAtIndexMethodDecl()->getSelector().print(OS);
else
OS << "(null)";
}
@@ -1975,7 +2020,7 @@ void ASTDumper::dumpFullComment(const FullComment *C) {
FC = C;
dumpComment(C);
- FC = 0;
+ FC = nullptr;
}
void ASTDumper::dumpComment(const Comment *C) {
@@ -2065,7 +2110,7 @@ void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
}
- if (C->isParamIndexValid())
+ if (C->isParamIndexValid() && !C->isVarArgParam())
OS << " ParamIndex=" << C->getParamIndex();
}
@@ -2106,27 +2151,25 @@ void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
// Decl method implementations
//===----------------------------------------------------------------------===//
-void Decl::dump() const {
- dump(llvm::errs());
-}
+LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
-void Decl::dump(raw_ostream &OS) const {
+LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const {
ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
&getASTContext().getSourceManager());
P.dumpDecl(this);
}
-void Decl::dumpColor() const {
+LLVM_DUMP_METHOD void Decl::dumpColor() const {
ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
&getASTContext().getSourceManager(), /*ShowColors*/true);
P.dumpDecl(this);
}
-void DeclContext::dumpLookups() const {
+LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
dumpLookups(llvm::errs());
}
-void DeclContext::dumpLookups(raw_ostream &OS) const {
+LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS) const {
const DeclContext *DC = this;
while (!DC->isTranslationUnit())
DC = DC->getParent();
@@ -2139,22 +2182,22 @@ void DeclContext::dumpLookups(raw_ostream &OS) const {
// Stmt method implementations
//===----------------------------------------------------------------------===//
-void Stmt::dump(SourceManager &SM) const {
+LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
dump(llvm::errs(), SM);
}
-void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
- ASTDumper P(OS, 0, &SM);
+LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
+ ASTDumper P(OS, nullptr, &SM);
P.dumpStmt(this);
}
-void Stmt::dump() const {
- ASTDumper P(llvm::errs(), 0, 0);
+LLVM_DUMP_METHOD void Stmt::dump() const {
+ ASTDumper P(llvm::errs(), nullptr, nullptr);
P.dumpStmt(this);
}
-void Stmt::dumpColor() const {
- ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true);
+LLVM_DUMP_METHOD void Stmt::dumpColor() const {
+ ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
P.dumpStmt(this);
}
@@ -2162,11 +2205,11 @@ void Stmt::dumpColor() const {
// Comment method implementations
//===----------------------------------------------------------------------===//
-void Comment::dump() const {
- dump(llvm::errs(), 0, 0);
+LLVM_DUMP_METHOD void Comment::dump() const {
+ dump(llvm::errs(), nullptr, nullptr);
}
-void Comment::dump(const ASTContext &Context) const {
+LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
dump(llvm::errs(), &Context.getCommentCommandTraits(),
&Context.getSourceManager());
}
@@ -2178,8 +2221,8 @@ void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
D.dumpFullComment(FC);
}
-void Comment::dumpColor() const {
+LLVM_DUMP_METHOD void Comment::dumpColor() const {
const FullComment *FC = dyn_cast<FullComment>(this);
- ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true);
+ ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
D.dumpFullComment(FC);
}
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp b/contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp
index e16015b..b0e0b1d 100644
--- a/contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ASTImporter.cpp
@@ -81,7 +81,7 @@ namespace clang {
bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
DeclContext *&LexicalDC, DeclarationName &Name,
SourceLocation &Loc);
- void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = 0);
+ void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
DeclarationNameInfo& To);
void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
@@ -407,10 +407,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
break;
+ case Type::Adjusted:
case Type::Decayed:
if (!IsStructurallyEquivalent(Context,
- cast<DecayedType>(T1)->getPointeeType(),
- cast<DecayedType>(T2)->getPointeeType()))
+ cast<AdjustedType>(T1)->getOriginalType(),
+ cast<AdjustedType>(T2)->getOriginalType()))
return false;
break;
@@ -534,12 +535,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
case Type::FunctionProto: {
const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
- if (Proto1->getNumArgs() != Proto2->getNumArgs())
+ if (Proto1->getNumParams() != Proto2->getNumParams())
return false;
- for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
- if (!IsStructurallyEquivalent(Context,
- Proto1->getArgType(I),
- Proto2->getArgType(I)))
+ for (unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
+ if (!IsStructurallyEquivalent(Context, Proto1->getParamType(I),
+ Proto2->getParamType(I)))
return false;
}
if (Proto1->isVariadic() != Proto2->isVariadic())
@@ -570,9 +570,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
case Type::FunctionNoProto: {
const FunctionType *Function1 = cast<FunctionType>(T1);
const FunctionType *Function2 = cast<FunctionType>(T2);
- if (!IsStructurallyEquivalent(Context,
- Function1->getResultType(),
- Function2->getResultType()))
+ if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
+ Function2->getReturnType()))
return false;
if (Function1->getExtInfo() != Function2->getExtInfo())
return false;
@@ -931,10 +930,8 @@ static Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) {
return None;
unsigned Index = 0;
- for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
- DEnd = Owner->noload_decls_end();
- D != DEnd; ++D) {
- FieldDecl *F = dyn_cast<FieldDecl>(*D);
+ for (const auto *D : Owner->noload_decls()) {
+ const auto *F = dyn_cast<FieldDecl>(D);
if (!F || !F->isAnonymousStructOrUnion())
continue;
@@ -1586,7 +1583,7 @@ QualType
ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
// FIXME: What happens if we're importing a function without a prototype
// into C++? Should we make it variadic?
- QualType ToResultType = Importer.Import(T->getResultType());
+ QualType ToResultType = Importer.Import(T->getReturnType());
if (ToResultType.isNull())
return QualType();
@@ -1595,16 +1592,14 @@ ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
}
QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
- QualType ToResultType = Importer.Import(T->getResultType());
+ QualType ToResultType = Importer.Import(T->getReturnType());
if (ToResultType.isNull())
return QualType();
// Import argument types
SmallVector<QualType, 4> ArgTypes;
- for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
- AEnd = T->arg_type_end();
- A != AEnd; ++A) {
- QualType ArgType = Importer.Import(*A);
+ for (const auto &A : T->param_types()) {
+ QualType ArgType = Importer.Import(A);
if (ArgType.isNull())
return QualType();
ArgTypes.push_back(ArgType);
@@ -1612,10 +1607,8 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
// Import exception types
SmallVector<QualType, 4> ExceptionTypes;
- for (FunctionProtoType::exception_iterator E = T->exception_begin(),
- EEnd = T->exception_end();
- E != EEnd; ++E) {
- QualType ExceptionType = Importer.Import(*E);
+ for (const auto &E : T->exceptions()) {
+ QualType ExceptionType = Importer.Import(E);
if (ExceptionType.isNull())
return QualType();
ExceptionTypes.push_back(ExceptionType);
@@ -1631,7 +1624,7 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
ToEPI.RefQualifier = FromEPI.RefQualifier;
ToEPI.NumExceptions = ExceptionTypes.size();
ToEPI.Exceptions = ExceptionTypes.data();
- ToEPI.ConsumedArguments = FromEPI.ConsumedArguments;
+ ToEPI.ConsumedParameters = FromEPI.ConsumedParameters;
ToEPI.ExceptionSpecType = FromEPI.ExceptionSpecType;
ToEPI.NoexceptExpr = Importer.Import(FromEPI.NoexceptExpr);
ToEPI.ExceptionSpecDecl = cast_or_null<FunctionDecl>(
@@ -1756,7 +1749,7 @@ QualType ASTNodeImporter::VisitTemplateSpecializationType(
}
QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
- NestedNameSpecifier *ToQualifier = 0;
+ NestedNameSpecifier *ToQualifier = nullptr;
// Note: the qualifier in an ElaboratedType is optional.
if (T->getQualifier()) {
ToQualifier = Importer.Import(T->getQualifier());
@@ -1787,11 +1780,9 @@ QualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
return QualType();
SmallVector<ObjCProtocolDecl *, 4> Protocols;
- for (ObjCObjectType::qual_iterator P = T->qual_begin(),
- PEnd = T->qual_end();
- P != PEnd; ++P) {
+ for (auto *P : T->quals()) {
ObjCProtocolDecl *Protocol
- = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
+ = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(P));
if (!Protocol)
return QualType();
Protocols.push_back(Protocol);
@@ -1909,11 +1900,8 @@ void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
return;
}
- for (DeclContext::decl_iterator From = FromDC->decls_begin(),
- FromEnd = FromDC->decls_end();
- From != FromEnd;
- ++From)
- Importer.Import(*From);
+ for (auto *From : FromDC->decls())
+ Importer.Import(From);
}
bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
@@ -1946,6 +1934,7 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ToData.HasProtectedFields = FromData.HasProtectedFields;
ToData.HasPublicFields = FromData.HasPublicFields;
ToData.HasMutableFields = FromData.HasMutableFields;
+ ToData.HasVariantMembers = FromData.HasVariantMembers;
ToData.HasOnlyCMembers = FromData.HasOnlyCMembers;
ToData.HasInClassInitializer = FromData.HasInClassInitializer;
ToData.HasUninitializedReferenceMember
@@ -1986,29 +1975,25 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ToData.IsLambda = FromData.IsLambda;
SmallVector<CXXBaseSpecifier *, 4> Bases;
- for (CXXRecordDecl::base_class_iterator
- Base1 = FromCXX->bases_begin(),
- FromBaseEnd = FromCXX->bases_end();
- Base1 != FromBaseEnd;
- ++Base1) {
- QualType T = Importer.Import(Base1->getType());
+ for (const auto &Base1 : FromCXX->bases()) {
+ QualType T = Importer.Import(Base1.getType());
if (T.isNull())
return true;
SourceLocation EllipsisLoc;
- if (Base1->isPackExpansion())
- EllipsisLoc = Importer.Import(Base1->getEllipsisLoc());
+ if (Base1.isPackExpansion())
+ EllipsisLoc = Importer.Import(Base1.getEllipsisLoc());
// Ensure that we have a definition for the base.
- ImportDefinitionIfNeeded(Base1->getType()->getAsCXXRecordDecl());
+ ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl());
Bases.push_back(
new (Importer.getToContext())
- CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
- Base1->isVirtual(),
- Base1->isBaseOfClass(),
- Base1->getAccessSpecifierAsWritten(),
- Importer.Import(Base1->getTypeSourceInfo()),
+ CXXBaseSpecifier(Importer.Import(Base1.getSourceRange()),
+ Base1.isVirtual(),
+ Base1.isBaseOfClass(),
+ Base1.getAccessSpecifierAsWritten(),
+ Importer.Import(Base1.getTypeSourceInfo()),
EllipsisLoc));
}
if (!Bases.empty())
@@ -2075,8 +2060,8 @@ TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
P != PEnd; ++P) {
Decl *To = Importer.Import(*P);
if (!To)
- return 0;
-
+ return nullptr;
+
ToParams.push_back(cast<NamedDecl>(To));
}
@@ -2236,7 +2221,7 @@ bool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From,
Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
<< D->getDeclKindName();
- return 0;
+ return nullptr;
}
Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
@@ -2254,9 +2239,9 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
- NamespaceDecl *MergeWithNamespace = 0;
+ return nullptr;
+
+ NamespaceDecl *MergeWithNamespace = nullptr;
if (!Name) {
// This is an anonymous namespace. Adopt an existing anonymous
// namespace if we can.
@@ -2296,7 +2281,7 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
D->isInline(),
Importer.Import(D->getLocStart()),
Loc, Name.getAsIdentifierInfo(),
- /*PrevDecl=*/0);
+ /*PrevDecl=*/nullptr);
ToNamespace->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToNamespace);
@@ -2322,8 +2307,8 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// If this typedef is not in block scope, determine whether we've
// seen a typedef with the same name (that we can merge with) or any
// other entity by that name (which name lookup could conflict with).
@@ -2350,15 +2335,15 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return 0;
+ return nullptr;
}
}
// Import the underlying type of this typedef;
QualType T = Importer.Import(D->getUnderlyingType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Create the new typedef node.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
SourceLocation StartL = Importer.Import(D->getLocStart());
@@ -2396,8 +2381,8 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Figure out what enum name we're looking for.
unsigned IDNS = Decl::IDNS_Tag;
DeclarationName SearchName = Name;
@@ -2440,7 +2425,7 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
// Create the enum declaration.
EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getLocStart()),
- Loc, Name.getAsIdentifierInfo(), 0,
+ Loc, Name.getAsIdentifierInfo(), nullptr,
D->isScoped(), D->isScopedUsingClassTag(),
D->isFixed());
// Import the qualifier, if any.
@@ -2453,12 +2438,12 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
// Import the integer type.
QualType ToIntegerType = Importer.Import(D->getIntegerType());
if (ToIntegerType.isNull())
- return 0;
+ return nullptr;
D2->setIntegerType(ToIntegerType);
// Import the definition
if (D->isCompleteDefinition() && ImportDefinition(D, D2))
- return 0;
+ return nullptr;
return D2;
}
@@ -2471,8 +2456,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -2481,8 +2466,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Figure out what structure name we're looking for.
unsigned IDNS = Decl::IDNS_Tag;
DeclarationName SearchName = Name;
@@ -2493,7 +2478,7 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
IDNS |= Decl::IDNS_Ordinary;
// We may already have a record of the same name; try to find and match it.
- RecordDecl *AdoptDecl = 0;
+ RecordDecl *AdoptDecl = nullptr;
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
SmallVector<NamedDecl *, 2> FoundDecls;
@@ -2538,6 +2523,21 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
} else if (!D->isCompleteDefinition()) {
// We have a forward declaration of this type, so adopt that forward
// declaration rather than building a new one.
+
+ // If one or both can be completed from external storage then try one
+ // last time to complete and compare them before doing this.
+
+ if (FoundRecord->hasExternalLexicalStorage() &&
+ !FoundRecord->isCompleteDefinition())
+ FoundRecord->getASTContext().getExternalSource()->CompleteType(FoundRecord);
+ if (D->hasExternalLexicalStorage())
+ D->getASTContext().getExternalSource()->CompleteType(D);
+
+ if (FoundRecord->isCompleteDefinition() &&
+ D->isCompleteDefinition() &&
+ !IsStructuralMatch(D, FoundRecord))
+ continue;
+
AdoptDecl = FoundRecord;
continue;
} else if (!SearchName) {
@@ -2581,8 +2581,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
Importer.Imported(D, D2);
if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default))
- return 0;
-
+ return nullptr;
+
return D2;
}
@@ -2592,11 +2592,11 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
+ return nullptr;
// Determine whether there are any other declarations with the same name and
// in the same context.
@@ -2623,14 +2623,14 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return 0;
+ return nullptr;
}
}
Expr *Init = Importer.Import(D->getInitExpr());
if (D->getInitExpr() && !Init)
- return 0;
-
+ return nullptr;
+
EnumConstantDecl *ToEnumerator
= EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
Name.getAsIdentifierInfo(), T,
@@ -2648,7 +2648,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
// Try to find a function in our own ("to") context with the same name, same
// type, and in the same context as the function we're importing.
@@ -2694,7 +2694,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return 0;
+ return nullptr;
}
}
@@ -2716,7 +2716,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
FromEPI.NoexceptExpr) {
FunctionProtoType::ExtProtoInfo DefaultEPI;
FromTy = Importer.getFromContext().getFunctionType(
- FromFPT->getResultType(), FromFPT->getArgTypes(), DefaultEPI);
+ FromFPT->getReturnType(), FromFPT->getParamTypes(), DefaultEPI);
usedDifferentExceptionSpec = true;
}
}
@@ -2724,22 +2724,21 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
// Import the type.
QualType T = Importer.Import(FromTy);
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Import the function parameters.
SmallVector<ParmVarDecl *, 8> Parameters;
- for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
- P != PEnd; ++P) {
- ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
+ for (auto P : D->params()) {
+ ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P));
if (!ToP)
- return 0;
-
+ return nullptr;
+
Parameters.push_back(ToP);
}
// Create the imported function.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
- FunctionDecl *ToFunction = 0;
+ FunctionDecl *ToFunction = nullptr;
if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
cast<CXXRecordDecl>(DC),
@@ -2804,7 +2803,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
// Update FunctionProtoType::ExtProtoInfo.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
+ return nullptr;
ToFunction->setType(T);
}
@@ -2838,10 +2837,8 @@ static unsigned getFieldIndex(Decl *F) {
return 0;
unsigned Index = 1;
- for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
- DEnd = Owner->noload_decls_end();
- D != DEnd; ++D) {
- if (*D == F)
+ for (const auto *D : Owner->noload_decls()) {
+ if (D == F)
return Index;
if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
@@ -2857,8 +2854,8 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Determine whether we've already imported this field.
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
@@ -2878,20 +2875,20 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
- return 0;
+ return nullptr;
}
}
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Expr *BitWidth = Importer.Import(D->getBitWidth());
if (!BitWidth && D->getBitWidth())
- return 0;
-
+ return nullptr;
+
FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
@@ -2913,7 +2910,7 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
// Determine whether we've already imported this field.
SmallVector<NamedDecl *, 2> FoundDecls;
@@ -2940,24 +2937,23 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
- return 0;
+ return nullptr;
}
}
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
+ return nullptr;
NamedDecl **NamedChain =
new (Importer.getToContext())NamedDecl*[D->getChainingSize()];
unsigned i = 0;
- for (IndirectFieldDecl::chain_iterator PI = D->chain_begin(),
- PE = D->chain_end(); PI != PE; ++PI) {
- Decl* D = Importer.Import(*PI);
+ for (auto *PI : D->chain()) {
+ Decl *D = Importer.Import(PI);
if (!D)
- return 0;
+ return nullptr;
NamedChain[i++] = cast<NamedDecl>(D);
}
@@ -2978,8 +2974,8 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Determine whether we've already imported this ivar
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
@@ -2995,27 +2991,26 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
<< Name << D->getType() << FoundIvar->getType();
Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
<< FoundIvar->getType();
- return 0;
+ return nullptr;
}
}
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Expr *BitWidth = Importer.Import(D->getBitWidth());
if (!BitWidth && D->getBitWidth())
- return 0;
-
+ return nullptr;
+
ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
cast<ObjCContainerDecl>(DC),
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
T, TInfo, D->getAccessControl(),
- BitWidth, D->getSynthesize(),
- D->getBackingIvarReferencedInAccessor());
+ BitWidth, D->getSynthesize());
ToIvar->setLexicalDeclContext(LexicalDC);
Importer.Imported(D, ToIvar);
LexicalDC->addDeclInternal(ToIvar);
@@ -3029,12 +3024,12 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Try to find a variable in our own ("to") context with the same name and
// in the same context as the variable we're importing.
if (D->isFileVarDecl()) {
- VarDecl *MergeWithVar = 0;
+ VarDecl *MergeWithVar = nullptr;
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
SmallVector<NamedDecl *, 2> FoundDecls;
@@ -3063,8 +3058,8 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
FoundVar->setType(T);
MergeWithVar = FoundVar;
break;
@@ -3115,15 +3110,15 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return 0;
+ return nullptr;
}
}
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Create the imported variable.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC,
@@ -3139,7 +3134,7 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
// Merge the initializer.
if (ImportDefinition(D, ToVar))
- return 0;
+ return nullptr;
return ToVar;
}
@@ -3152,16 +3147,16 @@ Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
// Import the name of this declaration.
DeclarationName Name = Importer.Import(D->getDeclName());
if (D->getDeclName() && !Name)
- return 0;
-
+ return nullptr;
+
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
// Import the parameter's type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Create the imported parameter.
ImplicitParamDecl *ToParm
= ImplicitParamDecl::Create(Importer.getToContext(), DC,
@@ -3178,23 +3173,23 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
// Import the name of this declaration.
DeclarationName Name = Importer.Import(D->getDeclName());
if (D->getDeclName() && !Name)
- return 0;
-
+ return nullptr;
+
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
// Import the parameter's type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Create the imported parameter.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
T, TInfo, D->getStorageClass(),
- /*FIXME: Default argument*/ 0);
+ /*FIXME: Default argument*/nullptr);
ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
return Importer.Imported(D, ToParm);
}
@@ -3205,8 +3200,8 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
@@ -3215,15 +3210,15 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
continue;
// Check return types.
- if (!Importer.IsStructurallyEquivalent(D->getResultType(),
- FoundMethod->getResultType())) {
+ if (!Importer.IsStructurallyEquivalent(D->getReturnType(),
+ FoundMethod->getReturnType())) {
Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
- << D->isInstanceMethod() << Name
- << D->getResultType() << FoundMethod->getResultType();
+ << D->isInstanceMethod() << Name << D->getReturnType()
+ << FoundMethod->getReturnType();
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return 0;
+ return nullptr;
}
// Check the number of parameters.
@@ -3234,7 +3229,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return 0;
+ return nullptr;
}
// Check parameter types.
@@ -3249,7 +3244,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
<< (*P)->getType() << (*FoundP)->getType();
Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
<< (*FoundP)->getType();
- return 0;
+ return nullptr;
}
}
@@ -3261,7 +3256,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return 0;
+ return nullptr;
}
// FIXME: Any other bits we need to merge?
@@ -3270,39 +3265,28 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
}
// Import the result type.
- QualType ResultTy = Importer.Import(D->getResultType());
+ QualType ResultTy = Importer.Import(D->getReturnType());
if (ResultTy.isNull())
- return 0;
+ return nullptr;
+
+ TypeSourceInfo *ReturnTInfo = Importer.Import(D->getReturnTypeSourceInfo());
- TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
-
- ObjCMethodDecl *ToMethod
- = ObjCMethodDecl::Create(Importer.getToContext(),
- Loc,
- Importer.Import(D->getLocEnd()),
- Name.getObjCSelector(),
- ResultTy, ResultTInfo, DC,
- D->isInstanceMethod(),
- D->isVariadic(),
- D->isPropertyAccessor(),
- D->isImplicit(),
- D->isDefined(),
- D->getImplementationControl(),
- D->hasRelatedResultType());
+ ObjCMethodDecl *ToMethod = ObjCMethodDecl::Create(
+ Importer.getToContext(), Loc, Importer.Import(D->getLocEnd()),
+ Name.getObjCSelector(), ResultTy, ReturnTInfo, DC, D->isInstanceMethod(),
+ D->isVariadic(), D->isPropertyAccessor(), D->isImplicit(), D->isDefined(),
+ D->getImplementationControl(), D->hasRelatedResultType());
// FIXME: When we decide to merge method definitions, we'll need to
// deal with implicit parameters.
// Import the parameters
SmallVector<ParmVarDecl *, 5> ToParams;
- for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
- FromPEnd = D->param_end();
- FromP != FromPEnd;
- ++FromP) {
- ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
+ for (auto *FromP : D->params()) {
+ ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP));
if (!ToP)
- return 0;
-
+ return nullptr;
+
ToParams.push_back(ToP);
}
@@ -3327,13 +3311,13 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
ObjCInterfaceDecl *ToInterface
= cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
if (!ToInterface)
- return 0;
-
+ return nullptr;
+
// Determine if we've already encountered this category.
ObjCCategoryDecl *MergeWithCategory
= ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
@@ -3363,7 +3347,7 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
ObjCProtocolDecl *ToProto
= cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
if (!ToProto)
- return 0;
+ return nullptr;
Protocols.push_back(ToProto);
ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
}
@@ -3385,8 +3369,8 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
= cast_or_null<ObjCCategoryImplDecl>(
Importer.Import(D->getImplementation()));
if (!Impl)
- return 0;
-
+ return nullptr;
+
ToCategory->setImplementation(Impl);
}
@@ -3441,8 +3425,8 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -3451,9 +3435,9 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
- ObjCProtocolDecl *MergeWithProtocol = 0;
+ ObjCProtocolDecl *MergeWithProtocol = nullptr;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
@@ -3469,7 +3453,7 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC,
Name.getAsIdentifierInfo(), Loc,
Importer.Import(D->getAtStartLoc()),
- /*PrevDecl=*/0);
+ /*PrevDecl=*/nullptr);
ToProto->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToProto);
}
@@ -3477,8 +3461,8 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Importer.Imported(D, ToProto);
if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto))
- return 0;
-
+ return nullptr;
+
return ToProto;
}
@@ -3558,12 +3542,8 @@ bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
// Import categories. When the categories themselves are imported, they'll
// hook themselves into this interface.
- for (ObjCInterfaceDecl::known_categories_iterator
- Cat = From->known_categories_begin(),
- CatEnd = From->known_categories_end();
- Cat != CatEnd; ++Cat) {
- Importer.Import(*Cat);
- }
+ for (auto *Cat : From->known_categories())
+ Importer.Import(Cat);
// If we have an @implementation, import it as well.
if (From->getImplementation()) {
@@ -3590,8 +3570,8 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -3600,10 +3580,10 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
// Look for an existing interface with the same name.
- ObjCInterfaceDecl *MergeWithIface = 0;
+ ObjCInterfaceDecl *MergeWithIface = nullptr;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
@@ -3620,7 +3600,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getAtStartLoc()),
Name.getAsIdentifierInfo(),
- /*PrevDecl=*/0,Loc,
+ /*PrevDecl=*/nullptr, Loc,
D->isImplicitInterfaceDecl());
ToIface->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToIface);
@@ -3628,8 +3608,8 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Importer.Imported(D, ToIface);
if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface))
- return 0;
-
+ return nullptr;
+
return ToIface;
}
@@ -3637,14 +3617,14 @@ Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
ObjCCategoryDecl *Category = cast_or_null<ObjCCategoryDecl>(
Importer.Import(D->getCategoryDecl()));
if (!Category)
- return 0;
-
+ return nullptr;
+
ObjCCategoryImplDecl *ToImpl = Category->getImplementation();
if (!ToImpl) {
DeclContext *DC = Importer.ImportContext(D->getDeclContext());
if (!DC)
- return 0;
-
+ return nullptr;
+
SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
ToImpl = ObjCCategoryImplDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getIdentifier()),
@@ -3657,8 +3637,8 @@ Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
if (D->getDeclContext() != D->getLexicalDeclContext()) {
LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
-
+ return nullptr;
+
ToImpl->setLexicalDeclContext(LexicalDC);
}
@@ -3676,15 +3656,15 @@ Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
ObjCInterfaceDecl *Iface = cast_or_null<ObjCInterfaceDecl>(
Importer.Import(D->getClassInterface()));
if (!Iface)
- return 0;
+ return nullptr;
// Import the superclass, if any.
- ObjCInterfaceDecl *Super = 0;
+ ObjCInterfaceDecl *Super = nullptr;
if (D->getSuperClass()) {
Super = cast_or_null<ObjCInterfaceDecl>(
Importer.Import(D->getSuperClass()));
if (!Super)
- return 0;
+ return nullptr;
}
ObjCImplementationDecl *Impl = Iface->getImplementation();
@@ -3704,7 +3684,7 @@ Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
DeclContext *LexicalDC
= Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
+ return nullptr;
Impl->setLexicalDeclContext(LexicalDC);
}
@@ -3717,28 +3697,29 @@ Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
// Verify that the existing @implementation has the same superclass.
if ((Super && !Impl->getSuperClass()) ||
(!Super && Impl->getSuperClass()) ||
- (Super && Impl->getSuperClass() &&
- !declaresSameEntity(Super->getCanonicalDecl(), Impl->getSuperClass()))) {
- Importer.ToDiag(Impl->getLocation(),
- diag::err_odr_objc_superclass_inconsistent)
- << Iface->getDeclName();
- // FIXME: It would be nice to have the location of the superclass
- // below.
- if (Impl->getSuperClass())
- Importer.ToDiag(Impl->getLocation(),
+ (Super && Impl->getSuperClass() &&
+ !declaresSameEntity(Super->getCanonicalDecl(),
+ Impl->getSuperClass()))) {
+ Importer.ToDiag(Impl->getLocation(),
+ diag::err_odr_objc_superclass_inconsistent)
+ << Iface->getDeclName();
+ // FIXME: It would be nice to have the location of the superclass
+ // below.
+ if (Impl->getSuperClass())
+ Importer.ToDiag(Impl->getLocation(),
+ diag::note_odr_objc_superclass)
+ << Impl->getSuperClass()->getDeclName();
+ else
+ Importer.ToDiag(Impl->getLocation(),
+ diag::note_odr_objc_missing_superclass);
+ if (D->getSuperClass())
+ Importer.FromDiag(D->getLocation(),
diag::note_odr_objc_superclass)
- << Impl->getSuperClass()->getDeclName();
- else
- Importer.ToDiag(Impl->getLocation(),
+ << D->getSuperClass()->getDeclName();
+ else
+ Importer.FromDiag(D->getLocation(),
diag::note_odr_objc_missing_superclass);
- if (D->getSuperClass())
- Importer.FromDiag(D->getLocation(),
- diag::note_odr_objc_superclass)
- << D->getSuperClass()->getDeclName();
- else
- Importer.FromDiag(D->getLocation(),
- diag::note_odr_objc_missing_superclass);
- return 0;
+ return nullptr;
}
}
@@ -3754,7 +3735,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
// Check whether we have already imported this property.
SmallVector<NamedDecl *, 2> FoundDecls;
@@ -3769,7 +3750,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
<< Name << D->getType() << FoundProp->getType();
Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
<< FoundProp->getType();
- return 0;
+ return nullptr;
}
// FIXME: Check property attributes, getters, setters, etc.?
@@ -3783,7 +3764,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
// Import the type.
TypeSourceInfo *T = Importer.Import(D->getTypeSourceInfo());
if (!T)
- return 0;
+ return nullptr;
// Create the new property.
ObjCPropertyDecl *ToProperty
@@ -3815,31 +3796,31 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
ObjCPropertyDecl *Property = cast_or_null<ObjCPropertyDecl>(
Importer.Import(D->getPropertyDecl()));
if (!Property)
- return 0;
+ return nullptr;
DeclContext *DC = Importer.ImportContext(D->getDeclContext());
if (!DC)
- return 0;
-
+ return nullptr;
+
// Import the lexical declaration context.
DeclContext *LexicalDC = DC;
if (D->getDeclContext() != D->getLexicalDeclContext()) {
LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
+ return nullptr;
}
ObjCImplDecl *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
if (!InImpl)
- return 0;
+ return nullptr;
// Import the ivar (for an @synthesize).
- ObjCIvarDecl *Ivar = 0;
+ ObjCIvarDecl *Ivar = nullptr;
if (D->getPropertyIvarDecl()) {
Ivar = cast_or_null<ObjCIvarDecl>(
Importer.Import(D->getPropertyIvarDecl()));
if (!Ivar)
- return 0;
+ return nullptr;
}
ObjCPropertyImplDecl *ToImpl
@@ -3868,7 +3849,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
diag::note_odr_objc_property_impl_kind)
<< D->getPropertyDecl()->getDeclName()
<< (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
- return 0;
+ return nullptr;
}
// For @synthesize, check that we have the same
@@ -3882,7 +3863,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
Importer.FromDiag(D->getPropertyIvarDeclLoc(),
diag::note_odr_objc_synthesize_ivar_here)
<< D->getPropertyIvarDecl()->getDeclName();
- return 0;
+ return nullptr;
}
// Merge the existing implementation with the new implementation.
@@ -3914,21 +3895,21 @@ ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
// Import the name of this declaration.
DeclarationName Name = Importer.Import(D->getDeclName());
if (D->getDeclName() && !Name)
- return 0;
-
+ return nullptr;
+
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
// Import the type of this declaration.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Import type-source information.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
if (D->getTypeSourceInfo() && !TInfo)
- return 0;
-
+ return nullptr;
+
// FIXME: Import default argument.
return NonTypeTemplateParmDecl::Create(Importer.getToContext(),
@@ -3944,8 +3925,8 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
// Import the name of this declaration.
DeclarationName Name = Importer.Import(D->getDeclName());
if (D->getDeclName() && !Name)
- return 0;
-
+ return nullptr;
+
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
@@ -3953,8 +3934,8 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
TemplateParameterList *TemplateParams
= ImportTemplateParameterList(D->getTemplateParameters());
if (!TemplateParams)
- return 0;
-
+ return nullptr;
+
// FIXME: Import default argument.
return TemplateTemplateParmDecl::Create(Importer.getToContext(),
@@ -3975,8 +3956,8 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
Decl *ImportedDef
= Importer.Import(Definition->getDescribedClassTemplate());
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -3985,8 +3966,8 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// We may already have a template of the same name; try to find and match it.
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
@@ -4019,7 +4000,7 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
}
if (!Name)
- return 0;
+ return nullptr;
}
CXXRecordDecl *DTemplated = D->getTemplatedDecl();
@@ -4039,12 +4020,12 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
TemplateParameterList *TemplateParams
= ImportTemplateParameterList(D->getTemplateParameters());
if (!TemplateParams)
- return 0;
-
+ return nullptr;
+
ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC,
Loc, Name, TemplateParams,
D2Templated,
- /*PrevDecl=*/0);
+ /*PrevDecl=*/nullptr);
D2Templated->setDescribedClassTemplate(D2);
D2->setAccess(D->getAccess());
@@ -4072,8 +4053,8 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -4081,18 +4062,18 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
= cast_or_null<ClassTemplateDecl>(Importer.Import(
D->getSpecializedTemplate()));
if (!ClassTemplate)
- return 0;
-
+ return nullptr;
+
// Import the context of this declaration.
DeclContext *DC = ClassTemplate->getDeclContext();
if (!DC)
- return 0;
-
+ return nullptr;
+
DeclContext *LexicalDC = DC;
if (D->getDeclContext() != D->getLexicalDeclContext()) {
LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
+ return nullptr;
}
// Import the location of this declaration.
@@ -4104,13 +4085,12 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
if (ImportTemplateArguments(D->getTemplateArgs().data(),
D->getTemplateArgs().size(),
TemplateArgs))
- return 0;
-
+ return nullptr;
+
// Try to find an existing specialization with these template arguments.
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *D2
- = ClassTemplate->findSpecialization(TemplateArgs.data(),
- TemplateArgs.size(), InsertPos);
+ = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
if (D2) {
// We already have a class template specialization with these template
// arguments.
@@ -4133,7 +4113,7 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
ClassTemplate,
TemplateArgs.data(),
TemplateArgs.size(),
- /*PrevDecl=*/0);
+ /*PrevDecl=*/nullptr);
D2->setSpecializationKind(D->getSpecializationKind());
// Add this specialization to the class template.
@@ -4149,8 +4129,8 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
Importer.Imported(D, D2);
if (D->isCompleteDefinition() && ImportDefinition(D, D2))
- return 0;
-
+ return nullptr;
+
return D2;
}
@@ -4164,7 +4144,7 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
if (Definition && Definition != D->getTemplatedDecl()) {
Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate());
if (!ImportedDef)
- return 0;
+ return nullptr;
return Importer.Imported(D, ImportedDef);
}
@@ -4174,7 +4154,7 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
// We may already have a template of the same name; try to find and match it.
assert(!DC->isFunctionOrMethod() &&
@@ -4206,14 +4186,14 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
}
if (!Name)
- return 0;
+ return nullptr;
VarDecl *DTemplated = D->getTemplatedDecl();
// Import the type.
QualType T = Importer.Import(DTemplated->getType());
if (T.isNull())
- return 0;
+ return nullptr;
// Create the declaration that is being templated.
SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
@@ -4231,17 +4211,16 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
// Merge the initializer.
if (ImportDefinition(DTemplated, D2Templated))
- return 0;
+ return nullptr;
// Create the variable template declaration itself.
TemplateParameterList *TemplateParams =
ImportTemplateParameterList(D->getTemplateParameters());
if (!TemplateParams)
- return 0;
+ return nullptr;
VarTemplateDecl *D2 = VarTemplateDecl::Create(
- Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated,
- /*PrevDecl=*/0);
+ Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated);
D2Templated->setDescribedVarTemplate(D2);
D2->setAccess(D->getAccess());
@@ -4269,7 +4248,7 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
+ return nullptr;
return Importer.Imported(D, ImportedDef);
}
@@ -4277,18 +4256,18 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
VarTemplateDecl *VarTemplate = cast_or_null<VarTemplateDecl>(
Importer.Import(D->getSpecializedTemplate()));
if (!VarTemplate)
- return 0;
+ return nullptr;
// Import the context of this declaration.
DeclContext *DC = VarTemplate->getDeclContext();
if (!DC)
- return 0;
+ return nullptr;
DeclContext *LexicalDC = DC;
if (D->getDeclContext() != D->getLexicalDeclContext()) {
LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
+ return nullptr;
}
// Import the location of this declaration.
@@ -4299,12 +4278,12 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
SmallVector<TemplateArgument, 2> TemplateArgs;
if (ImportTemplateArguments(D->getTemplateArgs().data(),
D->getTemplateArgs().size(), TemplateArgs))
- return 0;
+ return nullptr;
// Try to find an existing specialization with these template arguments.
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
- TemplateArgs.data(), TemplateArgs.size(), InsertPos);
+ TemplateArgs, InsertPos);
if (D2) {
// We already have a variable template specialization with these template
// arguments.
@@ -4325,7 +4304,7 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
+ return nullptr;
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
// Create a new specialization.
@@ -4348,7 +4327,7 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
Importer.Imported(D, D2);
if (D->isThisDeclarationADefinition() && ImportDefinition(D, D2))
- return 0;
+ return nullptr;
return D2;
}
@@ -4360,7 +4339,7 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
<< S->getStmtClassName();
- return 0;
+ return nullptr;
}
//----------------------------------------------------------------------------
@@ -4369,24 +4348,24 @@ Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
Expr *ASTNodeImporter::VisitExpr(Expr *E) {
Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
<< E->getStmtClassName();
- return 0;
+ return nullptr;
}
Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
if (!ToD)
- return 0;
+ return nullptr;
- NamedDecl *FoundD = 0;
+ NamedDecl *FoundD = nullptr;
if (E->getDecl() != E->getFoundDecl()) {
FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl()));
if (!FoundD)
- return 0;
+ return nullptr;
}
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(),
Importer.Import(E->getQualifierLoc()),
@@ -4396,7 +4375,7 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
Importer.Import(E->getLocation()),
T, E->getValueKind(),
FoundD,
- /*FIXME:TemplateArgs=*/0);
+ /*FIXME:TemplateArgs=*/nullptr);
if (E->hadMultipleCandidates())
DRE->setHadMultipleCandidates(true);
return DRE;
@@ -4405,7 +4384,7 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
return IntegerLiteral::Create(Importer.getToContext(),
E->getValue(), T,
@@ -4415,8 +4394,8 @@ Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
E->getKind(), T,
Importer.Import(E->getLocation()));
@@ -4425,8 +4404,8 @@ Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
Expr *SubExpr = Importer.Import(E->getSubExpr());
if (!SubExpr)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext())
ParenExpr(Importer.Import(E->getLParen()),
Importer.Import(E->getRParen()),
@@ -4436,12 +4415,12 @@ Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
Expr *SubExpr = Importer.Import(E->getSubExpr());
if (!SubExpr)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
T, E->getValueKind(),
E->getObjectKind(),
@@ -4455,8 +4434,8 @@ Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
if (E->isArgumentType()) {
TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
if (!TInfo)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
TInfo, ResultType,
Importer.Import(E->getOperatorLoc()),
@@ -4465,8 +4444,8 @@ Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
Expr *SubExpr = Importer.Import(E->getArgumentExpr());
if (!SubExpr)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
SubExpr, ResultType,
Importer.Import(E->getOperatorLoc()),
@@ -4476,16 +4455,16 @@ Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
Expr *LHS = Importer.Import(E->getLHS());
if (!LHS)
- return 0;
-
+ return nullptr;
+
Expr *RHS = Importer.Import(E->getRHS());
if (!RHS)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
T, E->getValueKind(),
E->getObjectKind(),
@@ -4496,24 +4475,24 @@ Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
QualType CompLHSType = Importer.Import(E->getComputationLHSType());
if (CompLHSType.isNull())
- return 0;
-
+ return nullptr;
+
QualType CompResultType = Importer.Import(E->getComputationResultType());
if (CompResultType.isNull())
- return 0;
-
+ return nullptr;
+
Expr *LHS = Importer.Import(E->getLHS());
if (!LHS)
- return 0;
-
+ return nullptr;
+
Expr *RHS = Importer.Import(E->getRHS());
if (!RHS)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext())
CompoundAssignOperator(LHS, RHS, E->getOpcode(),
T, E->getValueKind(),
@@ -4533,15 +4512,15 @@ static bool ImportCastPath(CastExpr *E, CXXCastPath &Path) {
Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
Expr *SubExpr = Importer.Import(E->getSubExpr());
if (!SubExpr)
- return 0;
+ return nullptr;
CXXCastPath BasePath;
if (ImportCastPath(E, BasePath))
- return 0;
+ return nullptr;
return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
SubExpr, &BasePath, E->getValueKind());
@@ -4550,19 +4529,19 @@ Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
Expr *SubExpr = Importer.Import(E->getSubExpr());
if (!SubExpr)
- return 0;
+ return nullptr;
TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
if (!TInfo && E->getTypeInfoAsWritten())
- return 0;
-
+ return nullptr;
+
CXXCastPath BasePath;
if (ImportCastPath(E, BasePath))
- return 0;
+ return nullptr;
return CStyleCastExpr::Create(Importer.getToContext(), T,
E->getValueKind(), E->getCastKind(),
@@ -4616,7 +4595,7 @@ TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
// on the type and a single location. Implement a real version of this.
QualType T = Import(FromTSI->getType());
if (T.isNull())
- return 0;
+ return nullptr;
return ToContext.getTrivialTypeSourceInfo(T,
FromTSI->getTypeLoc().getLocStart());
@@ -4624,7 +4603,7 @@ TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Decl *ASTImporter::Import(Decl *FromD) {
if (!FromD)
- return 0;
+ return nullptr;
ASTNodeImporter Importer(*this);
@@ -4639,8 +4618,8 @@ Decl *ASTImporter::Import(Decl *FromD) {
// Import the type
Decl *ToD = Importer.Visit(FromD);
if (!ToD)
- return 0;
-
+ return nullptr;
+
// Record the imported declaration.
ImportedDecls[FromD] = ToD;
@@ -4675,8 +4654,8 @@ DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
DeclContext *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
if (!ToDC)
- return 0;
-
+ return nullptr;
+
// When we're using a record/enum/Objective-C class/protocol as a context, we
// need it to have a definition.
if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(ToDC)) {
@@ -4726,14 +4705,14 @@ DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
Expr *ASTImporter::Import(Expr *FromE) {
if (!FromE)
- return 0;
+ return nullptr;
return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
}
Stmt *ASTImporter::Import(Stmt *FromS) {
if (!FromS)
- return 0;
+ return nullptr;
// Check whether we've already imported this declaration.
llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
@@ -4744,8 +4723,8 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
ASTNodeImporter Importer(*this);
Stmt *ToS = Importer.Visit(FromS);
if (!ToS)
- return 0;
-
+ return nullptr;
+
// Record the imported declaration.
ImportedStmts[FromS] = ToS;
return ToS;
@@ -4753,7 +4732,7 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
if (!FromNNS)
- return 0;
+ return nullptr;
NestedNameSpecifier *prefix = Import(FromNNS->getPrefix());
@@ -4762,21 +4741,21 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) {
return NestedNameSpecifier::Create(ToContext, prefix, II);
}
- return 0;
+ return nullptr;
case NestedNameSpecifier::Namespace:
if (NamespaceDecl *NS =
cast<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
return NestedNameSpecifier::Create(ToContext, prefix, NS);
}
- return 0;
+ return nullptr;
case NestedNameSpecifier::NamespaceAlias:
if (NamespaceAliasDecl *NSAD =
cast<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
}
- return 0;
+ return nullptr;
case NestedNameSpecifier::Global:
return NestedNameSpecifier::GlobalSpecifier(ToContext);
@@ -4791,7 +4770,7 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
bTemplate, T.getTypePtr());
}
}
- return 0;
+ return nullptr;
}
llvm_unreachable("Invalid nested name specifier kind");
@@ -4943,8 +4922,7 @@ FileID ASTImporter::Import(FileID FromID) {
llvm::MemoryBuffer *ToBuf
= llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
FromBuf->getBufferIdentifier());
- ToID = ToSM.createFileIDForMemBuffer(ToBuf,
- FromSLoc.getFile().getFileCharacteristic());
+ ToID = ToSM.createFileID(ToBuf, FromSLoc.getFile().getFileCharacteristic());
}
@@ -5054,7 +5032,7 @@ DeclarationName ASTImporter::Import(DeclarationName FromName) {
IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
if (!FromId)
- return 0;
+ return nullptr;
return &ToContext.Idents.get(FromId->getName());
}
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp b/contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp
index ae47ea9..baa8e48 100644
--- a/contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ASTTypeTraits.cpp
@@ -39,18 +39,24 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
#include "clang/AST/TypeNodes.def"
};
-bool ASTNodeKind::isBaseOf(ASTNodeKind Other) const {
- return isBaseOf(KindId, Other.KindId);
+bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
+ return isBaseOf(KindId, Other.KindId, Distance);
}
bool ASTNodeKind::isSame(ASTNodeKind Other) const {
return KindId != NKI_None && KindId == Other.KindId;
}
-bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived) {
+bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
+ unsigned *Distance) {
if (Base == NKI_None || Derived == NKI_None) return false;
- while (Derived != Base && Derived != NKI_None)
+ unsigned Dist = 0;
+ while (Derived != Base && Derived != NKI_None) {
Derived = AllKindInfo[Derived].ParentId;
+ ++Dist;
+ }
+ if (Distance)
+ *Distance = Dist;
return Derived == Base;
}
@@ -71,7 +77,7 @@ void DynTypedNode::print(llvm::raw_ostream &OS,
else if (const Decl *D = get<Decl>())
D->print(OS, PP);
else if (const Stmt *S = get<Stmt>())
- S->printPretty(OS, 0, PP);
+ S->printPretty(OS, nullptr, PP);
else if (const Type *T = get<Type>())
QualType(T, 0).print(OS, PP);
else
diff --git a/contrib/llvm/tools/clang/lib/AST/AttrImpl.cpp b/contrib/llvm/tools/clang/lib/AST/AttrImpl.cpp
index 7af3c8b..0bf6bcd 100644
--- a/contrib/llvm/tools/clang/lib/AST/AttrImpl.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/AttrImpl.cpp
@@ -24,6 +24,4 @@ void InheritableAttr::anchor() { }
void InheritableParamAttr::anchor() { }
-void MSInheritanceAttr::anchor() { }
-
#include "clang/AST/AttrImpl.inc"
diff --git a/contrib/llvm/tools/clang/lib/AST/CXXABI.h b/contrib/llvm/tools/clang/lib/AST/CXXABI.h
index 89203f1..12b929b 100644
--- a/contrib/llvm/tools/clang/lib/AST/CXXABI.h
+++ b/contrib/llvm/tools/clang/lib/AST/CXXABI.h
@@ -44,7 +44,6 @@ public:
};
/// Creates an instance of a C++ ABI class.
-CXXABI *CreateARMCXXABI(ASTContext &Ctx);
CXXABI *CreateItaniumCXXABI(ASTContext &Ctx);
CXXABI *CreateMicrosoftCXXABI(ASTContext &Ctx);
}
diff --git a/contrib/llvm/tools/clang/lib/AST/CXXInheritance.cpp b/contrib/llvm/tools/clang/lib/AST/CXXInheritance.cpp
index b51014b..6e80ee7 100644
--- a/contrib/llvm/tools/clang/lib/AST/CXXInheritance.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/CXXInheritance.cpp
@@ -35,16 +35,12 @@ void CXXBasePaths::ComputeDeclsFound() {
std::copy(Decls.begin(), Decls.end(), DeclsFound);
}
-CXXBasePaths::decl_iterator CXXBasePaths::found_decls_begin() {
+CXXBasePaths::decl_range CXXBasePaths::found_decls() {
if (NumDeclsFound == 0)
ComputeDeclsFound();
- return DeclsFound;
-}
-CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() {
- if (NumDeclsFound == 0)
- ComputeDeclsFound();
- return DeclsFound + NumDeclsFound;
+ return decl_range(decl_iterator(DeclsFound),
+ decl_iterator(DeclsFound + NumDeclsFound));
}
/// isAmbiguous - Determines whether the set of paths provided is
@@ -62,7 +58,7 @@ void CXXBasePaths::clear() {
Paths.clear();
ClassSubobjects.clear();
ScratchPath.clear();
- DetectedVirtual = 0;
+ DetectedVirtual = nullptr;
}
/// @brief Swaps the contents of this CXXBasePaths structure with the
@@ -141,9 +137,8 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
const CXXRecordDecl *Record = this;
bool AllMatches = true;
while (true) {
- for (CXXRecordDecl::base_class_const_iterator
- I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
- const RecordType *Ty = I->getType()->getAs<RecordType>();
+ for (const auto &I : Record->bases()) {
+ const RecordType *Ty = I.getType()->getAs<RecordType>();
if (!Ty) {
if (AllowShortCircuit) return false;
AllMatches = false;
@@ -186,14 +181,11 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
AccessSpecifier AccessToHere = ScratchPath.Access;
bool IsFirstStep = ScratchPath.empty();
- for (CXXRecordDecl::base_class_const_iterator BaseSpec = Record->bases_begin(),
- BaseSpecEnd = Record->bases_end();
- BaseSpec != BaseSpecEnd;
- ++BaseSpec) {
+ for (const auto &BaseSpec : Record->bases()) {
// Find the record of the base class subobjects for this type.
- QualType BaseType = Context.getCanonicalType(BaseSpec->getType())
- .getUnqualifiedType();
-
+ QualType BaseType =
+ Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType();
+
// C++ [temp.dep]p3:
// In the definition of a class template or a member of a class template,
// if a base class of the class template depends on a template-parameter,
@@ -208,10 +200,10 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
bool VisitBase = true;
bool SetVirtual = false;
- if (BaseSpec->isVirtual()) {
+ if (BaseSpec.isVirtual()) {
VisitBase = !Subobjects.first;
Subobjects.first = true;
- if (isDetectingVirtual() && DetectedVirtual == 0) {
+ if (isDetectingVirtual() && DetectedVirtual == nullptr) {
// If this is the first virtual we find, remember it. If it turns out
// there is no base path here, we'll reset it later.
DetectedVirtual = BaseType->getAs<RecordType>();
@@ -223,9 +215,9 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
if (isRecordingPaths()) {
// Add this base specifier to the current path.
CXXBasePathElement Element;
- Element.Base = &*BaseSpec;
+ Element.Base = &BaseSpec;
Element.Class = Record;
- if (BaseSpec->isVirtual())
+ if (BaseSpec.isVirtual())
Element.SubobjectNumber = 0;
else
Element.SubobjectNumber = Subobjects.second;
@@ -247,16 +239,16 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
// 3. Otherwise, overall access is determined by the most restrictive
// access in the sequence.
if (IsFirstStep)
- ScratchPath.Access = BaseSpec->getAccessSpecifier();
+ ScratchPath.Access = BaseSpec.getAccessSpecifier();
else
ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere,
- BaseSpec->getAccessSpecifier());
+ BaseSpec.getAccessSpecifier());
}
// Track whether there's a path involving this specific base.
bool FoundPathThroughBase = false;
- if (BaseMatches(BaseSpec, ScratchPath, UserData)) {
+ if (BaseMatches(&BaseSpec, ScratchPath, UserData)) {
// We've found a path that terminates at this base.
FoundPath = FoundPathThroughBase = true;
if (isRecordingPaths()) {
@@ -269,7 +261,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
}
} else if (VisitBase) {
CXXRecordDecl *BaseRecord
- = cast<CXXRecordDecl>(BaseSpec->getType()->castAs<RecordType>()
+ = cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>()
->getDecl());
if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) {
// C++ [class.member.lookup]p2:
@@ -294,7 +286,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
// If we set a virtual earlier, and this isn't a path, forget it again.
if (SetVirtual && !FoundPathThroughBase) {
- DetectedVirtual = 0;
+ DetectedVirtual = nullptr;
}
}
@@ -333,7 +325,7 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
for (CXXBasePath::iterator PE = P->begin(), PEEnd = P->end();
PE != PEEnd && !Hidden; ++PE) {
if (PE->Base->isVirtual()) {
- CXXRecordDecl *VBase = 0;
+ CXXRecordDecl *VBase = nullptr;
if (const RecordType *Record = PE->Base->getType()->getAs<RecordType>())
VBase = cast<CXXRecordDecl>(Record->getDecl());
if (!VBase)
@@ -347,7 +339,7 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
HidingPEnd = Paths.end();
HidingP != HidingPEnd;
++HidingP) {
- CXXRecordDecl *HidingClass = 0;
+ CXXRecordDecl *HidingClass = nullptr;
if (const RecordType *Record
= HidingP->back().Base->getType()->getAs<RecordType>())
HidingClass = cast<CXXRecordDecl>(Record->getDecl());
@@ -501,14 +493,13 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
SubobjectNumber
= ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
- for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
- BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base) {
- if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
+ for (const auto &Base : RD->bases()) {
+ if (const RecordType *RT = Base.getType()->getAs<RecordType>()) {
const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl());
if (!BaseDecl->isPolymorphic())
continue;
- if (Overriders.empty() && !Base->isVirtual()) {
+ if (Overriders.empty() && !Base.isVirtual()) {
// There are no other overriders of virtual member functions,
// so let the base class fill in our overriders for us.
Collect(BaseDecl, false, InVirtualSubobject, Overriders);
@@ -522,7 +513,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
// its base classes) more than once.
CXXFinalOverriderMap ComputedBaseOverriders;
CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders;
- if (Base->isVirtual()) {
+ if (Base.isVirtual()) {
CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl];
BaseOverriders = MyVirtualOverriders;
if (!MyVirtualOverriders) {
@@ -551,10 +542,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
}
}
- for (CXXRecordDecl::method_iterator M = RD->method_begin(),
- MEnd = RD->method_end();
- M != MEnd;
- ++M) {
+ for (auto *M : RD->methods()) {
// We only care about virtual methods.
if (!M->isVirtual())
continue;
@@ -637,7 +625,7 @@ FinalOverriderCollector::~FinalOverriderCollector() {
void
CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
FinalOverriderCollector Collector;
- Collector.Collect(this, false, 0, FinalOverriders);
+ Collector.Collect(this, false, nullptr, FinalOverriders);
// Weed out any final overriders that come from virtual base class
// subobjects that were hidden by other subobjects along any path.
@@ -702,13 +690,12 @@ AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context,
if (Layout.isPrimaryBaseVirtual())
Bases.insert(Layout.getPrimaryBase());
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- assert(!I->getType()->isDependentType() &&
+ for (const auto &I : RD->bases()) {
+ assert(!I.getType()->isDependentType() &&
"Cannot get indirect primary bases for class with dependent bases.");
const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
// Only bases with virtual bases participate in computing the
// indirect primary virtual base classes.
@@ -725,13 +712,12 @@ CXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const {
if (!getNumVBases())
return;
- for (CXXRecordDecl::base_class_const_iterator I = bases_begin(),
- E = bases_end(); I != E; ++I) {
- assert(!I->getType()->isDependentType() &&
+ for (const auto &I : bases()) {
+ assert(!I.getType()->isDependentType() &&
"Cannot get indirect primary bases for class with dependent bases.");
const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
// Only bases with virtual bases participate in computing the
// indirect primary virtual base classes.
diff --git a/contrib/llvm/tools/clang/lib/AST/Comment.cpp b/contrib/llvm/tools/clang/lib/AST/Comment.cpp
index f24a23d..4f43346 100644
--- a/contrib/llvm/tools/clang/lib/AST/Comment.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/Comment.cpp
@@ -136,7 +136,7 @@ void DeclInfo::fill() {
IsInstanceMethod = false;
IsClassMethod = false;
ParamVars = None;
- TemplateParameters = NULL;
+ TemplateParameters = nullptr;
if (!CommentDecl) {
// If there is no declaration, the defaults is our only guess.
@@ -159,7 +159,7 @@ void DeclInfo::fill() {
Kind = FunctionKind;
ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
FD->getNumParams());
- ResultType = FD->getResultType();
+ ReturnType = FD->getReturnType();
unsigned NumLists = FD->getNumTemplateParameterLists();
if (NumLists != 0) {
TemplateKind = TemplateSpecialization;
@@ -180,7 +180,7 @@ void DeclInfo::fill() {
Kind = FunctionKind;
ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(),
MD->param_size());
- ResultType = MD->getResultType();
+ ReturnType = MD->getReturnType();
IsObjCMethod = true;
IsInstanceMethod = MD->isInstanceMethod();
IsClassMethod = !IsInstanceMethod;
@@ -193,7 +193,7 @@ void DeclInfo::fill() {
const FunctionDecl *FD = FTD->getTemplatedDecl();
ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
FD->getNumParams());
- ResultType = FD->getResultType();
+ ReturnType = FD->getReturnType();
TemplateParameters = FTD->getTemplateParameters();
break;
}
@@ -251,6 +251,16 @@ void DeclInfo::fill() {
TL = PointerTL.getPointeeLoc().getUnqualifiedLoc();
continue;
}
+ // Look through reference types.
+ if (ReferenceTypeLoc ReferenceTL = TL.getAs<ReferenceTypeLoc>()) {
+ TL = ReferenceTL.getPointeeLoc().getUnqualifiedLoc();
+ continue;
+ }
+ // Look through adjusted types.
+ if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>()) {
+ TL = ATL.getOriginalLoc();
+ continue;
+ }
if (BlockPointerTypeLoc BlockPointerTL =
TL.getAs<BlockPointerTypeLoc>()) {
TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc();
@@ -261,13 +271,39 @@ void DeclInfo::fill() {
TL = MemberPointerTL.getPointeeLoc().getUnqualifiedLoc();
continue;
}
+ if (ElaboratedTypeLoc ETL = TL.getAs<ElaboratedTypeLoc>()) {
+ TL = ETL.getNamedTypeLoc();
+ continue;
+ }
// Is this a typedef for a function type?
if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
Kind = FunctionKind;
ArrayRef<ParmVarDecl *> Params = FTL.getParams();
ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(),
Params.size());
- ResultType = FTL.getResultLoc().getType();
+ ReturnType = FTL.getReturnLoc().getType();
+ break;
+ }
+ if (TemplateSpecializationTypeLoc STL =
+ TL.getAs<TemplateSpecializationTypeLoc>()) {
+ // If we have a typedef to a template specialization with exactly one
+ // template argument of a function type, this looks like std::function,
+ // boost::function, or other function wrapper. Treat these typedefs as
+ // functions.
+ if (STL.getNumArgs() != 1)
+ break;
+ TemplateArgumentLoc MaybeFunction = STL.getArgLoc(0);
+ if (MaybeFunction.getArgument().getKind() != TemplateArgument::Type)
+ break;
+ TypeSourceInfo *MaybeFunctionTSI = MaybeFunction.getTypeSourceInfo();
+ TypeLoc TL = MaybeFunctionTSI->getTypeLoc().getUnqualifiedLoc();
+ if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
+ Kind = FunctionKind;
+ ArrayRef<ParmVarDecl *> Params = FTL.getParams();
+ ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(),
+ Params.size());
+ ReturnType = FTL.getReturnLoc().getType();
+ }
break;
}
break;
diff --git a/contrib/llvm/tools/clang/lib/AST/CommentCommandTraits.cpp b/contrib/llvm/tools/clang/lib/AST/CommentCommandTraits.cpp
index 01bd12e..a7b07a4 100644
--- a/contrib/llvm/tools/clang/lib/AST/CommentCommandTraits.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/CommentCommandTraits.cpp
@@ -43,47 +43,42 @@ const CommandInfo *CommandTraits::getCommandInfo(unsigned CommandID) const {
return getRegisteredCommandInfo(CommandID);
}
-static void
-HelperTypoCorrectCommandInfo(SmallVectorImpl<const CommandInfo *> &BestCommand,
- StringRef Typo, const CommandInfo *Command) {
- const unsigned MaxEditDistance = 1;
- unsigned BestEditDistance = MaxEditDistance + 1;
- StringRef Name = Command->Name;
-
- unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
- if (MinPossibleEditDistance > 0 &&
- Typo.size() / MinPossibleEditDistance < 1)
- return;
- unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance);
- if (EditDistance > MaxEditDistance)
- return;
- if (EditDistance == BestEditDistance)
- BestCommand.push_back(Command);
- else if (EditDistance < BestEditDistance) {
- BestCommand.clear();
- BestCommand.push_back(Command);
- BestEditDistance = EditDistance;
- }
-}
-
const CommandInfo *
CommandTraits::getTypoCorrectCommandInfo(StringRef Typo) const {
- // single character command impostures, such as \t or \n must not go
+ // Single-character command impostures, such as \t or \n, should not go
// through the fixit logic.
if (Typo.size() <= 1)
- return NULL;
-
+ return nullptr;
+
+ // The maximum edit distance we're prepared to accept.
+ const unsigned MaxEditDistance = 1;
+
+ unsigned BestEditDistance = MaxEditDistance;
SmallVector<const CommandInfo *, 2> BestCommand;
-
- const int NumOfCommands = llvm::array_lengthof(Commands);
- for (int i = 0; i < NumOfCommands; i++)
- HelperTypoCorrectCommandInfo(BestCommand, Typo, &Commands[i]);
-
- for (unsigned i = 0, e = RegisteredCommands.size(); i != e; ++i)
- if (!RegisteredCommands[i]->IsUnknownCommand)
- HelperTypoCorrectCommandInfo(BestCommand, Typo, RegisteredCommands[i]);
-
- return (BestCommand.size() != 1) ? NULL : BestCommand[0];
+
+ auto ConsiderCorrection = [&](const CommandInfo *Command) {
+ StringRef Name = Command->Name;
+
+ unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
+ if (MinPossibleEditDistance <= BestEditDistance) {
+ unsigned EditDistance = Typo.edit_distance(Name, true, BestEditDistance);
+ if (EditDistance < BestEditDistance) {
+ BestEditDistance = EditDistance;
+ BestCommand.clear();
+ }
+ if (EditDistance == BestEditDistance)
+ BestCommand.push_back(Command);
+ }
+ };
+
+ for (const auto &Command : Commands)
+ ConsiderCorrection(&Command);
+
+ for (const auto *Command : RegisteredCommands)
+ if (!Command->IsUnknownCommand)
+ ConsiderCorrection(Command);
+
+ return BestCommand.size() == 1 ? BestCommand[0] : nullptr;
}
CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) {
@@ -118,7 +113,7 @@ const CommandInfo *CommandTraits::getBuiltinCommandInfo(
unsigned CommandID) {
if (CommandID < llvm::array_lengthof(Commands))
return &Commands[CommandID];
- return NULL;
+ return nullptr;
}
const CommandInfo *CommandTraits::getRegisteredCommandInfo(
@@ -127,7 +122,7 @@ const CommandInfo *CommandTraits::getRegisteredCommandInfo(
if (RegisteredCommands[i]->Name == Name)
return RegisteredCommands[i];
}
- return NULL;
+ return nullptr;
}
const CommandInfo *CommandTraits::getRegisteredCommandInfo(
diff --git a/contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp b/contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp
index 01ed3ce..792a832 100644
--- a/contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/CommentLexer.cpp
@@ -268,6 +268,19 @@ const char *findCCommentEnd(const char *BufferPtr, const char *BufferEnd) {
} // unnamed namespace
+void Lexer::formTokenWithChars(Token &Result, const char *TokEnd,
+ tok::TokenKind Kind) {
+ const unsigned TokLen = TokEnd - BufferPtr;
+ Result.setLocation(getSourceLocation(BufferPtr));
+ Result.setKind(Kind);
+ Result.setLength(TokLen);
+#ifndef NDEBUG
+ Result.TextPtr = "<UNSET>";
+ Result.IntVal = 7;
+#endif
+ BufferPtr = TokEnd;
+}
+
void Lexer::lexCommentText(Token &T) {
assert(CommentState == LCS_InsideBCPLComment ||
CommentState == LCS_InsideCComment);
diff --git a/contrib/llvm/tools/clang/lib/AST/CommentParser.cpp b/contrib/llvm/tools/clang/lib/AST/CommentParser.cpp
index 03e0101..cb37ec3 100644
--- a/contrib/llvm/tools/clang/lib/AST/CommentParser.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/CommentParser.cpp
@@ -311,9 +311,9 @@ void Parser::parseBlockCommandArgs(BlockCommandComment *BC,
BlockCommandComment *Parser::parseBlockCommand() {
assert(Tok.is(tok::backslash_command) || Tok.is(tok::at_command));
- ParamCommandComment *PC = 0;
- TParamCommandComment *TPC = 0;
- BlockCommandComment *BC = 0;
+ ParamCommandComment *PC = nullptr;
+ TParamCommandComment *TPC = nullptr;
+ BlockCommandComment *BC = nullptr;
const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
CommandMarkerKind CommandMarker =
Tok.is(tok::backslash_command) ? CMK_Backslash : CMK_At;
diff --git a/contrib/llvm/tools/clang/lib/AST/CommentSema.cpp b/contrib/llvm/tools/clang/lib/AST/CommentSema.cpp
index 1c6222f..12823c3 100644
--- a/contrib/llvm/tools/clang/lib/AST/CommentSema.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/CommentSema.cpp
@@ -29,7 +29,8 @@ Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
DiagnosticsEngine &Diags, CommandTraits &Traits,
const Preprocessor *PP) :
Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits),
- PP(PP), ThisDeclInfo(NULL), BriefCommand(NULL), HeaderfileCommand(NULL) {
+ PP(PP), ThisDeclInfo(nullptr), BriefCommand(nullptr),
+ HeaderfileCommand(nullptr) {
}
void Sema::setDecl(const Decl *D) {
@@ -68,8 +69,12 @@ void Sema::actOnBlockCommandFinish(BlockCommandComment *Command,
Command->setParagraph(Paragraph);
checkBlockCommandEmptyParagraph(Command);
checkBlockCommandDuplicate(Command);
- checkReturnsCommand(Command);
- checkDeprecatedCommand(Command);
+ if (ThisDeclInfo) {
+ // These checks only make sense if the comment is attached to a
+ // declaration.
+ checkReturnsCommand(Command);
+ checkDeprecatedCommand(Command);
+ }
}
ParamCommandComment *Sema::actOnParamCommandStart(
@@ -122,7 +127,7 @@ void Sema::checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment) {
<< (DiagSelect-1) << (DiagSelect-1)
<< Comment->getSourceRange();
}
-
+
void Sema::checkContainerDeclVerbatimLine(const BlockCommandComment *Comment) {
const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID());
if (!Info->IsRecordLikeDeclarationCommand)
@@ -478,6 +483,7 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin,
if (isHTMLEndTagForbidden(TagName)) {
Diag(HET->getLocation(), diag::warn_doc_html_end_forbidden)
<< TagName << HET->getSourceRange();
+ HET->setIsMalformed();
return HET;
}
@@ -493,14 +499,19 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin,
if (!FoundOpen) {
Diag(HET->getLocation(), diag::warn_doc_html_end_unbalanced)
<< HET->getSourceRange();
+ HET->setIsMalformed();
return HET;
}
while (!HTMLOpenTags.empty()) {
- const HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val();
+ HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val();
StringRef LastNotClosedTagName = HST->getTagName();
- if (LastNotClosedTagName == TagName)
+ if (LastNotClosedTagName == TagName) {
+ // If the start tag is malformed, end tag is malformed as well.
+ if (HST->isMalformed())
+ HET->setIsMalformed();
break;
+ }
if (isHTMLEndTagOptional(LastNotClosedTagName))
continue;
@@ -514,16 +525,18 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin,
HET->getLocation(),
&CloseLineInvalid);
- if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine)
+ if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine) {
Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch)
<< HST->getTagName() << HET->getTagName()
<< HST->getSourceRange() << HET->getSourceRange();
- else {
+ HST->setIsMalformed();
+ } else {
Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch)
<< HST->getTagName() << HET->getTagName()
<< HST->getSourceRange();
Diag(HET->getLocation(), diag::note_doc_html_end_tag)
<< HET->getSourceRange();
+ HST->setIsMalformed();
}
}
@@ -534,6 +547,18 @@ FullComment *Sema::actOnFullComment(
ArrayRef<BlockContentComment *> Blocks) {
FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo);
resolveParamCommandIndexes(FC);
+
+ // Complain about HTML tags that are not closed.
+ while (!HTMLOpenTags.empty()) {
+ HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val();
+ if (isHTMLEndTagOptional(HST->getTagName()))
+ continue;
+
+ Diag(HST->getLocation(), diag::warn_doc_html_missing_end_tag)
+ << HST->getTagName() << HST->getSourceRange();
+ HST->setIsMalformed();
+ }
+
return FC;
}
@@ -558,8 +583,11 @@ void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) {
void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
if (!Traits.getCommandInfo(Command->getCommandID())->IsReturnsCommand)
return;
+
+ assert(ThisDeclInfo && "should not call this check on a bare comment");
+
if (isFunctionDecl()) {
- if (ThisDeclInfo->ResultType->isVoidType()) {
+ if (ThisDeclInfo->ReturnType->isVoidType()) {
unsigned DiagKind;
switch (ThisDeclInfo->CommentDecl->getKind()) {
default:
@@ -586,7 +614,7 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
}
else if (isObjCPropertyDecl())
return;
-
+
Diag(Command->getLocation(),
diag::warn_doc_returns_not_attached_to_a_function_decl)
<< Command->getCommandMarker()
@@ -596,7 +624,7 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
void Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) {
const CommandInfo *Info = Traits.getCommandInfo(Command->getCommandID());
- const BlockCommandComment *PrevCommand = NULL;
+ const BlockCommandComment *PrevCommand = nullptr;
if (Info->IsBriefCommand) {
if (!BriefCommand) {
BriefCommand = Command;
@@ -636,6 +664,8 @@ void Sema::checkDeprecatedCommand(const BlockCommandComment *Command) {
if (!Traits.getCommandInfo(Command->getCommandID())->IsDeprecatedCommand)
return;
+ assert(ThisDeclInfo && "should not call this check on a bare comment");
+
const Decl *D = ThisDeclInfo->CommentDecl;
if (!D)
return;
@@ -694,7 +724,7 @@ void Sema::resolveParamCommandIndexes(const FullComment *FC) {
SmallVector<ParamCommandComment *, 8> ParamVarDocs;
ArrayRef<const ParmVarDecl *> ParamVars = getParamVars();
- ParamVarDocs.resize(ParamVars.size(), NULL);
+ ParamVarDocs.resize(ParamVars.size(), nullptr);
// First pass over all \\param commands: resolve all parameter names.
for (Comment::child_iterator I = FC->child_begin(), E = FC->child_end();
@@ -783,11 +813,14 @@ bool Sema::isAnyFunctionDecl() {
}
bool Sema::isFunctionOrMethodVariadic() {
- if (!isAnyFunctionDecl() && !isObjCMethodDecl())
+ if (!isAnyFunctionDecl() && !isObjCMethodDecl() && !isFunctionTemplateDecl())
return false;
if (const FunctionDecl *FD =
dyn_cast<FunctionDecl>(ThisDeclInfo->CurrentDecl))
return FD->isVariadic();
+ if (const FunctionTemplateDecl *FTD =
+ dyn_cast<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl))
+ return FTD->getTemplatedDecl()->isVariadic();
if (const ObjCMethodDecl *MD =
dyn_cast<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl))
return MD->isVariadic();
@@ -812,7 +845,7 @@ bool Sema::isFunctionPointerVarDecl() {
}
return false;
}
-
+
bool Sema::isObjCPropertyDecl() {
if (!ThisDeclInfo)
return false;
@@ -834,8 +867,8 @@ bool Sema::isRecordLikeDecl() {
return false;
if (!ThisDeclInfo->IsFilled)
inspectThisDecl();
- return isUnionDecl() || isClassOrStructDecl()
- || isObjCInterfaceDecl() || isObjCProtocolDecl();
+ return isUnionDecl() || isClassOrStructDecl() || isObjCInterfaceDecl() ||
+ isObjCProtocolDecl();
}
bool Sema::isUnionDecl() {
@@ -848,7 +881,7 @@ bool Sema::isUnionDecl() {
return RD->isUnion();
return false;
}
-
+
bool Sema::isClassOrStructDecl() {
if (!ThisDeclInfo)
return false;
@@ -858,7 +891,7 @@ bool Sema::isClassOrStructDecl() {
isa<RecordDecl>(ThisDeclInfo->CurrentDecl) &&
!isUnionDecl();
}
-
+
bool Sema::isClassTemplateDecl() {
if (!ThisDeclInfo)
return false;
@@ -874,7 +907,7 @@ bool Sema::isFunctionTemplateDecl() {
if (!ThisDeclInfo->IsFilled)
inspectThisDecl();
return ThisDeclInfo->CurrentDecl &&
- (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl));
+ (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl));
}
bool Sema::isObjCInterfaceDecl() {
@@ -885,7 +918,7 @@ bool Sema::isObjCInterfaceDecl() {
return ThisDeclInfo->CurrentDecl &&
isa<ObjCInterfaceDecl>(ThisDeclInfo->CurrentDecl);
}
-
+
bool Sema::isObjCProtocolDecl() {
if (!ThisDeclInfo)
return false;
@@ -894,7 +927,7 @@ bool Sema::isObjCProtocolDecl() {
return ThisDeclInfo->CurrentDecl &&
isa<ObjCProtocolDecl>(ThisDeclInfo->CurrentDecl);
}
-
+
ArrayRef<const ParmVarDecl *> Sema::getParamVars() {
if (!ThisDeclInfo->IsFilled)
inspectThisDecl();
@@ -930,7 +963,7 @@ class SimpleTypoCorrector {
public:
SimpleTypoCorrector(StringRef Typo) :
Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3),
- BestDecl(NULL), BestEditDistance(MaxEditDistance + 1),
+ BestDecl(nullptr), BestEditDistance(MaxEditDistance + 1),
BestIndex(0), NextIndex(0)
{ }
@@ -938,7 +971,7 @@ public:
const NamedDecl *getBestDecl() const {
if (BestEditDistance > MaxEditDistance)
- return NULL;
+ return nullptr;
return BestDecl;
}
diff --git a/contrib/llvm/tools/clang/lib/AST/Decl.cpp b/contrib/llvm/tools/clang/lib/AST/Decl.cpp
index 6bd9858..7448de2 100644
--- a/contrib/llvm/tools/clang/lib/AST/Decl.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/Decl.cpp
@@ -13,6 +13,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
@@ -29,7 +30,6 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/type_traits.h"
#include <algorithm>
using namespace clang;
@@ -158,8 +158,7 @@ static bool usesTypeVisibility(const NamedDecl *D) {
/// Does the given declaration have member specialization information,
/// and if so, is it an explicit specialization?
template <class T> static typename
-llvm::enable_if_c<!llvm::is_base_of<RedeclarableTemplateDecl, T>::value,
- bool>::type
+std::enable_if<!std::is_base_of<RedeclarableTemplateDecl, T>::value, bool>::type
isExplicitMemberSpecialization(const T *D) {
if (const MemberSpecializationInfo *member =
D->getMemberSpecializationInfo()) {
@@ -209,11 +208,8 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D,
// If we're on Mac OS X, an 'availability' for Mac OS X attribute
// implies visibility(default).
if (D->getASTContext().getTargetInfo().getTriple().isOSDarwin()) {
- for (specific_attr_iterator<AvailabilityAttr>
- A = D->specific_attr_begin<AvailabilityAttr>(),
- AEnd = D->specific_attr_end<AvailabilityAttr>();
- A != AEnd; ++A)
- if ((*A)->getPlatform()->getName().equals("macosx"))
+ for (const auto *A : D->specific_attrs<AvailabilityAttr>())
+ if (A->getPlatform()->getName().equals("macosx"))
return DefaultVisibility;
}
@@ -231,23 +227,21 @@ getLVForType(const Type &T, LVComputationKind computation) {
/// template parameter list. For visibility purposes, template
/// parameters are part of the signature of a template.
static LinkageInfo
-getLVForTemplateParameterList(const TemplateParameterList *params,
+getLVForTemplateParameterList(const TemplateParameterList *Params,
LVComputationKind computation) {
LinkageInfo LV;
- for (TemplateParameterList::const_iterator P = params->begin(),
- PEnd = params->end();
- P != PEnd; ++P) {
-
+ for (const NamedDecl *P : *Params) {
// Template type parameters are the most common and never
// contribute to visibility, pack or not.
- if (isa<TemplateTypeParmDecl>(*P))
+ if (isa<TemplateTypeParmDecl>(P))
continue;
// Non-type template parameters can be restricted by the value type, e.g.
// template <enum X> class A { ... };
// We have to be careful here, though, because we can be dealing with
// dependent types.
- if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+ if (const NonTypeTemplateParmDecl *NTTP =
+ dyn_cast<NonTypeTemplateParmDecl>(P)) {
// Handle the non-pack case first.
if (!NTTP->isExpandedParameterPack()) {
if (!NTTP->getType()->isDependentType()) {
@@ -267,7 +261,7 @@ getLVForTemplateParameterList(const TemplateParameterList *params,
// Template template parameters can be restricted by their
// template parameters, recursively.
- TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
+ const TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(P);
// Handle the non-pack case first.
if (!TTP->isExpandedParameterPack()) {
@@ -292,7 +286,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D,
LVComputationKind computation);
static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
- const Decl *Ret = NULL;
+ const Decl *Ret = nullptr;
const DeclContext *DC = D->getDeclContext();
while (DC->getDeclKind() != Decl::TranslationUnit) {
if (isa<FunctionDecl>(DC) || isa<BlockDecl>(DC))
@@ -307,43 +301,41 @@ static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
///
/// Note that we don't take an LVComputationKind because we always
/// want to honor the visibility of template arguments in the same way.
-static LinkageInfo
-getLVForTemplateArgumentList(ArrayRef<TemplateArgument> args,
- LVComputationKind computation) {
+static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
+ LVComputationKind computation) {
LinkageInfo LV;
- for (unsigned i = 0, e = args.size(); i != e; ++i) {
- const TemplateArgument &arg = args[i];
- switch (arg.getKind()) {
+ for (const TemplateArgument &Arg : Args) {
+ switch (Arg.getKind()) {
case TemplateArgument::Null:
case TemplateArgument::Integral:
case TemplateArgument::Expression:
continue;
case TemplateArgument::Type:
- LV.merge(getLVForType(*arg.getAsType(), computation));
+ LV.merge(getLVForType(*Arg.getAsType(), computation));
continue;
case TemplateArgument::Declaration:
- if (NamedDecl *ND = dyn_cast<NamedDecl>(arg.getAsDecl())) {
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl())) {
assert(!usesTypeVisibility(ND));
LV.merge(getLVForDecl(ND, computation));
}
continue;
case TemplateArgument::NullPtr:
- LV.merge(arg.getNullPtrType()->getLinkageAndVisibility());
+ LV.merge(Arg.getNullPtrType()->getLinkageAndVisibility());
continue;
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
- if (TemplateDecl *Template
- = arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl())
+ if (TemplateDecl *Template =
+ Arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl())
LV.merge(getLVForDecl(Template, computation));
continue;
case TemplateArgument::Pack:
- LV.merge(getLVForTemplateArgumentList(arg.getPackAsArray(), computation));
+ LV.merge(getLVForTemplateArgumentList(Arg.getPackAsArray(), computation));
continue;
}
llvm_unreachable("bad template argument kind");
@@ -479,6 +471,58 @@ static void mergeTemplateLV(LinkageInfo &LV,
LV.mergeExternalVisibility(argsLV);
}
+/// Should we consider visibility associated with the template
+/// arguments and parameters of the given variable template
+/// specialization? As usual, follow class template specialization
+/// logic up to initialization.
+static bool shouldConsiderTemplateVisibility(
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
+ // Include visibility from the template parameters and arguments
+ // only if this is not an explicit instantiation or specialization
+ // with direct explicit visibility (and note that implicit
+ // instantiations won't have a direct attribute).
+ if (!spec->isExplicitInstantiationOrSpecialization())
+ return true;
+
+ // An explicit variable specialization is an independent, top-level
+ // declaration. As such, if it has an explicit visibility attribute,
+ // that must directly express the user's intent, and we should honor
+ // it.
+ if (spec->isExplicitSpecialization() &&
+ hasExplicitVisibilityAlready(computation))
+ return false;
+
+ return !hasDirectVisibilityAttribute(spec, computation);
+}
+
+/// Merge in template-related linkage and visibility for the given
+/// variable template specialization. As usual, follow class template
+/// specialization logic up to initialization.
+static void mergeTemplateLV(LinkageInfo &LV,
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
+ bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
+
+ // Merge information from the template parameters, but ignore
+ // visibility if we're only considering template arguments.
+
+ VarTemplateDecl *temp = spec->getSpecializedTemplate();
+ LinkageInfo tempLV =
+ getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
+ LV.mergeMaybeWithVisibility(tempLV,
+ considerVisibility && !hasExplicitVisibilityAlready(computation));
+
+ // Merge information from the template arguments. We ignore
+ // template-argument visibility if we've got an explicit
+ // instantiation with a visibility attribute.
+ const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
+ LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
+ if (considerVisibility)
+ LV.mergeVisibility(argsLV);
+ LV.mergeExternalVisibility(argsLV);
+}
+
static bool useInlineVisibilityHidden(const NamedDecl *D) {
// FIXME: we should warn if -fvisibility-inlines-hidden is used with c.
const LangOptions &Opts = D->getASTContext().getLangOpts();
@@ -498,7 +542,7 @@ static bool useInlineVisibilityHidden(const NamedDecl *D) {
TSK = MSI->getTemplateSpecializationKind();
}
- const FunctionDecl *Def = 0;
+ const FunctionDecl *Def = nullptr;
// InlineVisibilityHidden only applies to definitions, and
// isInlined() only gives meaningful answers on definitions
// anyway.
@@ -512,9 +556,9 @@ template <typename T> static bool isFirstInExternCContext(T *D) {
return First->isInExternCContext();
}
-static bool isSingleLineExternC(const Decl &D) {
+static bool isSingleLineLanguageLinkage(const Decl &D) {
if (const LinkageSpecDecl *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext()))
- if (SD->getLanguage() == LinkageSpecDecl::lang_c && !SD->hasBraces())
+ if (!SD->hasBraces())
return true;
return false;
}
@@ -548,7 +592,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
if (Var->getStorageClass() != SC_Extern &&
Var->getStorageClass() != SC_PrivateExtern &&
- !isSingleLineExternC(*Var))
+ !isSingleLineLanguageLinkage(*Var))
return LinkageInfo::internal();
}
@@ -561,16 +605,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
if (PrevVar->getStorageClass() == SC_Static)
return LinkageInfo::internal();
}
- } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
+ } else if (const FunctionDecl *Function = D->getAsFunction()) {
// C++ [temp]p4:
// A non-member function template can have internal linkage; any
// other template name shall have external linkage.
- const FunctionDecl *Function = 0;
- if (const FunctionTemplateDecl *FunTmpl
- = dyn_cast<FunctionTemplateDecl>(D))
- Function = FunTmpl->getTemplatedDecl();
- else
- Function = cast<FunctionDecl>(D);
// Explicitly declared static.
if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
@@ -676,6 +714,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// C99 6.2.2p4 and propagating the visibility attribute, so we don't have
// to do it here.
+ // As per function and class template specializations (below),
+ // consider LV for the template and template arguments. We're at file
+ // scope, so we do not need to worry about nested specializations.
+ if (const VarTemplateSpecializationDecl *spec
+ = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+ mergeTemplateLV(LV, spec, computation);
+ }
+
// - a function, unless it has internal linkage; or
} else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// In theory, we can modify the function's LV by the LV of its
@@ -782,11 +828,18 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// really have linkage, but it's convenient to say they do for the
// purposes of calculating linkage of pointer-to-data-member
// template arguments.
+ //
+ // Templates also don't officially have linkage, but since we ignore
+ // the C++ standard and look at template arguments when determining
+ // linkage and visibility of a template specialization, we might hit
+ // a template template argument that way. If we do, we need to
+ // consider its linkage.
if (!(isa<CXXMethodDecl>(D) ||
isa<VarDecl>(D) ||
isa<FieldDecl>(D) ||
isa<IndirectFieldDecl>(D) ||
- isa<TagDecl>(D)))
+ isa<TagDecl>(D) ||
+ isa<TemplateDecl>(D)))
return LinkageInfo::none();
LinkageInfo LV;
@@ -825,7 +878,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// we need to completely ignore the visibility from it.
// Specifically, if this decl exists and has an explicit attribute.
- const NamedDecl *explicitSpecSuppressor = 0;
+ const NamedDecl *explicitSpecSuppressor = nullptr;
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
// If the type of the function uses a type with unique-external
@@ -876,6 +929,10 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// Static data members.
} else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarTemplateSpecializationDecl *spec
+ = dyn_cast<VarTemplateSpecializationDecl>(VD))
+ mergeTemplateLV(LV, spec, computation);
+
// Modify the variable's linkage by its type, but ignore the
// type's visibility unless it's a definition.
LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
@@ -989,6 +1046,10 @@ getExplicitVisibilityAux(const NamedDecl *ND,
return getVisibilityOf(InstantiatedFrom, kind);
}
+ if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Var))
+ return getVisibilityOf(VTSD->getSpecializedTemplate()->getTemplatedDecl(),
+ kind);
+
return None;
}
// Also handle function template specializations.
@@ -1242,16 +1303,13 @@ public:
// We have just computed the linkage for this decl. By induction we know
// that all other computed linkages match, check that the one we just
- // computed
- // also does.
- NamedDecl *Old = NULL;
- for (NamedDecl::redecl_iterator I = D->redecls_begin(),
- E = D->redecls_end();
- I != E; ++I) {
- NamedDecl *T = cast<NamedDecl>(*I);
+ // computed also does.
+ NamedDecl *Old = nullptr;
+ for (auto I : D->redecls()) {
+ NamedDecl *T = cast<NamedDecl>(I);
if (T == D)
continue;
- if (T->hasCachedLinkage()) {
+ if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
Old = T;
break;
}
@@ -1270,13 +1328,9 @@ static LinkageInfo getLVForDecl(const NamedDecl *D,
}
std::string NamedDecl::getQualifiedNameAsString() const {
- return getQualifiedNameAsString(getASTContext().getPrintingPolicy());
-}
-
-std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
std::string QualName;
llvm::raw_string_ostream OS(QualName);
- printQualifiedName(OS, P);
+ printQualifiedName(OS, getASTContext().getPrintingPolicy());
return OS.str();
}
@@ -1313,17 +1367,20 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
TemplateArgs.size(),
P);
} else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
+ if (P.SuppressUnwrittenScope &&
+ (ND->isAnonymousNamespace() || ND->isInline()))
+ continue;
if (ND->isAnonymousNamespace())
- OS << "<anonymous namespace>";
+ OS << "(anonymous namespace)";
else
OS << *ND;
} else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) {
if (!RD->getIdentifier())
- OS << "<anonymous " << RD->getKindName() << '>';
+ OS << "(anonymous " << RD->getKindName() << ')';
else
OS << *RD;
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
- const FunctionProtoType *FT = 0;
+ const FunctionProtoType *FT = nullptr;
if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(FD->getType()->castAs<FunctionType>());
@@ -1352,7 +1409,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
if (getDeclName())
OS << *this;
else
- OS << "<anonymous>";
+ OS << "(anonymous)";
}
void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
@@ -1392,6 +1449,7 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
if (isa<ObjCMethodDecl>(this))
return false;
+ // FIXME: Is this correct if one of the decls comes from an inline namespace?
if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
return true;
@@ -1418,14 +1476,19 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
// A typedef of an Objective-C class type can replace an Objective-C class
// declaration or definition, and vice versa.
+ // FIXME: Is this correct if one of the decls comes from an inline namespace?
if ((isa<TypedefNameDecl>(this) && isa<ObjCInterfaceDecl>(OldD)) ||
(isa<ObjCInterfaceDecl>(this) && isa<TypedefNameDecl>(OldD)))
return true;
-
+
// For non-function declarations, if the declarations are of the
- // same kind then this must be a redeclaration, or semantic analysis
- // would not have given us the new declaration.
- return this->getKind() == OldD->getKind();
+ // same kind and have the same parent then this must be a redeclaration,
+ // or semantic analysis would not have given us the new declaration.
+ // Note that inline namespaces can give us two declarations with the same
+ // name and kind in the same scope but different contexts.
+ return this->getKind() == OldD->getKind() &&
+ this->getDeclContext()->getRedeclContext()->Equals(
+ OldD->getDeclContext()->getRedeclContext());
}
bool NamedDecl::hasLinkage() const {
@@ -1453,11 +1516,9 @@ bool NamedDecl::isCXXInstanceMember() const {
if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<MSPropertyDecl>(D))
return true;
- if (isa<CXXMethodDecl>(D))
- return cast<CXXMethodDecl>(D)->isInstance();
- if (isa<FunctionTemplateDecl>(D))
- return cast<CXXMethodDecl>(cast<FunctionTemplateDecl>(D)
- ->getTemplatedDecl())->isInstance();
+ if (const CXXMethodDecl *MD =
+ dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()))
+ return MD->isInstance();
return false;
}
@@ -1574,7 +1635,9 @@ bool typeIsPostfix(clang::QualType QT) {
SourceRange DeclaratorDecl::getSourceRange() const {
SourceLocation RangeEnd = getLocation();
if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
- if (typeIsPostfix(TInfo->getType()))
+ // If the declaration has no name or the type extends past the name take the
+ // end location of the type.
+ if (!getDeclName() || typeIsPostfix(TInfo->getType()))
RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd();
}
return SourceRange(getOuterLocStart(), RangeEnd);
@@ -1584,13 +1647,13 @@ void
QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
unsigned NumTPLists,
TemplateParameterList **TPLists) {
- assert((NumTPLists == 0 || TPLists != 0) &&
+ assert((NumTPLists == 0 || TPLists != nullptr) &&
"Empty array of template parameters with positive size!");
// Free previous template parameters (if any).
if (NumTemplParamLists > 0) {
Context.Deallocate(TemplParamLists);
- TemplParamLists = 0;
+ TemplParamLists = nullptr;
NumTemplParamLists = 0;
}
// Set info on matched template parameter lists (if any).
@@ -1620,12 +1683,16 @@ const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
llvm_unreachable("Invalid storage class");
}
-VarDecl::VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC)
- : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() {
- assert(sizeof(VarDeclBitfields) <= sizeof(unsigned));
- assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned));
+VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+ StorageClass SC)
+ : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
+ redeclarable_base(C), Init() {
+ static_assert(sizeof(VarDeclBitfields) <= sizeof(unsigned),
+ "VarDeclBitfields too large!");
+ static_assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned),
+ "ParmVarDeclBitfields too large!");
AllBits = 0;
VarDeclBits.SClass = SC;
// Everything else is implicitly initialized to false.
@@ -1635,13 +1702,13 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartL, SourceLocation IdL,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
StorageClass S) {
- return new (C) VarDecl(Var, DC, StartL, IdL, Id, T, TInfo, S);
+ return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S);
}
VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarDecl));
- return new (Mem) VarDecl(Var, 0, SourceLocation(), SourceLocation(), 0,
- QualType(), 0, SC_None);
+ return new (C, ID)
+ VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
+ QualType(), nullptr, SC_None);
}
void VarDecl::setStorageClass(StorageClass SC) {
@@ -1649,6 +1716,21 @@ void VarDecl::setStorageClass(StorageClass SC) {
VarDeclBits.SClass = SC;
}
+VarDecl::TLSKind VarDecl::getTLSKind() const {
+ switch (VarDeclBits.TSCSpec) {
+ case TSCS_unspecified:
+ if (hasAttr<ThreadAttr>())
+ return TLS_Static;
+ return TLS_None;
+ case TSCS___thread: // Fall through.
+ case TSCS__Thread_local:
+ return TLS_Static;
+ case TSCS_thread_local:
+ return TLS_Dynamic;
+ }
+ llvm_unreachable("Unknown thread storage class specifier!");
+}
+
SourceRange VarDecl::getSourceRange() const {
if (const Expr *Init = getInit()) {
SourceLocation InitEnd = Init->getLocEnd();
@@ -1661,7 +1743,7 @@ SourceRange VarDecl::getSourceRange() const {
}
template<typename T>
-static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
+static LanguageLinkage getDeclLanguageLinkage(const T &D) {
// C++ [dcl.link]p1: All function types, function names with external linkage,
// and variable names with external linkage have a language linkage.
if (!D.hasExternalFormalLinkage())
@@ -1689,7 +1771,7 @@ static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
}
template<typename T>
-static bool isExternCTemplate(const T &D) {
+static bool isDeclExternC(const T &D) {
// Since the context is ignored for class members, they can only have C++
// language linkage or no language linkage.
const DeclContext *DC = D.getDeclContext();
@@ -1702,11 +1784,11 @@ static bool isExternCTemplate(const T &D) {
}
LanguageLinkage VarDecl::getLanguageLinkage() const {
- return getLanguageLinkageTemplate(*this);
+ return getDeclLanguageLinkage(*this);
}
bool VarDecl::isExternC() const {
- return isExternCTemplate(*this);
+ return isDeclExternC(*this);
}
bool VarDecl::isInExternCContext() const {
@@ -1775,7 +1857,7 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition(
// A declaration directly contained in a linkage-specification is treated
// as if it contains the extern specifier for the purpose of determining
// the linkage of the declared name and whether it is a definition.
- if (isSingleLineExternC(*this))
+ if (isSingleLineLanguageLinkage(*this))
return DeclarationOnly;
// C99 6.9.2p2:
@@ -1794,38 +1876,35 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition(
VarDecl *VarDecl::getActingDefinition() {
DefinitionKind Kind = isThisDeclarationADefinition();
if (Kind != TentativeDefinition)
- return 0;
+ return nullptr;
- VarDecl *LastTentative = 0;
+ VarDecl *LastTentative = nullptr;
VarDecl *First = getFirstDecl();
- for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
- I != E; ++I) {
- Kind = (*I)->isThisDeclarationADefinition();
+ for (auto I : First->redecls()) {
+ Kind = I->isThisDeclarationADefinition();
if (Kind == Definition)
- return 0;
+ return nullptr;
else if (Kind == TentativeDefinition)
- LastTentative = *I;
+ LastTentative = I;
}
return LastTentative;
}
VarDecl *VarDecl::getDefinition(ASTContext &C) {
VarDecl *First = getFirstDecl();
- for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
- I != E; ++I) {
- if ((*I)->isThisDeclarationADefinition(C) == Definition)
- return *I;
+ for (auto I : First->redecls()) {
+ if (I->isThisDeclarationADefinition(C) == Definition)
+ return I;
}
- return 0;
+ return nullptr;
}
VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const {
DefinitionKind Kind = DeclarationOnly;
const VarDecl *First = getFirstDecl();
- for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
- I != E; ++I) {
- Kind = std::max(Kind, (*I)->isThisDeclarationADefinition(C));
+ for (auto I : First->redecls()) {
+ Kind = std::max(Kind, I->isThisDeclarationADefinition(C));
if (Kind == Definition)
break;
}
@@ -1834,15 +1913,13 @@ VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const {
}
const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const {
- redecl_iterator I = redecls_begin(), E = redecls_end();
- while (I != E && !I->getInit())
- ++I;
-
- if (I != E) {
- D = *I;
- return I->getInit();
+ for (auto I : redecls()) {
+ if (auto Expr = I->getInit()) {
+ D = I;
+ return Expr;
+ }
}
- return 0;
+ return nullptr;
}
bool VarDecl::isOutOfLine() const {
@@ -1863,15 +1940,14 @@ bool VarDecl::isOutOfLine() const {
VarDecl *VarDecl::getOutOfLineDefinition() {
if (!isStaticDataMember())
- return 0;
-
- for (VarDecl::redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
- RD != RDEnd; ++RD) {
+ return nullptr;
+
+ for (auto RD : redecls()) {
if (RD->getLexicalDeclContext()->isFileContext())
- return *RD;
+ return RD;
}
-
- return 0;
+
+ return nullptr;
}
void VarDecl::setInit(Expr *I) {
@@ -1948,7 +2024,7 @@ APValue *VarDecl::evaluateValue(
// first time it is evaluated. FIXME: The notes won't always be emitted the
// first time we try evaluation, so might not be produced at all.
if (Eval->WasEvaluated)
- return Eval->Evaluated.isUninit() ? 0 : &Eval->Evaluated;
+ return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated;
const Expr *Init = cast<Expr>(Eval->Value);
assert(!Init->isValueDependent());
@@ -1957,7 +2033,7 @@ APValue *VarDecl::evaluateValue(
// FIXME: Produce a diagnostic for self-initialization.
Eval->CheckedICE = true;
Eval->IsICE = false;
- return 0;
+ return nullptr;
}
Eval->IsEvaluating = true;
@@ -1983,7 +2059,7 @@ APValue *VarDecl::evaluateValue(
Eval->IsICE = Result && Notes.empty();
}
- return Result ? &Eval->Evaluated : 0;
+ return Result ? &Eval->Evaluated : nullptr;
}
bool VarDecl::checkInitIsICE() const {
@@ -2025,8 +2101,8 @@ bool VarDecl::checkInitIsICE() const {
VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
return cast<VarDecl>(MSI->getInstantiatedFrom());
-
- return 0;
+
+ return nullptr;
}
TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
@@ -2066,7 +2142,7 @@ MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const {
// return getASTContext().getInstantiatedFromStaticDataMember(this);
return getASTContext().getTemplateOrSpecializationInfo(this)
.dyn_cast<MemberSpecializationInfo *>();
- return 0;
+ return nullptr;
}
void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
@@ -2108,8 +2184,8 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, Expr *DefArg) {
- return new (C) ParmVarDecl(ParmVar, DC, StartLoc, IdLoc, Id, T, TInfo,
- S, DefArg);
+ return new (C, DC) ParmVarDecl(ParmVar, C, DC, StartLoc, IdLoc, Id, T, TInfo,
+ S, DefArg);
}
QualType ParmVarDecl::getOriginalType() const {
@@ -2121,9 +2197,9 @@ QualType ParmVarDecl::getOriginalType() const {
}
ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ParmVarDecl));
- return new (Mem) ParmVarDecl(ParmVar, 0, SourceLocation(), SourceLocation(),
- 0, QualType(), 0, SC_None, 0);
+ return new (C, ID)
+ ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(),
+ nullptr, QualType(), nullptr, SC_None, nullptr);
}
SourceRange ParmVarDecl::getSourceRange() const {
@@ -2196,9 +2272,9 @@ bool FunctionDecl::isVariadic() const {
}
bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
- for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+ for (auto I : redecls()) {
if (I->Body || I->IsLateTemplateParsed) {
- Definition = *I;
+ Definition = I;
return true;
}
}
@@ -2221,10 +2297,10 @@ bool FunctionDecl::hasTrivialBody() const
}
bool FunctionDecl::isDefined(const FunctionDecl *&Definition) const {
- for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+ for (auto I : redecls()) {
if (I->IsDeleted || I->IsDefaulted || I->Body || I->IsLateTemplateParsed ||
I->hasAttr<AliasAttr>()) {
- Definition = I->IsDeleted ? I->getCanonicalDecl() : *I;
+ Definition = I->IsDeleted ? I->getCanonicalDecl() : I;
return true;
}
}
@@ -2234,12 +2310,12 @@ bool FunctionDecl::isDefined(const FunctionDecl *&Definition) const {
Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
if (!hasBody(Definition))
- return 0;
+ return nullptr;
if (Definition->Body)
return Definition->Body.get(getASTContext().getExternalSource());
- return 0;
+ return nullptr;
}
void FunctionDecl::setBody(Stmt *B) {
@@ -2303,11 +2379,12 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
getDeclName().getCXXOverloadedOperator() == OO_Array_New ||
getDeclName().getCXXOverloadedOperator() == OO_Array_Delete);
- if (isa<CXXRecordDecl>(getDeclContext())) return false;
- assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+ if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
+ return false;
const FunctionProtoType *proto = getType()->castAs<FunctionProtoType>();
- if (proto->getNumArgs() != 2 || proto->isVariadic()) return false;
+ if (proto->getNumParams() != 2 || proto->isVariadic())
+ return false;
ASTContext &Context =
cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext())
@@ -2315,13 +2392,7 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
// The result type and first argument type are constant across all
// these operators. The second argument must be exactly void*.
- return (proto->getArgType(1).getCanonicalType() == Context.VoidPtrTy);
-}
-
-static bool isNamespaceStd(const DeclContext *DC) {
- const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC->getRedeclContext());
- return ND && isNamed(ND, "std") &&
- ND->getParent()->getRedeclContext()->isTranslationUnit();
+ return (proto->getParamType(1).getCanonicalType() == Context.VoidPtrTy);
}
bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
@@ -2335,20 +2406,23 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
if (isa<CXXRecordDecl>(getDeclContext()))
return false;
- assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+
+ // This can only fail for an invalid 'operator new' declaration.
+ if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
+ return false;
const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
- if (FPT->getNumArgs() > 2 || FPT->isVariadic())
+ if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic())
return false;
// If this is a single-parameter function, it must be a replaceable global
// allocation or deallocation function.
- if (FPT->getNumArgs() == 1)
+ if (FPT->getNumParams() == 1)
return true;
// Otherwise, we're looking for a second parameter whose type is
// 'const std::nothrow_t &', or, in C++1y, 'std::size_t'.
- QualType Ty = FPT->getArgType(1);
+ QualType Ty = FPT->getParamType(1);
ASTContext &Ctx = getASTContext();
if (Ctx.getLangOpts().SizedDeallocation &&
Ctx.hasSameType(Ty, Ctx.getSizeType()))
@@ -2358,30 +2432,31 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
Ty = Ty->getPointeeType();
if (Ty.getCVRQualifiers() != Qualifiers::Const)
return false;
- // FIXME: Recognise nothrow_t in an inline namespace inside std?
const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
- return RD && isNamed(RD, "nothrow_t") && isNamespaceStd(RD->getDeclContext());
+ return RD && isNamed(RD, "nothrow_t") && RD->isInStdNamespace();
}
FunctionDecl *
FunctionDecl::getCorrespondingUnsizedGlobalDeallocationFunction() const {
ASTContext &Ctx = getASTContext();
if (!Ctx.getLangOpts().SizedDeallocation)
- return 0;
+ return nullptr;
if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName)
- return 0;
+ return nullptr;
if (getDeclName().getCXXOverloadedOperator() != OO_Delete &&
getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
- return 0;
+ return nullptr;
if (isa<CXXRecordDecl>(getDeclContext()))
- return 0;
- assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+ return nullptr;
+
+ if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
+ return nullptr;
if (getNumParams() != 2 || isVariadic() ||
- !Ctx.hasSameType(getType()->castAs<FunctionProtoType>()->getArgType(1),
+ !Ctx.hasSameType(getType()->castAs<FunctionProtoType>()->getParamType(1),
Ctx.getSizeType()))
- return 0;
+ return nullptr;
// This is a sized deallocation function. Find the corresponding unsized
// deallocation function.
@@ -2391,15 +2466,15 @@ FunctionDecl::getCorrespondingUnsizedGlobalDeallocationFunction() const {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*RI))
if (FD->getNumParams() == 1 && !FD->isVariadic())
return FD;
- return 0;
+ return nullptr;
}
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
- return getLanguageLinkageTemplate(*this);
+ return getDeclLanguageLinkage(*this);
}
bool FunctionDecl::isExternC() const {
- return isExternCTemplate(*this);
+ return isDeclExternC(*this);
}
bool FunctionDecl::isInExternCContext() const {
@@ -2442,7 +2517,7 @@ FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
FunctionTemplateDecl *PrevFunTmpl
- = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
+ = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : nullptr;
assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
FunTmpl->setPreviousDecl(PrevFunTmpl);
}
@@ -2488,7 +2563,7 @@ unsigned FunctionDecl::getBuiltinID() const {
// If the function is marked "overloadable", it has a different mangled name
// and is not the C library function.
- if (getAttr<OverloadableAttr>())
+ if (hasAttr<OverloadableAttr>())
return 0;
if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
@@ -2510,16 +2585,13 @@ unsigned FunctionDecl::getBuiltinID() const {
/// based on its FunctionType. This is the length of the ParamInfo array
/// after it has been created.
unsigned FunctionDecl::getNumParams() const {
- const FunctionType *FT = getType()->castAs<FunctionType>();
- if (isa<FunctionNoProtoType>(FT))
- return 0;
- return cast<FunctionProtoType>(FT)->getNumArgs();
-
+ const FunctionProtoType *FPT = getType()->getAs<FunctionProtoType>();
+ return FPT ? FPT->getNumParams() : 0;
}
void FunctionDecl::setParams(ASTContext &C,
ArrayRef<ParmVarDecl *> NewParamInfo) {
- assert(ParamInfo == 0 && "Already has param info!");
+ assert(!ParamInfo && "Already has param info!");
assert(NewParamInfo.size() == getNumParams() && "Parameter count mismatch!");
// Zero params -> null pointer.
@@ -2536,44 +2608,67 @@ void FunctionDecl::setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls) {
NamedDecl **A = new (getASTContext()) NamedDecl*[NewDecls.size()];
std::copy(NewDecls.begin(), NewDecls.end(), A);
DeclsInPrototypeScope = ArrayRef<NamedDecl *>(A, NewDecls.size());
+ // Move declarations introduced in prototype to the function context.
+ for (auto I : NewDecls) {
+ DeclContext *DC = I->getDeclContext();
+ // Forward-declared reference to an enumeration is not added to
+ // declaration scope, so skip declaration that is absent from its
+ // declaration contexts.
+ if (DC->containsDecl(I)) {
+ DC->removeDecl(I);
+ I->setDeclContext(this);
+ addDecl(I);
+ }
+ }
}
}
/// 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++) or the last parameter is a parameter pack.
+/// arguments (in C++) or are parameter packs (C++11).
unsigned FunctionDecl::getMinRequiredArguments() const {
if (!getASTContext().getLangOpts().CPlusPlus)
return getNumParams();
-
- unsigned NumRequiredArgs = getNumParams();
-
- // If the last parameter is a parameter pack, we don't need an argument for
- // it.
- if (NumRequiredArgs > 0 &&
- getParamDecl(NumRequiredArgs - 1)->isParameterPack())
- --NumRequiredArgs;
-
- // If this parameter has a default argument, we don't need an argument for
- // it.
- while (NumRequiredArgs > 0 &&
- getParamDecl(NumRequiredArgs-1)->hasDefaultArg())
- --NumRequiredArgs;
-
- // We might have parameter packs before the end. These can't be deduced,
- // but they can still handle multiple arguments.
- unsigned ArgIdx = NumRequiredArgs;
- while (ArgIdx > 0) {
- if (getParamDecl(ArgIdx - 1)->isParameterPack())
- NumRequiredArgs = ArgIdx;
-
- --ArgIdx;
- }
-
+
+ unsigned NumRequiredArgs = 0;
+ for (auto *Param : params())
+ if (!Param->isParameterPack() && !Param->hasDefaultArg())
+ ++NumRequiredArgs;
return NumRequiredArgs;
}
+/// \brief The combination of the extern and inline keywords under MSVC forces
+/// the function to be required.
+///
+/// Note: This function assumes that we will only get called when isInlined()
+/// would return true for this FunctionDecl.
+bool FunctionDecl::isMSExternInline() const {
+ assert(isInlined() && "expected to get called on an inlined function!");
+
+ const ASTContext &Context = getASTContext();
+ if (!Context.getLangOpts().MSVCCompat && !hasAttr<DLLExportAttr>())
+ return false;
+
+ for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDecl())
+ if (FD->getStorageClass() == SC_Extern)
+ return true;
+
+ return false;
+}
+
+static bool redeclForcesDefMSVC(const FunctionDecl *Redecl) {
+ if (Redecl->getStorageClass() != SC_Extern)
+ return false;
+
+ for (const FunctionDecl *FD = Redecl->getPreviousDecl(); FD;
+ FD = FD->getPreviousDecl())
+ if (FD->getStorageClass() == SC_Extern)
+ return false;
+
+ return true;
+}
+
static bool RedeclForcesDefC99(const FunctionDecl *Redecl) {
// Only consider file-scope declarations in this test.
if (!Redecl->getLexicalDeclContext()->isTranslationUnit())
@@ -2593,7 +2688,7 @@ static bool RedeclForcesDefC99(const FunctionDecl *Redecl) {
/// \brief For a function declaration in C or C++, determine whether this
/// declaration causes the definition to be externally visible.
///
-/// Specifically, this determines if adding the current declaration to the set
+/// For instance, this determines if adding the current declaration to the set
/// of redeclarations of the given functions causes
/// isInlineDefinitionExternallyVisible to change from false to true.
bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
@@ -2602,6 +2697,13 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
ASTContext &Context = getASTContext();
+ if (Context.getLangOpts().MSVCCompat) {
+ const FunctionDecl *Definition;
+ if (hasBody(Definition) && Definition->isInlined() &&
+ redeclForcesDefMSVC(this))
+ return true;
+ }
+
if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) {
// With GNU inlining, a declaration with 'inline' but not 'extern', forces
// an externally visible definition.
@@ -2649,6 +2751,26 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
return FoundBody;
}
+SourceRange FunctionDecl::getReturnTypeSourceRange() const {
+ const TypeSourceInfo *TSI = getTypeSourceInfo();
+ if (!TSI)
+ return SourceRange();
+ FunctionTypeLoc FTL =
+ TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
+ if (!FTL)
+ return SourceRange();
+
+ // Skip self-referential return types.
+ const SourceManager &SM = getASTContext().getSourceManager();
+ SourceRange RTRange = FTL.getReturnLoc().getSourceRange();
+ SourceLocation Boundary = getNameInfo().getLocStart();
+ if (RTRange.isInvalid() || Boundary.isInvalid() ||
+ !SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary))
+ return SourceRange();
+
+ return RTRange;
+}
+
/// \brief For an inline function definition in C, or for a gnu_inline function
/// in C++, determine whether the definition will be externally visible.
///
@@ -2683,9 +2805,7 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
// If any declaration is 'inline' but not 'extern', then this definition
// is externally visible.
- for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
- Redecl != RedeclEnd;
- ++Redecl) {
+ for (auto Redecl : redecls()) {
if (Redecl->isInlineSpecified() &&
Redecl->getStorageClass() != SC_Extern)
return true;
@@ -2702,10 +2822,8 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
// [...] If all of the file scope declarations for a function in a
// translation unit include the inline function specifier without extern,
// then the definition in that translation unit is an inline definition.
- for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
- Redecl != RedeclEnd;
- ++Redecl) {
- if (RedeclForcesDefC99(*Redecl))
+ for (auto Redecl : redecls()) {
+ if (RedeclForcesDefC99(Redecl))
return true;
}
@@ -2731,7 +2849,7 @@ const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const {
if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName)
return getDeclName().getCXXLiteralIdentifier();
else
- return 0;
+ return nullptr;
}
FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const {
@@ -2753,8 +2871,8 @@ FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const {
FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
if (MemberSpecializationInfo *Info = getMemberSpecializationInfo())
return cast<FunctionDecl>(Info->getInstantiatedFrom());
-
- return 0;
+
+ return nullptr;
}
void
@@ -2784,7 +2902,7 @@ bool FunctionDecl::isImplicitlyInstantiable() const {
// It is possible to instantiate TSK_ExplicitSpecialization kind
// if the FunctionDecl has a class scope specialization pattern.
case TSK_ExplicitSpecialization:
- return getClassScopeSpecializationPattern() != 0;
+ return getClassScopeSpecializationPattern() != nullptr;
case TSK_ExplicitInstantiationDeclaration:
// Handled below.
@@ -2824,14 +2942,34 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
// Handle class scope explicit specialization special case.
if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
return getClassScopeSpecializationPattern();
-
+
+ // If this is a generic lambda call operator specialization, its
+ // instantiation pattern is always its primary template's pattern
+ // even if its primary template was instantiated from another
+ // member template (which happens with nested generic lambdas).
+ // Since a lambda's call operator's body is transformed eagerly,
+ // we don't have to go hunting for a prototype definition template
+ // (i.e. instantiated-from-member-template) to use as an instantiation
+ // pattern.
+
+ if (isGenericLambdaCallOperatorSpecialization(
+ dyn_cast<CXXMethodDecl>(this))) {
+ assert(getPrimaryTemplate() && "A generic lambda specialization must be "
+ "generated from a primary call operator "
+ "template");
+ assert(getPrimaryTemplate()->getTemplatedDecl()->getBody() &&
+ "A generic lambda call operator template must always have a body - "
+ "even if instantiated from a prototype (i.e. as written) member "
+ "template");
+ return getPrimaryTemplate()->getTemplatedDecl();
+ }
+
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
while (Primary->getInstantiatedFromMemberTemplate()) {
// If we have hit a point where the user provided a specialization of
// this template, we're done looking.
if (Primary->isMemberSpecialization())
break;
-
Primary = Primary->getInstantiatedFromMemberTemplate();
}
@@ -2847,7 +2985,7 @@ FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
return Info->Template.getPointer();
}
- return 0;
+ return nullptr;
}
FunctionDecl *FunctionDecl::getClassScopeSpecializationPattern() const {
@@ -2861,7 +2999,7 @@ FunctionDecl::getTemplateSpecializationArgs() const {
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
return Info->TemplateArguments;
}
- return 0;
+ return nullptr;
}
const ASTTemplateArgumentListInfo *
@@ -2871,7 +3009,7 @@ FunctionDecl::getTemplateSpecializationArgsAsWritten() const {
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
return Info->TemplateArgumentsAsWritten;
}
- return 0;
+ return nullptr;
}
void
@@ -3101,14 +3239,14 @@ FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
InClassInitStyle InitStyle) {
- return new (C) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
- BW, Mutable, InitStyle);
+ return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
+ BW, Mutable, InitStyle);
}
FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FieldDecl));
- return new (Mem) FieldDecl(Field, 0, SourceLocation(), SourceLocation(),
- 0, QualType(), 0, 0, false, ICIS_NoInit);
+ return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(),
+ SourceLocation(), nullptr, QualType(), nullptr,
+ nullptr, false, ICIS_NoInit);
}
bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -3180,8 +3318,10 @@ TagDecl *TagDecl::getCanonicalDecl() { return getFirstDecl(); }
void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
NamedDeclOrQualifier = TDD;
- if (TypeForDecl)
- assert(TypeForDecl->isLinkageValid());
+ if (const Type *T = getTypeForDecl()) {
+ (void)T;
+ assert(T->isLinkageValid());
+ }
assert(isLinkageValid());
}
@@ -3189,10 +3329,10 @@ void TagDecl::startDefinition() {
IsBeingDefined = true;
if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(this)) {
- struct CXXRecordDecl::DefinitionData *Data =
+ struct CXXRecordDecl::DefinitionData *Data =
new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
- for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
- cast<CXXRecordDecl>(*I)->DefinitionData = Data;
+ for (auto I : redecls())
+ cast<CXXRecordDecl>(I)->DefinitionData = Data;
}
}
@@ -3224,12 +3364,11 @@ TagDecl *TagDecl::getDefinition() const {
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this))
return CXXRD->getDefinition();
- for (redecl_iterator R = redecls_begin(), REnd = redecls_end();
- R != REnd; ++R)
+ for (auto R : redecls())
if (R->isCompleteDefinition())
- return *R;
+ return R;
- return 0;
+ return nullptr;
}
void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
@@ -3244,7 +3383,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
if (hasExtInfo()) {
if (getExtInfo()->NumTemplParamLists == 0) {
getASTContext().Deallocate(getExtInfo());
- NamedDeclOrQualifier = (TypedefNameDecl*) 0;
+ NamedDeclOrQualifier = (TypedefNameDecl*)nullptr;
}
else
getExtInfo()->QualifierLoc = QualifierLoc;
@@ -3275,21 +3414,28 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
EnumDecl *PrevDecl, bool IsScoped,
bool IsScopedUsingClassTag, bool IsFixed) {
- EnumDecl *Enum = new (C) EnumDecl(DC, StartLoc, IdLoc, Id, PrevDecl,
- IsScoped, IsScopedUsingClassTag, IsFixed);
+ EnumDecl *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl,
+ IsScoped, IsScopedUsingClassTag,
+ IsFixed);
Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
C.getTypeDeclType(Enum, PrevDecl);
return Enum;
}
EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EnumDecl));
- EnumDecl *Enum = new (Mem) EnumDecl(0, SourceLocation(), SourceLocation(),
- 0, 0, false, false, false);
+ EnumDecl *Enum =
+ new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(),
+ nullptr, nullptr, false, false, false);
Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
return Enum;
}
+SourceRange EnumDecl::getIntegerTypeRange() const {
+ if (const TypeSourceInfo *TI = getIntegerTypeSourceInfo())
+ return TI->getTypeLoc().getSourceRange();
+ return SourceRange();
+}
+
void EnumDecl::completeDefinition(QualType NewType,
QualType NewPromotionType,
unsigned NumPositiveBits,
@@ -3325,7 +3471,7 @@ EnumDecl *EnumDecl::getInstantiatedFromMemberEnum() const {
if (SpecializationInfo)
return cast<EnumDecl>(SpecializationInfo->getInstantiatedFrom());
- return 0;
+ return nullptr;
}
void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
@@ -3338,10 +3484,11 @@ void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
// RecordDecl Implementation
//===----------------------------------------------------------------------===//
-RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, RecordDecl *PrevDecl)
- : TagDecl(DK, TK, DC, IdLoc, Id, PrevDecl, StartLoc) {
+RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
+ DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ RecordDecl *PrevDecl)
+ : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
HasFlexibleArrayMember = false;
AnonymousStructOrUnion = false;
HasObjectMember = false;
@@ -3353,8 +3500,8 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl* PrevDecl) {
- RecordDecl* R = new (C) RecordDecl(Record, TK, DC, StartLoc, IdLoc, Id,
- PrevDecl);
+ RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC,
+ StartLoc, IdLoc, Id, PrevDecl);
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
C.getTypeDeclType(R, PrevDecl);
@@ -3362,9 +3509,9 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
}
RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(RecordDecl));
- RecordDecl *R = new (Mem) RecordDecl(Record, TTK_Struct, 0, SourceLocation(),
- SourceLocation(), 0, 0);
+ RecordDecl *R =
+ new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(),
+ SourceLocation(), nullptr, nullptr);
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
return R;
}
@@ -3427,7 +3574,7 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
if (Decls.empty())
return;
- llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls,
+ std::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls,
/*FieldsAlreadyLoaded=*/false);
}
@@ -3436,7 +3583,7 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
//===----------------------------------------------------------------------===//
void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
- assert(ParamInfo == 0 && "Already has param info!");
+ assert(!ParamInfo && "Already has param info!");
// Zero params -> null pointer.
if (!NewParamInfo.empty()) {
@@ -3454,7 +3601,7 @@ void BlockDecl::setCaptures(ASTContext &Context,
if (begin == end) {
NumCaptures = 0;
- Captures = 0;
+ Captures = nullptr;
return;
}
@@ -3469,10 +3616,9 @@ void BlockDecl::setCaptures(ASTContext &Context,
}
bool BlockDecl::capturesVariable(const VarDecl *variable) const {
- for (capture_const_iterator
- i = capture_begin(), e = capture_end(); i != e; ++i)
+ for (const auto &I : captures())
// Only auto vars can be captured, so no redeclaration worries.
- if (i->getVariable() == variable)
+ if (I.getVariable() == variable)
return true;
return false;
@@ -3489,33 +3635,33 @@ SourceRange BlockDecl::getSourceRange() const {
void TranslationUnitDecl::anchor() { }
TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
- return new (C) TranslationUnitDecl(C);
+ return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C);
}
void LabelDecl::anchor() { }
LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, IdentifierInfo *II) {
- return new (C) LabelDecl(DC, IdentL, II, 0, IdentL);
+ return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, IdentL);
}
LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, IdentifierInfo *II,
SourceLocation GnuLabelL) {
assert(GnuLabelL != IdentL && "Use this only for GNU local labels");
- return new (C) LabelDecl(DC, IdentL, II, 0, GnuLabelL);
+ return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL);
}
LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(LabelDecl));
- return new (Mem) LabelDecl(0, SourceLocation(), 0, 0, SourceLocation());
+ return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr,
+ SourceLocation());
}
void ValueDecl::anchor() { }
bool ValueDecl::isWeak() const {
- for (attr_iterator I = attr_begin(), E = attr_end(); I != E; ++I)
- if (isa<WeakAttr>(*I) || isa<WeakRefAttr>(*I))
+ for (const auto *I : attrs())
+ if (isa<WeakAttr>(I) || isa<WeakRefAttr>(I))
return true;
return isWeakImported();
@@ -3527,13 +3673,13 @@ ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc,
IdentifierInfo *Id,
QualType Type) {
- return new (C) ImplicitParamDecl(DC, IdLoc, Id, Type);
+ return new (C, DC) ImplicitParamDecl(C, DC, IdLoc, Id, Type);
}
-ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C,
+ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ImplicitParamDecl));
- return new (Mem) ImplicitParamDecl(0, SourceLocation(), 0, QualType());
+ return new (C, ID) ImplicitParamDecl(C, nullptr, SourceLocation(), nullptr,
+ QualType());
}
FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
@@ -3541,66 +3687,53 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass SC,
- bool isInlineSpecified,
+ bool isInlineSpecified,
bool hasWrittenPrototype,
bool isConstexprSpecified) {
- FunctionDecl *New = new (C) FunctionDecl(Function, DC, StartLoc, NameInfo,
- T, TInfo, SC,
- isInlineSpecified,
- isConstexprSpecified);
+ FunctionDecl *New =
+ new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo,
+ SC, isInlineSpecified, isConstexprSpecified);
New->HasWrittenPrototype = hasWrittenPrototype;
return New;
}
FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionDecl));
- return new (Mem) FunctionDecl(Function, 0, SourceLocation(),
- DeclarationNameInfo(), QualType(), 0,
- SC_None, false, false);
+ return new (C, ID) FunctionDecl(Function, C, nullptr, SourceLocation(),
+ DeclarationNameInfo(), QualType(), nullptr,
+ SC_None, false, false);
}
BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
- return new (C) BlockDecl(DC, L);
+ return new (C, DC) BlockDecl(DC, L);
}
BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(BlockDecl));
- return new (Mem) BlockDecl(0, SourceLocation());
-}
-
-MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C,
- unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(MSPropertyDecl));
- return new (Mem) MSPropertyDecl(0, SourceLocation(), DeclarationName(),
- QualType(), 0, SourceLocation(),
- 0, 0);
+ return new (C, ID) BlockDecl(nullptr, SourceLocation());
}
CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC,
unsigned NumParams) {
- unsigned Size = sizeof(CapturedDecl) + NumParams * sizeof(ImplicitParamDecl*);
- return new (C.Allocate(Size)) CapturedDecl(DC, NumParams);
+ return new (C, DC, NumParams * sizeof(ImplicitParamDecl *))
+ CapturedDecl(DC, NumParams);
}
CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, unsigned ID,
- unsigned NumParams) {
- unsigned Size = sizeof(CapturedDecl) + NumParams * sizeof(ImplicitParamDecl*);
- void *Mem = AllocateDeserializedDecl(C, ID, Size);
- return new (Mem) CapturedDecl(0, NumParams);
+ unsigned NumParams) {
+ return new (C, ID, NumParams * sizeof(ImplicitParamDecl *))
+ CapturedDecl(nullptr, NumParams);
}
EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T,
Expr *E, const llvm::APSInt &V) {
- return new (C) EnumConstantDecl(CD, L, Id, T, E, V);
+ return new (C, CD) EnumConstantDecl(CD, L, Id, T, E, V);
}
EnumConstantDecl *
EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EnumConstantDecl));
- return new (Mem) EnumConstantDecl(0, SourceLocation(), 0, QualType(), 0,
- llvm::APSInt());
+ return new (C, ID) EnumConstantDecl(nullptr, SourceLocation(), nullptr,
+ QualType(), nullptr, llvm::APSInt());
}
void IndirectFieldDecl::anchor() { }
@@ -3609,14 +3742,14 @@ IndirectFieldDecl *
IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, NamedDecl **CH,
unsigned CHS) {
- return new (C) IndirectFieldDecl(DC, L, Id, T, CH, CHS);
+ return new (C, DC) IndirectFieldDecl(DC, L, Id, T, CH, CHS);
}
IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(IndirectFieldDecl));
- return new (Mem) IndirectFieldDecl(0, SourceLocation(), DeclarationName(),
- QualType(), 0, 0);
+ return new (C, ID) IndirectFieldDecl(nullptr, SourceLocation(),
+ DeclarationName(), QualType(), nullptr,
+ 0);
}
SourceRange EnumConstantDecl::getSourceRange() const {
@@ -3631,26 +3764,26 @@ void TypeDecl::anchor() { }
TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo) {
- return new (C) TypedefDecl(DC, StartLoc, IdLoc, Id, TInfo);
+ return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
}
void TypedefNameDecl::anchor() { }
TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypedefDecl));
- return new (Mem) TypedefDecl(0, SourceLocation(), SourceLocation(), 0, 0);
+ return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(),
+ nullptr, nullptr);
}
TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
TypeSourceInfo *TInfo) {
- return new (C) TypeAliasDecl(DC, StartLoc, IdLoc, Id, TInfo);
+ return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
}
TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasDecl));
- return new (Mem) TypeAliasDecl(0, SourceLocation(), SourceLocation(), 0, 0);
+ return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(),
+ SourceLocation(), nullptr, nullptr);
}
SourceRange TypedefDecl::getSourceRange() const {
@@ -3675,24 +3808,23 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
StringLiteral *Str,
SourceLocation AsmLoc,
SourceLocation RParenLoc) {
- return new (C) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc);
+ return new (C, DC) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc);
}
-FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C,
+FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FileScopeAsmDecl));
- return new (Mem) FileScopeAsmDecl(0, 0, SourceLocation(), SourceLocation());
+ return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(),
+ SourceLocation());
}
void EmptyDecl::anchor() {}
EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
- return new (C) EmptyDecl(DC, L);
+ return new (C, DC) EmptyDecl(DC, L);
}
EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EmptyDecl));
- return new (Mem) EmptyDecl(0, SourceLocation());
+ return new (C, ID) EmptyDecl(nullptr, SourceLocation());
}
//===----------------------------------------------------------------------===//
@@ -3730,30 +3862,28 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
*reinterpret_cast<SourceLocation *>(this + 1) = EndLoc;
}
-ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC,
+ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs) {
- void *Mem = C.Allocate(sizeof(ImportDecl) +
- IdentifierLocs.size() * sizeof(SourceLocation));
- return new (Mem) ImportDecl(DC, StartLoc, Imported, IdentifierLocs);
+ return new (C, DC, IdentifierLocs.size() * sizeof(SourceLocation))
+ ImportDecl(DC, StartLoc, Imported, IdentifierLocs);
}
-ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC,
+ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
- Module *Imported,
+ Module *Imported,
SourceLocation EndLoc) {
- void *Mem = C.Allocate(sizeof(ImportDecl) + sizeof(SourceLocation));
- ImportDecl *Import = new (Mem) ImportDecl(DC, StartLoc, Imported, EndLoc);
+ ImportDecl *Import =
+ new (C, DC, sizeof(SourceLocation)) ImportDecl(DC, StartLoc,
+ Imported, EndLoc);
Import->setImplicit();
return Import;
}
ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumLocations) {
- void *Mem = AllocateDeserializedDecl(C, ID,
- (sizeof(ImportDecl) +
- NumLocations * sizeof(SourceLocation)));
- return new (Mem) ImportDecl(EmptyShell());
+ return new (C, ID, NumLocations * sizeof(SourceLocation))
+ ImportDecl(EmptyShell());
}
ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const {
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp b/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp
index 121c5a6..2b1506d 100644
--- a/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp
@@ -45,25 +45,30 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const {
getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
}
-void *Decl::AllocateDeserializedDecl(const ASTContext &Context,
- unsigned ID,
- unsigned Size) {
+void *Decl::operator new(std::size_t Size, const ASTContext &Context,
+ unsigned ID, std::size_t Extra) {
// Allocate an extra 8 bytes worth of storage, which ensures that the
// resulting pointer will still be 8-byte aligned.
- void *Start = Context.Allocate(Size + 8);
+ void *Start = Context.Allocate(Size + Extra + 8);
void *Result = (char*)Start + 8;
-
+
unsigned *PrefixPtr = (unsigned *)Result - 2;
-
+
// Zero out the first 4 bytes; this is used to store the owning module ID.
PrefixPtr[0] = 0;
-
+
// Store the global declaration ID in the second 4 bytes.
PrefixPtr[1] = ID;
-
+
return Result;
}
+void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,
+ DeclContext *Parent, std::size_t Extra) {
+ assert(!Parent || &Parent->getParentASTContext() == &Ctx);
+ return ::operator new(Size + Extra, Ctx);
+}
+
Module *Decl::getOwningModuleSlow() const {
assert(isFromASTFile() && "Not from AST file?");
return getASTContext().getExternalSource()->getModule(getOwningModuleID());
@@ -80,6 +85,7 @@ const char *Decl::getDeclKindName() const {
void Decl::setInvalidDecl(bool Invalid) {
InvalidDecl = Invalid;
+ assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());
if (Invalid && !isa<ParmVarDecl>(this)) {
// Defensive maneuver for ill-formed code: we're likely not to make it to
// a point where we set the access specifier, so default it to "public"
@@ -153,11 +159,12 @@ bool Decl::isParameterPack() const {
return isTemplateParameterPack();
}
-bool Decl::isFunctionOrFunctionTemplate() const {
- if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
- return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
-
- return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
+FunctionDecl *Decl::getAsFunction() {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
+ return FD;
+ if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(this))
+ return FTD->getTemplatedDecl();
+ return nullptr;
}
bool Decl::isTemplateDecl() const {
@@ -171,7 +178,7 @@ const DeclContext *Decl::getParentFunctionOrMethod() const {
if (DC->isFunctionOrMethod())
return DC;
- return 0;
+ return nullptr;
}
@@ -244,6 +251,10 @@ bool Decl::isInAnonymousNamespace() const {
return false;
}
+bool Decl::isInStdNamespace() const {
+ return getDeclContext()->isStdNamespace();
+}
+
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this))
return TUD;
@@ -306,7 +317,7 @@ bool Decl::isReferenced() const {
return true;
// Check redeclarations.
- for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
+ for (auto I : redecls())
if (I->Referenced)
return true;
@@ -401,8 +412,8 @@ AvailabilityResult Decl::getAvailability(std::string *Message) const {
AvailabilityResult Result = AR_Available;
std::string ResultMessage;
- for (attr_iterator A = attr_begin(), AEnd = attr_end(); A != AEnd; ++A) {
- if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
+ for (const auto *A : attrs()) {
+ if (const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
if (Result >= AR_Deprecated)
continue;
@@ -413,13 +424,13 @@ AvailabilityResult Decl::getAvailability(std::string *Message) const {
continue;
}
- if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
+ if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
if (Message)
*Message = Unavailable->getMessage();
return AR_Unavailable;
}
- if (AvailabilityAttr *Availability = dyn_cast<AvailabilityAttr>(*A)) {
+ if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
Message);
@@ -475,13 +486,13 @@ bool Decl::isWeakImported() const {
if (!canBeWeakImported(IsDefinition))
return false;
- for (attr_iterator A = attr_begin(), AEnd = attr_end(); A != AEnd; ++A) {
- if (isa<WeakImportAttr>(*A))
+ for (const auto *A : attrs()) {
+ if (isa<WeakImportAttr>(A))
return true;
- if (AvailabilityAttr *Availability = dyn_cast<AvailabilityAttr>(*A)) {
- if (CheckAvailability(getASTContext(), Availability, 0)
- == AR_NotYetIntroduced)
+ if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
+ if (CheckAvailability(getASTContext(), Availability,
+ nullptr) == AR_NotYetIntroduced)
return true;
}
}
@@ -662,7 +673,7 @@ SourceLocation Decl::getBodyRBrace() const {
return SourceLocation();
}
-void Decl::CheckAccessDeclContext() const {
+bool Decl::AccessDeclContextSanity() const {
#ifndef NDEBUG
// Suppress this check if any of the following hold:
// 1. this is the translation unit (and thus has no parent)
@@ -684,16 +695,35 @@ void Decl::CheckAccessDeclContext() const {
// AS_none as access specifier.
isa<CXXRecordDecl>(this) ||
isa<ClassScopeFunctionSpecializationDecl>(this))
- return;
+ return true;
assert(Access != AS_none &&
"Access specifier is AS_none inside a record decl");
#endif
+ return true;
}
static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }
+const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
+ QualType Ty;
+ if (const ValueDecl *D = dyn_cast<ValueDecl>(this))
+ Ty = D->getType();
+ else if (const TypedefNameDecl *D = dyn_cast<TypedefNameDecl>(this))
+ Ty = D->getUnderlyingType();
+ else
+ return nullptr;
+
+ if (Ty->isFunctionPointerType())
+ Ty = Ty->getAs<PointerType>()->getPointeeType();
+ else if (BlocksToo && Ty->isBlockPointerType())
+ Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
+
+ return Ty->getAs<FunctionType>();
+}
+
+
/// Starting at a given context (a Decl or DeclContext), look for a
/// code context that is not a closure (a lambda, block, etc.).
template <class T> static Decl *getNonClosureContext(T *D) {
@@ -712,7 +742,7 @@ template <class T> static Decl *getNonClosureContext(T *D) {
} else if (CapturedDecl *CD = dyn_cast<CapturedDecl>(D)) {
return getNonClosureContext(CD->getParent());
} else {
- return 0;
+ return nullptr;
}
}
@@ -769,6 +799,22 @@ bool DeclContext::isInlineNamespace() const {
cast<NamespaceDecl>(this)->isInline();
}
+bool DeclContext::isStdNamespace() const {
+ if (!isNamespace())
+ return false;
+
+ const NamespaceDecl *ND = cast<NamespaceDecl>(this);
+ if (ND->isInline()) {
+ return ND->getParent()->isStdNamespace();
+ }
+
+ if (!getParent()->getRedeclContext()->isTranslationUnit())
+ return false;
+
+ const IdentifierInfo *II = ND->getIdentifier();
+ return II && II->isStr("std");
+}
+
bool DeclContext::isDependentContext() const {
if (isFileContext())
return false;
@@ -811,7 +857,7 @@ static bool isLinkageSpecContext(const DeclContext *DC,
while (DC->getDeclKind() != Decl::TranslationUnit) {
if (DC->getDeclKind() == Decl::LinkageSpec)
return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;
- DC = DC->getParent();
+ DC = DC->getLexicalParent();
}
return false;
}
@@ -874,18 +920,17 @@ DeclContext *DeclContext::getPrimaryContext() {
// If this is a tag type that has a definition or is currently
// being defined, that definition is our primary context.
TagDecl *Tag = cast<TagDecl>(this);
- assert(isa<TagType>(Tag->TypeForDecl) ||
- isa<InjectedClassNameType>(Tag->TypeForDecl));
if (TagDecl *Def = Tag->getDefinition())
return Def;
- if (!isa<InjectedClassNameType>(Tag->TypeForDecl)) {
- const TagType *TagTy = cast<TagType>(Tag->TypeForDecl);
- if (TagTy->isBeingDefined())
- // FIXME: is it necessarily being defined in the decl
- // that owns the type?
- return TagTy->getDecl();
+ if (const TagType *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
+ // Note, TagType::getDecl returns the (partial) definition one exists.
+ TagDecl *PossiblePartialDef = TagTy->getDecl();
+ if (PossiblePartialDef->isBeingDefined())
+ return PossiblePartialDef;
+ } else {
+ assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
}
return Tag;
@@ -918,8 +963,8 @@ std::pair<Decl *, Decl *>
DeclContext::BuildDeclChain(ArrayRef<Decl*> Decls,
bool FieldsAlreadyLoaded) {
// Build up a chain of declarations via the Decl::NextInContextAndBits field.
- Decl *FirstNewDecl = 0;
- Decl *PrevDecl = 0;
+ Decl *FirstNewDecl = nullptr;
+ Decl *PrevDecl = nullptr;
for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
if (FieldsAlreadyLoaded && isa<FieldDecl>(Decls[I]))
continue;
@@ -939,13 +984,12 @@ DeclContext::BuildDeclChain(ArrayRef<Decl*> Decls,
/// \brief We have just acquired external visible storage, and we already have
/// built a lookup map. For every name in the map, pull in the new names from
/// the external storage.
-void DeclContext::reconcileExternalVisibleStorage() {
+void DeclContext::reconcileExternalVisibleStorage() const {
assert(NeedToReconcileExternalVisibleStorage && LookupPtr.getPointer());
NeedToReconcileExternalVisibleStorage = false;
- StoredDeclsMap &Map = *LookupPtr.getPointer();
- for (StoredDeclsMap::iterator I = Map.begin(); I != Map.end(); ++I)
- I->second.setHasExternalDecls();
+ for (auto &Lookup : *LookupPtr.getPointer())
+ Lookup.second.setHasExternalDecls();
}
/// \brief Load the declarations within this lexical storage from an
@@ -982,8 +1026,8 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const {
// Splice the newly-read declarations into the beginning of the list
// of declarations.
Decl *ExternalFirst, *ExternalLast;
- llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls,
- FieldsAlreadyLoaded);
+ std::tie(ExternalFirst, ExternalLast) =
+ BuildDeclChain(Decls, FieldsAlreadyLoaded);
ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
FirstDecl = ExternalFirst;
if (!LastDecl)
@@ -997,6 +1041,8 @@ ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,
StoredDeclsMap *Map;
if (!(Map = DC->LookupPtr.getPointer()))
Map = DC->CreateStoredDeclsMap(Context);
+ if (DC->NeedToReconcileExternalVisibleStorage)
+ DC->reconcileExternalVisibleStorage();
(*Map)[Name].removeExternalDecls();
@@ -1011,6 +1057,8 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
StoredDeclsMap *Map;
if (!(Map = DC->LookupPtr.getPointer()))
Map = DC->CreateStoredDeclsMap(Context);
+ if (DC->NeedToReconcileExternalVisibleStorage)
+ DC->reconcileExternalVisibleStorage();
StoredDeclsList &List = (*Map)[Name];
@@ -1050,14 +1098,9 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
return List.getLookupResult();
}
-DeclContext::decl_iterator DeclContext::noload_decls_begin() const {
- return decl_iterator(FirstDecl);
-}
-
DeclContext::decl_iterator DeclContext::decls_begin() const {
if (hasExternalLexicalStorage())
LoadLexicalDeclsFromExternalStorage();
-
return decl_iterator(FirstDecl);
}
@@ -1082,7 +1125,7 @@ void DeclContext::removeDecl(Decl *D) {
// Remove D from the decl chain. This is O(n) but hopefully rare.
if (D == FirstDecl) {
if (D == LastDecl)
- FirstDecl = LastDecl = 0;
+ FirstDecl = LastDecl = nullptr;
else
FirstDecl = D->NextInContextAndBits.getPointer();
} else {
@@ -1097,7 +1140,7 @@ void DeclContext::removeDecl(Decl *D) {
}
// Mark that D is no longer in the decl chain.
- D->NextInContextAndBits.setPointer(0);
+ D->NextInContextAndBits.setPointer(nullptr);
// Remove D from the lookup table if necessary.
if (isa<NamedDecl>(D)) {
@@ -1187,6 +1230,10 @@ static bool shouldBeHidden(NamedDecl *D) {
/// buildLookup - Build the lookup data structure with all of the
/// declarations in this DeclContext (and any other contexts linked
/// to it or transparent contexts nested within it) and return it.
+///
+/// Note that the produced map may miss out declarations from an
+/// external source. If it does, those entries will be marked with
+/// the 'hasExternalDecls' flag.
StoredDeclsMap *DeclContext::buildLookup() {
assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");
@@ -1202,7 +1249,6 @@ StoredDeclsMap *DeclContext::buildLookup() {
// We no longer have any lazy decls.
LookupPtr.setInt(false);
- NeedToReconcileExternalVisibleStorage = false;
return LookupPtr.getPointer();
}
@@ -1251,11 +1297,13 @@ DeclContext::lookup(DeclarationName Name) {
return PrimaryContext->lookup(Name);
if (hasExternalVisibleStorage()) {
+ if (NeedToReconcileExternalVisibleStorage)
+ reconcileExternalVisibleStorage();
+
StoredDeclsMap *Map = LookupPtr.getPointer();
+
if (LookupPtr.getInt())
Map = buildLookup();
- else if (NeedToReconcileExternalVisibleStorage)
- reconcileExternalVisibleStorage();
if (!Map)
Map = CreateStoredDeclsMap(getParentASTContext());
@@ -1267,7 +1315,7 @@ DeclContext::lookup(DeclarationName Name) {
return R.first->second.getLookupResult();
ExternalASTSource *Source = getParentASTContext().getExternalSource();
- if (Source->FindExternalVisibleDeclsByName(this, Name) || R.second) {
+ if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {
if (StoredDeclsMap *Map = LookupPtr.getPointer()) {
StoredDeclsMap::iterator I = Map->find(Name);
if (I != Map->end())
@@ -1275,7 +1323,7 @@ DeclContext::lookup(DeclarationName Name) {
}
}
- return lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
}
StoredDeclsMap *Map = LookupPtr.getPointer();
@@ -1283,11 +1331,11 @@ DeclContext::lookup(DeclarationName Name) {
Map = buildLookup();
if (!Map)
- return lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
StoredDeclsMap::iterator I = Map->find(Name);
if (I == Map->end())
- return lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
return I->second.getLookupResult();
}
@@ -1324,12 +1372,12 @@ DeclContext::noload_lookup(DeclarationName Name) {
}
if (!Map)
- return lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
StoredDeclsMap::iterator I = Map->find(Name);
- return I != Map->end()
- ? I->second.getLookupResult()
- : lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return I != Map->end() ? I->second.getLookupResult()
+ : lookup_result(lookup_iterator(nullptr),
+ lookup_iterator(nullptr));
}
void DeclContext::localUncachedLookup(DeclarationName Name,
@@ -1502,13 +1550,13 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {
/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
/// this context.
-DeclContext::udir_iterator_range
-DeclContext::getUsingDirectives() const {
+DeclContext::udir_range DeclContext::using_directives() const {
// FIXME: Use something more efficient than normal lookup for using
// directives. In C++, using directives are looked up more than anything else.
lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
- return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.begin()),
- reinterpret_cast<udir_iterator>(Result.end()));
+ return udir_range(
+ reinterpret_cast<UsingDirectiveDecl *const *>(Result.begin()),
+ reinterpret_cast<UsingDirectiveDecl *const *>(Result.end()));
}
//===----------------------------------------------------------------------===//
@@ -1568,7 +1616,7 @@ DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,
// Allocate the copy of the PartialDiagnostic via the ASTContext's
// BumpPtrAllocator, rather than the ASTContext itself.
- PartialDiagnostic::Storage *DiagStorage = 0;
+ PartialDiagnostic::Storage *DiagStorage = nullptr;
if (PDiag.hasStorage())
DiagStorage = new (C) PartialDiagnostic::Storage;
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp b/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp
index a17abdd..ed26c52 100644
--- a/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/DeclCXX.cpp
@@ -31,8 +31,7 @@ using namespace clang;
void AccessSpecDecl::anchor() { }
AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(AccessSpecDecl));
- return new (Mem) AccessSpecDecl(EmptyShell());
+ return new (C, ID) AccessSpecDecl(EmptyShell());
}
void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const {
@@ -51,7 +50,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true),
HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false),
- HasMutableFields(false), HasOnlyCMembers(true),
+ HasMutableFields(false), HasVariantMembers(false), HasOnlyCMembers(true),
HasInClassInitializer(false), HasUninitializedReferenceMember(false),
NeedOverloadResolutionForMoveConstructor(false),
NeedOverloadResolutionForMoveAssignment(false),
@@ -71,7 +70,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
ImplicitCopyAssignmentHasConstParam(true),
HasDeclaredCopyConstructorWithConstParam(false),
HasDeclaredCopyAssignmentWithConstParam(false),
- IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(),
+ IsLambda(false), IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0),
+ Bases(), VBases(),
Definition(D), FirstFriend() {
}
@@ -83,20 +83,22 @@ CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getVBasesSlowCase() const {
return VBases.get(Definition->getASTContext().getExternalSource());
}
-CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
- : RecordDecl(K, TK, DC, StartLoc, IdLoc, Id, PrevDecl),
- DefinitionData(PrevDecl ? PrevDecl->DefinitionData : 0),
- TemplateOrInstantiation() { }
+CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
+ DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ CXXRecordDecl *PrevDecl)
+ : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl),
+ DefinitionData(PrevDecl ? PrevDecl->DefinitionData
+ : DefinitionDataPtr(this)),
+ TemplateOrInstantiation() {}
CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
CXXRecordDecl* PrevDecl,
bool DelayTypeCreation) {
- CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, StartLoc, IdLoc,
- Id, PrevDecl);
+ CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc,
+ IdLoc, Id, PrevDecl);
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
// FIXME: DelayTypeCreation seems like such a hack
@@ -105,29 +107,29 @@ CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
return R;
}
-CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
- TypeSourceInfo *Info, SourceLocation Loc,
- bool Dependent, bool IsGeneric,
- LambdaCaptureDefault CaptureDefault) {
- CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc,
- 0, 0);
+CXXRecordDecl *
+CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
+ TypeSourceInfo *Info, SourceLocation Loc,
+ bool Dependent, bool IsGeneric,
+ LambdaCaptureDefault CaptureDefault) {
+ CXXRecordDecl *R =
+ new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc,
+ nullptr, nullptr);
R->IsBeingDefined = true;
- R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info,
- Dependent,
- IsGeneric,
- CaptureDefault);
+ R->DefinitionData =
+ new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric,
+ CaptureDefault);
R->MayHaveOutOfDateDef = false;
R->setImplicit(true);
- C.getTypeDeclType(R, /*PrevDecl=*/0);
+ C.getTypeDeclType(R, /*PrevDecl=*/nullptr);
return R;
}
CXXRecordDecl *
CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXRecordDecl));
- CXXRecordDecl *R = new (Mem) CXXRecordDecl(CXXRecord, TTK_Struct, 0,
- SourceLocation(), SourceLocation(),
- 0, 0);
+ CXXRecordDecl *R = new (C, ID) CXXRecordDecl(
+ CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(),
+ nullptr, nullptr);
R->MayHaveOutOfDateDef = false;
return R;
}
@@ -205,19 +207,17 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
data().HasNonLiteralTypeFieldsOrBases = true;
// Now go through all virtual bases of this base and add them.
- for (CXXRecordDecl::base_class_iterator VBase =
- BaseClassDecl->vbases_begin(),
- E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
+ for (const auto &VBase : BaseClassDecl->vbases()) {
// Add this base if it's not already in the list.
- if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType()))) {
- VBases.push_back(VBase);
+ if (SeenVBaseTypes.insert(C.getCanonicalType(VBase.getType()))) {
+ VBases.push_back(&VBase);
// C++11 [class.copy]p8:
// The implicitly-declared copy constructor for a class X will have
// the form 'X::X(const X&)' if each [...] virtual base class B of X
// has a copy constructor whose first parameter is of type
// 'const B&' or 'const volatile B&' [...]
- if (CXXRecordDecl *VBaseDecl = VBase->getType()->getAsCXXRecordDecl())
+ if (CXXRecordDecl *VBaseDecl = VBase.getType()->getAsCXXRecordDecl())
if (!VBaseDecl->hasCopyConstructorWithConstParam())
data().ImplicitCopyConstructorHasConstParam = false;
}
@@ -335,8 +335,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
addedClassSubobject(BaseClassDecl);
}
- if (VBases.empty())
+ if (VBases.empty()) {
+ data().IsParsingBaseSpecifiers = false;
return;
+ }
// Create base specifier for any direct or indirect virtual bases.
data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
@@ -347,6 +349,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
addedClassSubobject(Type->getAsCXXRecordDecl());
data().getVBases()[I] = *VBases[I];
}
+
+ data().IsParsingBaseSpecifiers = false;
}
void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
@@ -391,7 +395,7 @@ bool CXXRecordDecl::hasAnyDependentBases() const {
if (!isDependentContext())
return false;
- return !forallBases(SawBase, 0);
+ return !forallBases(SawBase, nullptr);
}
bool CXXRecordDecl::isTriviallyCopyable() const {
@@ -532,8 +536,11 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D)) {
SMKind |= SMF_Destructor;
- if (!DD->isImplicit())
+ if (DD->isUserProvided())
data().HasIrrelevantDestructor = false;
+ // If the destructor is explicitly defaulted and not trivial or not public
+ // or if the destructor is deleted, we clear HasIrrelevantDestructor in
+ // finishedDefaultedOrDeletedMember.
// C++11 [class.dtor]p5:
// A destructor is trivial if [...] the destructor is not virtual.
@@ -656,7 +663,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
// Keep track of the presence of mutable fields.
if (Field->isMutable())
data().HasMutableFields = true;
-
+
+ // C++11 [class.union]p8, DR1460:
+ // If X is a union, a non-static data member of X that is not an anonymous
+ // union is a variant member of X.
+ if (isUnion() && !Field->isAnonymousStructOrUnion())
+ data().HasVariantMembers = true;
+
// C++0x [class]p9:
// A POD struct is a class that is both a trivial class and a
// standard-layout class, and has no non-static data members of type
@@ -692,7 +705,9 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (!T->isLiteralType(Context) || T.isVolatileQualified())
data().HasNonLiteralTypeFieldsOrBases = true;
- if (Field->hasInClassInitializer()) {
+ if (Field->hasInClassInitializer() ||
+ (Field->isAnonymousStructOrUnion() &&
+ Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) {
data().HasInClassInitializer = true;
// C++11 [class]p5:
@@ -809,15 +824,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
// Virtual bases and virtual methods make a class non-empty, but they
// also make it non-standard-layout so we needn't check here.
// A non-empty base class may leave the class standard-layout, but not
- // if we have arrived here, and have at least on non-static data
+ // if we have arrived here, and have at least one non-static data
// member. If IsStandardLayout remains true, then the first non-static
// data member must come through here with Empty still true, and Empty
// will subsequently be set to false below.
if (data().IsStandardLayout && data().Empty) {
- for (CXXRecordDecl::base_class_const_iterator BI = bases_begin(),
- BE = bases_end();
- BI != BE; ++BI) {
- if (Context.hasSameUnqualifiedType(BI->getType(), T)) {
+ for (const auto &BI : bases()) {
+ if (Context.hasSameUnqualifiedType(BI.getType(), T)) {
data().IsStandardLayout = false;
break;
}
@@ -862,6 +875,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (FieldRec->hasUninitializedReferenceMember() &&
!Field->hasInClassInitializer())
data().HasUninitializedReferenceMember = true;
+
+ // C++11 [class.union]p8, DR1460:
+ // a non-static data member of an anonymous union that is a member of
+ // X is also a variant member of X.
+ if (FieldRec->hasVariantMembers() &&
+ Field->isAnonymousStructOrUnion())
+ data().HasVariantMembers = true;
}
} else {
// Base element type of field is a non-class type.
@@ -928,9 +948,11 @@ void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) {
else if (Constructor->isConstexpr())
// We may now know that the constructor is constexpr.
data().HasConstexprNonCopyMoveConstructor = true;
- } else if (isa<CXXDestructorDecl>(D))
+ } else if (isa<CXXDestructorDecl>(D)) {
SMKind |= SMF_Destructor;
- else if (D->isCopyAssignmentOperator())
+ if (!D->isTrivial() || D->getAccess() != AS_public || D->isDeleted())
+ data().HasIrrelevantDestructor = false;
+ } else if (D->isCopyAssignmentOperator())
SMKind |= SMF_CopyAssignment;
else if (D->isMoveAssignmentOperator())
SMKind |= SMF_MoveAssignment;
@@ -959,7 +981,7 @@ bool CXXRecordDecl::isGenericLambda() const {
}
CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const {
- if (!isLambda()) return 0;
+ if (!isLambda()) return nullptr;
DeclarationName Name =
getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
DeclContext::lookup_const_result Calls = lookup(Name);
@@ -976,11 +998,11 @@ CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const {
}
CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
- if (!isLambda()) return 0;
+ if (!isLambda()) return nullptr;
DeclarationName Name =
&getASTContext().Idents.get(getLambdaStaticInvokerName());
DeclContext::lookup_const_result Invoker = lookup(Name);
- if (Invoker.empty()) return 0;
+ if (Invoker.empty()) return nullptr;
assert(Invoker.size() == 1 && "More than one static invoker operator!");
NamedDecl *InvokerFun = Invoker.front();
if (FunctionTemplateDecl *InvokerTemplate =
@@ -994,11 +1016,11 @@ void CXXRecordDecl::getCaptureFields(
llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
FieldDecl *&ThisCapture) const {
Captures.clear();
- ThisCapture = 0;
+ ThisCapture = nullptr;
LambdaDefinitionData &Lambda = getLambdaData();
RecordDecl::field_iterator Field = field_begin();
- for (LambdaExpr::Capture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
+ for (const LambdaCapture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
C != CEnd; ++C, ++Field) {
if (C->capturesThis())
ThisCapture = *Field;
@@ -1010,21 +1032,17 @@ void CXXRecordDecl::getCaptureFields(
TemplateParameterList *
CXXRecordDecl::getGenericLambdaTemplateParameterList() const {
- if (!isLambda()) return 0;
+ if (!isLambda()) return nullptr;
CXXMethodDecl *CallOp = getLambdaCallOperator();
if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate())
return Tmpl->getTemplateParameters();
- return 0;
+ return nullptr;
}
static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
- QualType T;
- if (isa<UsingShadowDecl>(Conv))
- Conv = cast<UsingShadowDecl>(Conv)->getTargetDecl();
- if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv))
- T = ConvTemp->getTemplatedDecl()->getResultType();
- else
- T = cast<CXXConversionDecl>(Conv)->getConversionType();
+ QualType T =
+ cast<CXXConversionDecl>(Conv->getUnderlyingDecl()->getAsFunction())
+ ->getConversionType();
return Context.getCanonicalType(T);
}
@@ -1087,14 +1105,13 @@ static void CollectVisibleConversions(ASTContext &Context,
}
// Collect information recursively from any base classes.
- for (CXXRecordDecl::base_class_iterator
- I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
- const RecordType *RT = I->getType()->getAs<RecordType>();
+ for (const auto &I : Record->bases()) {
+ const RecordType *RT = I.getType()->getAs<RecordType>();
if (!RT) continue;
AccessSpecifier BaseAccess
- = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier());
- bool BaseInVirtual = InVirtual || I->isVirtual();
+ = CXXRecordDecl::MergeAccess(Access, I.getAccessSpecifier());
+ bool BaseInVirtual = InVirtual || I.isVirtual();
CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess,
@@ -1130,13 +1147,12 @@ static void CollectVisibleConversions(ASTContext &Context,
HiddenTypes.insert(GetConversionType(Context, ConvI.getDecl()));
// Recursively collect conversions from base classes.
- for (CXXRecordDecl::base_class_iterator
- I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
- const RecordType *RT = I->getType()->getAs<RecordType>();
+ for (const auto &I : Record->bases()) {
+ const RecordType *RT = I.getType()->getAs<RecordType>();
if (!RT) continue;
CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()),
- I->isVirtual(), I->getAccessSpecifier(),
+ I.isVirtual(), I.getAccessSpecifier(),
HiddenTypes, Output, VBaseCs, HiddenVBaseCs);
}
@@ -1197,8 +1213,8 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
-
- return 0;
+
+ return nullptr;
}
void
@@ -1248,14 +1264,14 @@ CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
DeclContext::lookup_const_result R = lookup(Name);
if (R.empty())
- return 0;
+ return nullptr;
CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(R.front());
return Dtor;
}
void CXXRecordDecl::completeDefinition() {
- completeDefinition(0);
+ completeDefinition(nullptr);
}
void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
@@ -1317,11 +1333,9 @@ bool CXXRecordDecl::mayBeAbstract() const {
isDependentContext())
return false;
- for (CXXRecordDecl::base_class_const_iterator B = bases_begin(),
- BEnd = bases_end();
- B != BEnd; ++B) {
+ for (const auto &B : bases()) {
CXXRecordDecl *BaseDecl
- = cast<CXXRecordDecl>(B->getType()->getAs<RecordType>()->getDecl());
+ = cast<CXXRecordDecl>(B.getType()->getAs<RecordType>()->getDecl());
if (BaseDecl->isAbstract())
return true;
}
@@ -1369,7 +1383,7 @@ CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
if (MayBeBase && recursivelyOverrides(this, MD))
return MD;
}
- return NULL;
+ return nullptr;
}
lookup_const_result Candidates = RD->lookup(getDeclName());
@@ -1383,9 +1397,8 @@ CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
return MD;
}
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- const RecordType *RT = I->getType()->getAs<RecordType>();
+ for (const auto &I : RD->bases()) {
+ const RecordType *RT = I.getType()->getAs<RecordType>();
if (!RT)
continue;
const CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
@@ -1394,7 +1407,7 @@ CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
return T;
}
- return NULL;
+ return nullptr;
}
CXXMethodDecl *
@@ -1404,17 +1417,15 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
QualType T, TypeSourceInfo *TInfo,
StorageClass SC, bool isInline,
bool isConstexpr, SourceLocation EndLocation) {
- return new (C) CXXMethodDecl(CXXMethod, RD, StartLoc, NameInfo, T, TInfo,
- SC, isInline, isConstexpr,
- EndLocation);
+ return new (C, RD) CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo,
+ T, TInfo, SC, isInline, isConstexpr,
+ EndLocation);
}
CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXMethodDecl));
- return new (Mem) CXXMethodDecl(CXXMethod, 0, SourceLocation(),
- DeclarationNameInfo(), QualType(),
- 0, SC_None, false, false,
- SourceLocation());
+ return new (C, ID) CXXMethodDecl(CXXMethod, C, nullptr, SourceLocation(),
+ DeclarationNameInfo(), QualType(), nullptr,
+ SC_None, false, false, SourceLocation());
}
bool CXXMethodDecl::isUsualDeallocationFunction() const {
@@ -1511,12 +1522,12 @@ void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
}
CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
- if (isa<CXXConstructorDecl>(this)) return 0;
+ if (isa<CXXConstructorDecl>(this)) return nullptr;
return getASTContext().overridden_methods_begin(this);
}
CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
- if (isa<CXXConstructorDecl>(this)) return 0;
+ if (isa<CXXConstructorDecl>(this)) return nullptr;
return getASTContext().overridden_methods_end(this);
}
@@ -1614,7 +1625,7 @@ CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
VarDecl **Indices,
unsigned NumIndices)
: Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
- LParenLoc(L), RParenLoc(R), IsVirtual(false),
+ LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
{
VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
@@ -1646,7 +1657,7 @@ const Type *CXXCtorInitializer::getBaseClass() const {
if (isBaseInitializer())
return Initializee.get<TypeSourceInfo*>()->getType().getTypePtr();
else
- return 0;
+ return nullptr;
}
SourceLocation CXXCtorInitializer::getSourceLocation() const {
@@ -1677,9 +1688,9 @@ void CXXConstructorDecl::anchor() { }
CXXConstructorDecl *
CXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXConstructorDecl));
- return new (Mem) CXXConstructorDecl(0, SourceLocation(),DeclarationNameInfo(),
- QualType(), 0, false, false, false,false);
+ return new (C, ID) CXXConstructorDecl(C, nullptr, SourceLocation(),
+ DeclarationNameInfo(), QualType(),
+ nullptr, false, false, false, false);
}
CXXConstructorDecl *
@@ -1692,9 +1703,9 @@ CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXConstructorName &&
"Name must refer to a constructor");
- return new (C) CXXConstructorDecl(RD, StartLoc, NameInfo, T, TInfo,
- isExplicit, isInline, isImplicitlyDeclared,
- isConstexpr);
+ return new (C, RD) CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo,
+ isExplicit, isInline,
+ isImplicitlyDeclared, isConstexpr);
}
CXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const {
@@ -1702,8 +1713,8 @@ CXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const {
Expr *E = (*init_begin())->getInit()->IgnoreImplicit();
if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(E))
return Construct->getConstructor();
-
- return 0;
+
+ return nullptr;
}
bool CXXConstructorDecl::isDefaultConstructor() const {
@@ -1739,8 +1750,8 @@ bool CXXConstructorDecl::isCopyOrMoveConstructor(unsigned &TypeQuals) const {
// all other parameters have default arguments.
if ((getNumParams() < 1) ||
(getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
- (getPrimaryTemplate() != 0) ||
- (getDescribedFunctionTemplate() != 0))
+ (getPrimaryTemplate() != nullptr) ||
+ (getDescribedFunctionTemplate() != nullptr))
return false;
const ParmVarDecl *Param = getParamDecl(0);
@@ -1788,8 +1799,8 @@ bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
bool CXXConstructorDecl::isSpecializationCopyingObject() const {
if ((getNumParams() < 1) ||
(getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
- (getPrimaryTemplate() == 0) ||
- (getDescribedFunctionTemplate() != 0))
+ (getPrimaryTemplate() == nullptr) ||
+ (getDescribedFunctionTemplate() != nullptr))
return false;
const ParmVarDecl *Param = getParamDecl(0);
@@ -1810,7 +1821,7 @@ const CXXConstructorDecl *CXXConstructorDecl::getInheritedConstructor() const {
// Hack: we store the inherited constructor in the overridden method table
method_iterator It = getASTContext().overridden_methods_begin(this);
if (It == getASTContext().overridden_methods_end(this))
- return 0;
+ return nullptr;
return cast<CXXConstructorDecl>(*It);
}
@@ -1827,9 +1838,9 @@ void CXXDestructorDecl::anchor() { }
CXXDestructorDecl *
CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXDestructorDecl));
- return new (Mem) CXXDestructorDecl(0, SourceLocation(), DeclarationNameInfo(),
- QualType(), 0, false, false);
+ return new (C, ID)
+ CXXDestructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(),
+ QualType(), nullptr, false, false);
}
CXXDestructorDecl *
@@ -1841,18 +1852,18 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXDestructorName &&
"Name must refer to a destructor");
- return new (C) CXXDestructorDecl(RD, StartLoc, NameInfo, T, TInfo, isInline,
- isImplicitlyDeclared);
+ return new (C, RD) CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo,
+ isInline, isImplicitlyDeclared);
}
void CXXConversionDecl::anchor() { }
CXXConversionDecl *
CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXConversionDecl));
- return new (Mem) CXXConversionDecl(0, SourceLocation(), DeclarationNameInfo(),
- QualType(), 0, false, false, false,
- SourceLocation());
+ return new (C, ID) CXXConversionDecl(C, nullptr, SourceLocation(),
+ DeclarationNameInfo(), QualType(),
+ nullptr, false, false, false,
+ SourceLocation());
}
CXXConversionDecl *
@@ -1865,9 +1876,9 @@ CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXConversionFunctionName &&
"Name must refer to a conversion function");
- return new (C) CXXConversionDecl(RD, StartLoc, NameInfo, T, TInfo,
- isInline, isExplicit, isConstexpr,
- EndLocation);
+ return new (C, RD) CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo,
+ isInline, isExplicit, isConstexpr,
+ EndLocation);
}
bool CXXConversionDecl::isLambdaToBlockPointerConversion() const {
@@ -1883,13 +1894,13 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
SourceLocation LangLoc,
LanguageIDs Lang,
bool HasBraces) {
- return new (C) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces);
+ return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces);
}
-LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(LinkageSpecDecl));
- return new (Mem) LinkageSpecDecl(0, SourceLocation(), SourceLocation(),
- lang_c, false);
+LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID) {
+ return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(),
+ SourceLocation(), lang_c, false);
}
void UsingDirectiveDecl::anchor() { }
@@ -1903,16 +1914,16 @@ UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
DeclContext *CommonAncestor) {
if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
Used = NS->getOriginalNamespace();
- return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc,
- IdentLoc, Used, CommonAncestor);
+ return new (C, DC) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc,
+ IdentLoc, Used, CommonAncestor);
}
-UsingDirectiveDecl *
-UsingDirectiveDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingDirectiveDecl));
- return new (Mem) UsingDirectiveDecl(0, SourceLocation(), SourceLocation(),
- NestedNameSpecifierLoc(),
- SourceLocation(), 0, 0);
+UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID) {
+ return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(),
+ SourceLocation(),
+ NestedNameSpecifierLoc(),
+ SourceLocation(), nullptr, nullptr);
}
NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
@@ -1922,17 +1933,14 @@ NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
return cast_or_null<NamespaceDecl>(NominatedNamespace);
}
-void NamespaceDecl::anchor() { }
-
-NamespaceDecl::NamespaceDecl(DeclContext *DC, bool Inline,
- SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- NamespaceDecl *PrevDecl)
- : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
- LocStart(StartLoc), RBraceLoc(), AnonOrFirstNamespaceAndInline(0, Inline)
-{
+NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, NamespaceDecl *PrevDecl)
+ : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
+ redeclarable_base(C), LocStart(StartLoc), RBraceLoc(),
+ AnonOrFirstNamespaceAndInline(nullptr, Inline) {
setPreviousDecl(PrevDecl);
-
+
if (PrevDecl)
AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace());
}
@@ -1941,13 +1949,23 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
bool Inline, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
NamespaceDecl *PrevDecl) {
- return new (C) NamespaceDecl(DC, Inline, StartLoc, IdLoc, Id, PrevDecl);
+ return new (C, DC) NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id,
+ PrevDecl);
}
NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NamespaceDecl));
- return new (Mem) NamespaceDecl(0, false, SourceLocation(), SourceLocation(),
- 0, 0);
+ return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(),
+ SourceLocation(), nullptr, nullptr);
+}
+
+NamespaceDecl *NamespaceDecl::getNextRedeclarationImpl() {
+ return getNextRedeclaration();
+}
+NamespaceDecl *NamespaceDecl::getPreviousDeclImpl() {
+ return getPreviousDecl();
+}
+NamespaceDecl *NamespaceDecl::getMostRecentDeclImpl() {
+ return getMostRecentDecl();
}
void NamespaceAliasDecl::anchor() { }
@@ -1961,24 +1979,24 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
NamedDecl *Namespace) {
if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
Namespace = NS->getOriginalNamespace();
- return new (C) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias,
- QualifierLoc, IdentLoc, Namespace);
+ return new (C, DC) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias,
+ QualifierLoc, IdentLoc, Namespace);
}
NamespaceAliasDecl *
NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NamespaceAliasDecl));
- return new (Mem) NamespaceAliasDecl(0, SourceLocation(), SourceLocation(), 0,
- NestedNameSpecifierLoc(),
- SourceLocation(), 0);
+ return new (C, ID) NamespaceAliasDecl(nullptr, SourceLocation(),
+ SourceLocation(), nullptr,
+ NestedNameSpecifierLoc(),
+ SourceLocation(), nullptr);
}
void UsingShadowDecl::anchor() { }
UsingShadowDecl *
UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingShadowDecl));
- return new (Mem) UsingShadowDecl(0, SourceLocation(), 0, 0);
+ return new (C, ID) UsingShadowDecl(C, nullptr, SourceLocation(),
+ nullptr, nullptr);
}
UsingDecl *UsingShadowDecl::getUsingDecl() const {
@@ -2026,13 +2044,13 @@ UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
bool HasTypename) {
- return new (C) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename);
+ return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename);
}
UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingDecl));
- return new (Mem) UsingDecl(0, SourceLocation(), NestedNameSpecifierLoc(),
- DeclarationNameInfo(), false);
+ return new (C, ID) UsingDecl(nullptr, SourceLocation(),
+ NestedNameSpecifierLoc(), DeclarationNameInfo(),
+ false);
}
SourceRange UsingDecl::getSourceRange() const {
@@ -2048,16 +2066,16 @@ UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation UsingLoc,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo) {
- return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
- QualifierLoc, NameInfo);
+ return new (C, DC) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
+ QualifierLoc, NameInfo);
}
UnresolvedUsingValueDecl *
UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UnresolvedUsingValueDecl));
- return new (Mem) UnresolvedUsingValueDecl(0, QualType(), SourceLocation(),
- NestedNameSpecifierLoc(),
- DeclarationNameInfo());
+ return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(),
+ SourceLocation(),
+ NestedNameSpecifierLoc(),
+ DeclarationNameInfo());
}
SourceRange UnresolvedUsingValueDecl::getSourceRange() const {
@@ -2075,20 +2093,16 @@ UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TargetNameLoc,
DeclarationName TargetName) {
- return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
- QualifierLoc, TargetNameLoc,
- TargetName.getAsIdentifierInfo());
+ return new (C, DC) UnresolvedUsingTypenameDecl(
+ DC, UsingLoc, TypenameLoc, QualifierLoc, TargetNameLoc,
+ TargetName.getAsIdentifierInfo());
}
UnresolvedUsingTypenameDecl *
UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID,
- sizeof(UnresolvedUsingTypenameDecl));
- return new (Mem) UnresolvedUsingTypenameDecl(0, SourceLocation(),
- SourceLocation(),
- NestedNameSpecifierLoc(),
- SourceLocation(),
- 0);
+ return new (C, ID) UnresolvedUsingTypenameDecl(
+ nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(),
+ SourceLocation(), nullptr);
}
void StaticAssertDecl::anchor() { }
@@ -2099,15 +2113,30 @@ StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
StringLiteral *Message,
SourceLocation RParenLoc,
bool Failed) {
- return new (C) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message,
- RParenLoc, Failed);
+ return new (C, DC) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message,
+ RParenLoc, Failed);
}
-StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C,
+StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(StaticAssertDecl));
- return new (Mem) StaticAssertDecl(0, SourceLocation(), 0, 0,
- SourceLocation(), false);
+ return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr,
+ nullptr, SourceLocation(), false);
+}
+
+MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, DeclarationName N,
+ QualType T, TypeSourceInfo *TInfo,
+ SourceLocation StartL,
+ IdentifierInfo *Getter,
+ IdentifierInfo *Setter) {
+ return new (C, DC) MSPropertyDecl(DC, L, N, T, TInfo, StartL, Getter, Setter);
+}
+
+MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID) {
+ return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(),
+ DeclarationName(), QualType(), nullptr,
+ SourceLocation(), nullptr, nullptr);
}
static const char *getAccessName(AccessSpecifier AS) {
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclFriend.cpp b/contrib/llvm/tools/clang/lib/AST/DeclFriend.cpp
index 1c639d6..a996cab 100644
--- a/contrib/llvm/tools/clang/lib/AST/DeclFriend.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/DeclFriend.cpp
@@ -46,25 +46,21 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
}
#endif
- std::size_t Size = sizeof(FriendDecl)
- + FriendTypeTPLists.size() * sizeof(TemplateParameterList*);
- void *Mem = C.Allocate(Size);
- FriendDecl *FD = new (Mem) FriendDecl(DC, L, Friend, FriendL,
- FriendTypeTPLists);
+ std::size_t Extra = FriendTypeTPLists.size() * sizeof(TemplateParameterList*);
+ FriendDecl *FD = new (C, DC, Extra) FriendDecl(DC, L, Friend, FriendL,
+ FriendTypeTPLists);
cast<CXXRecordDecl>(DC)->pushFriendDecl(FD);
return FD;
}
FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned FriendTypeNumTPLists) {
- std::size_t Size = sizeof(FriendDecl)
- + FriendTypeNumTPLists * sizeof(TemplateParameterList*);
- void *Mem = AllocateDeserializedDecl(C, ID, Size);
- return new (Mem) FriendDecl(EmptyShell(), FriendTypeNumTPLists);
+ std::size_t Extra = FriendTypeNumTPLists * sizeof(TemplateParameterList*);
+ return new (C, ID, Extra) FriendDecl(EmptyShell(), FriendTypeNumTPLists);
}
FriendDecl *CXXRecordDecl::getFirstFriend() const {
ExternalASTSource *Source = getParentASTContext().getExternalSource();
Decl *First = data().FirstFriend.get(Source);
- return First ? cast<FriendDecl>(First) : 0;
+ return First ? cast<FriendDecl>(First) : nullptr;
}
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp b/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp
index b2b5b70..2204dff 100644
--- a/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/DeclObjC.cpp
@@ -25,7 +25,7 @@ using namespace clang;
//===----------------------------------------------------------------------===//
void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
- List = 0;
+ List = nullptr;
if (Elts == 0) return; // Setting to an empty list is a noop.
@@ -60,7 +60,7 @@ ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
return ivar;
}
- return 0;
+ return nullptr;
}
// Get the local instance/class method declared in this interface.
@@ -72,7 +72,7 @@ ObjCContainerDecl::getMethod(Selector Sel, bool isInstance,
if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
if (const ObjCProtocolDecl *Def = Proto->getDefinition())
if (Def->isHidden() && !AllowHidden)
- return 0;
+ return nullptr;
}
// Since instance & class methods can have the same name, the loop below
@@ -90,7 +90,7 @@ ObjCContainerDecl::getMethod(Selector Sel, bool isInstance,
if (MD && MD->isInstanceMethod() == isInstance)
return MD;
}
- return 0;
+ return nullptr;
}
/// HasUserDeclaredSetterMethod - This routine returns 'true' if a user declared setter
@@ -112,11 +112,7 @@ ObjCContainerDecl::HasUserDeclaredSetterMethod(const ObjCPropertyDecl *Property)
if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
// Also look into categories, including class extensions, looking
// for a user declared instance method.
- for (ObjCInterfaceDecl::visible_categories_iterator
- Cat = ID->visible_categories_begin(),
- CatEnd = ID->visible_categories_end();
- Cat != CatEnd;
- ++Cat) {
+ for (const auto *Cat : ID->visible_categories()) {
if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))
if (!MD->isImplicit())
return true;
@@ -125,8 +121,7 @@ ObjCContainerDecl::HasUserDeclaredSetterMethod(const ObjCPropertyDecl *Property)
// Also search through the categories looking for a 'readwrite' declaration
// of this property. If one found, presumably a setter will be provided
// (properties declared in categories will not get auto-synthesized).
- for (ObjCContainerDecl::prop_iterator P = Cat->prop_begin(),
- E = Cat->prop_end(); P != E; ++P)
+ for (const auto *P : Cat->properties())
if (P->getIdentifier() == Property->getIdentifier()) {
if (P->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite)
return true;
@@ -135,13 +130,10 @@ ObjCContainerDecl::HasUserDeclaredSetterMethod(const ObjCPropertyDecl *Property)
}
// Also look into protocols, for a user declared instance method.
- for (ObjCInterfaceDecl::all_protocol_iterator P =
- ID->all_referenced_protocol_begin(),
- PE = ID->all_referenced_protocol_end(); P != PE; ++P) {
- ObjCProtocolDecl *Proto = (*P);
+ for (const auto *Proto : ID->all_referenced_protocols())
if (Proto->HasUserDeclaredSetterMethod(Property))
return true;
- }
+
// And in its super class.
ObjCInterfaceDecl *OSC = ID->getSuperClass();
while (OSC) {
@@ -151,11 +143,9 @@ ObjCContainerDecl::HasUserDeclaredSetterMethod(const ObjCPropertyDecl *Property)
}
}
if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(this))
- for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
- E = PD->protocol_end(); PI != E; ++PI) {
- if ((*PI)->HasUserDeclaredSetterMethod(Property))
+ for (const auto *PI : PD->protocols())
+ if (PI->HasUserDeclaredSetterMethod(Property))
return true;
- }
return false;
}
@@ -167,7 +157,7 @@ ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
if (const ObjCProtocolDecl *Def = Proto->getDefinition())
if (Def->isHidden())
- return 0;
+ return nullptr;
}
DeclContext::lookup_const_result R = DC->lookup(propertyID);
@@ -176,7 +166,7 @@ ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
return PD;
- return 0;
+ return nullptr;
}
IdentifierInfo *
@@ -197,7 +187,7 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
if (const ObjCProtocolDecl *Def = Proto->getDefinition())
if (Def->isHidden())
- return 0;
+ return nullptr;
}
if (ObjCPropertyDecl *PD =
@@ -209,29 +199,23 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
break;
case Decl::ObjCProtocol: {
const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
- for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
- E = PID->protocol_end(); I != E; ++I)
- if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+ for (const auto *I : PID->protocols())
+ if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
return P;
break;
}
case Decl::ObjCInterface: {
const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
// Look through categories (but not extensions).
- for (ObjCInterfaceDecl::visible_categories_iterator
- Cat = OID->visible_categories_begin(),
- CatEnd = OID->visible_categories_end();
- Cat != CatEnd; ++Cat) {
+ for (const auto *Cat : OID->visible_categories()) {
if (!Cat->IsClassExtension())
if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
return P;
}
// Look through protocols.
- for (ObjCInterfaceDecl::all_protocol_iterator
- I = OID->all_referenced_protocol_begin(),
- E = OID->all_referenced_protocol_end(); I != E; ++I)
- if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+ for (const auto *I : OID->all_referenced_protocols())
+ if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
return P;
// Finally, check the super class.
@@ -243,15 +227,13 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
// Look through protocols.
if (!OCD->IsClassExtension())
- for (ObjCCategoryDecl::protocol_iterator
- I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
- if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
- return P;
-
+ for (const auto *I : OCD->protocols())
+ if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
+ return P;
break;
}
}
- return 0;
+ return nullptr;
}
void ObjCInterfaceDecl::anchor() { }
@@ -265,8 +247,8 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
IdentifierInfo *PropertyId) const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
-
+ return nullptr;
+
if (data().ExternallyCompleted)
LoadExternalDefinition();
@@ -275,27 +257,21 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
return PD;
// Look through protocols.
- for (ObjCInterfaceDecl::all_protocol_iterator
- I = all_referenced_protocol_begin(),
- E = all_referenced_protocol_end(); I != E; ++I)
- if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+ for (const auto *I : all_referenced_protocols())
+ if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
return P;
- return 0;
+ return nullptr;
}
void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
PropertyDeclOrder &PO) const {
- for (ObjCContainerDecl::prop_iterator P = prop_begin(),
- E = prop_end(); P != E; ++P) {
- ObjCPropertyDecl *Prop = *P;
+ for (auto *Prop : properties()) {
PM[Prop->getIdentifier()] = Prop;
PO.push_back(Prop);
}
- for (ObjCInterfaceDecl::all_protocol_iterator
- PI = all_referenced_protocol_begin(),
- E = all_referenced_protocol_end(); PI != E; ++PI)
- (*PI)->collectPropertiesToImplement(PM, PO);
+ for (const auto *PI : all_referenced_protocols())
+ PI->collectPropertiesToImplement(PM, PO);
// Note, the properties declared only in class extensions are still copied
// into the main @interface's property list, and therefore we don't
// explicitly, have to search class extension properties.
@@ -318,7 +294,7 @@ const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
return Class;
Class = Class->getSuperClass();
}
- return 0;
+ return nullptr;
}
void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
@@ -341,10 +317,7 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
for (unsigned i = 0; i < ExtNum; i++) {
bool protocolExists = false;
ObjCProtocolDecl *ProtoInExtension = ExtList[i];
- for (all_protocol_iterator
- p = all_referenced_protocol_begin(),
- e = all_referenced_protocol_end(); p != e; ++p) {
- ObjCProtocolDecl *Proto = (*p);
+ for (auto *Proto : all_referenced_protocols()) {
if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
protocolExists = true;
break;
@@ -360,14 +333,132 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
return;
// Merge ProtocolRefs into class's protocol list;
- for (all_protocol_iterator p = all_referenced_protocol_begin(),
- e = all_referenced_protocol_end(); p != e; ++p) {
- ProtocolRefs.push_back(*p);
+ for (auto *P : all_referenced_protocols()) {
+ ProtocolRefs.push_back(P);
}
data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
}
+const ObjCInterfaceDecl *
+ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {
+ const ObjCInterfaceDecl *IFace = this;
+ while (IFace) {
+ if (IFace->hasDesignatedInitializers())
+ return IFace;
+ if (!IFace->inheritsDesignatedInitializers())
+ break;
+ IFace = IFace->getSuperClass();
+ }
+ return nullptr;
+}
+
+static bool isIntroducingInitializers(const ObjCInterfaceDecl *D) {
+ for (const auto *MD : D->instance_methods()) {
+ if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
+ return true;
+ }
+ for (const auto *Ext : D->visible_extensions()) {
+ for (const auto *MD : Ext->instance_methods()) {
+ if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
+ return true;
+ }
+ }
+ if (const auto *ImplD = D->getImplementation()) {
+ for (const auto *MD : ImplD->instance_methods()) {
+ if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
+ switch (data().InheritedDesignatedInitializers) {
+ case DefinitionData::IDI_Inherited:
+ return true;
+ case DefinitionData::IDI_NotInherited:
+ return false;
+ case DefinitionData::IDI_Unknown: {
+ // If the class introduced initializers we conservatively assume that we
+ // don't know if any of them is a designated initializer to avoid possible
+ // misleading warnings.
+ if (isIntroducingInitializers(this)) {
+ data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
+ } else {
+ if (auto SuperD = getSuperClass()) {
+ data().InheritedDesignatedInitializers =
+ SuperD->declaresOrInheritsDesignatedInitializers() ?
+ DefinitionData::IDI_Inherited :
+ DefinitionData::IDI_NotInherited;
+ } else {
+ data().InheritedDesignatedInitializers =
+ DefinitionData::IDI_NotInherited;
+ }
+ }
+ assert(data().InheritedDesignatedInitializers
+ != DefinitionData::IDI_Unknown);
+ return data().InheritedDesignatedInitializers ==
+ DefinitionData::IDI_Inherited;
+ }
+ }
+
+ llvm_unreachable("unexpected InheritedDesignatedInitializers value");
+}
+
+void ObjCInterfaceDecl::getDesignatedInitializers(
+ llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {
+ // Check for a complete definition and recover if not so.
+ if (!isThisDeclarationADefinition())
+ return;
+ if (data().ExternallyCompleted)
+ LoadExternalDefinition();
+
+ const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
+ if (!IFace)
+ return;
+
+ for (const auto *MD : IFace->instance_methods())
+ if (MD->isThisDeclarationADesignatedInitializer())
+ Methods.push_back(MD);
+ for (const auto *Ext : IFace->visible_extensions()) {
+ for (const auto *MD : Ext->instance_methods())
+ if (MD->isThisDeclarationADesignatedInitializer())
+ Methods.push_back(MD);
+ }
+}
+
+bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
+ const ObjCMethodDecl **InitMethod) const {
+ // Check for a complete definition and recover if not so.
+ if (!isThisDeclarationADefinition())
+ return false;
+ if (data().ExternallyCompleted)
+ LoadExternalDefinition();
+
+ const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
+ if (!IFace)
+ return false;
+
+ if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) {
+ if (MD->isThisDeclarationADesignatedInitializer()) {
+ if (InitMethod)
+ *InitMethod = MD;
+ return true;
+ }
+ }
+ for (const auto *Ext : IFace->visible_extensions()) {
+ if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) {
+ if (MD->isThisDeclarationADesignatedInitializer()) {
+ if (InitMethod)
+ *InitMethod = MD;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void ObjCInterfaceDecl::allocateDefinitionData() {
assert(!hasDefinition() && "ObjC class already has a definition");
Data.setPointer(new (getASTContext()) DefinitionData());
@@ -382,9 +473,8 @@ void ObjCInterfaceDecl::startDefinition() {
allocateDefinitionData();
// Update all of the declarations with a pointer to the definition.
- for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
- RD != RDEnd; ++RD) {
- if (*RD != this)
+ for (auto RD : redecls()) {
+ if (RD != this)
RD->Data = Data;
}
}
@@ -393,22 +483,19 @@ ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
ObjCInterfaceDecl *&clsDeclared) {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
+ return nullptr;
if (data().ExternallyCompleted)
LoadExternalDefinition();
ObjCInterfaceDecl* ClassDecl = this;
- while (ClassDecl != NULL) {
+ while (ClassDecl != nullptr) {
if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
clsDeclared = ClassDecl;
return I;
}
- for (ObjCInterfaceDecl::visible_extensions_iterator
- Ext = ClassDecl->visible_extensions_begin(),
- ExtEnd = ClassDecl->visible_extensions_end();
- Ext != ExtEnd; ++Ext) {
+ for (const auto *Ext : ClassDecl->visible_extensions()) {
if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
clsDeclared = ClassDecl;
return I;
@@ -417,7 +504,7 @@ ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
ClassDecl = ClassDecl->getSuperClass();
}
- return NULL;
+ return nullptr;
}
/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
@@ -427,29 +514,27 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
const IdentifierInfo*ICName) {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
+ return nullptr;
if (data().ExternallyCompleted)
LoadExternalDefinition();
ObjCInterfaceDecl* ClassDecl = this;
- while (ClassDecl != NULL) {
+ while (ClassDecl != nullptr) {
if (ClassDecl->getIdentifier() == ICName)
return ClassDecl;
ClassDecl = ClassDecl->getSuperClass();
}
- return NULL;
+ return nullptr;
}
ObjCProtocolDecl *
ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
- for (ObjCInterfaceDecl::all_protocol_iterator P =
- all_referenced_protocol_begin(), PE = all_referenced_protocol_end();
- P != PE; ++P)
- if ((*P)->lookupProtocolNamed(Name))
- return (*P);
+ for (auto *P : all_referenced_protocols())
+ if (P->lookupProtocolNamed(Name))
+ return P;
ObjCInterfaceDecl *SuperClass = getSuperClass();
- return SuperClass ? SuperClass->lookupNestedProtocol(Name) : NULL;
+ return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr;
}
/// lookupMethod - This method returns an instance/class method by looking in
@@ -457,37 +542,34 @@ ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
/// When argument category "C" is specified, any implicit method found
/// in this category is ignored.
ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
- bool isInstance,
- bool shallowCategoryLookup,
- const ObjCCategoryDecl *C) const {
+ bool isInstance,
+ bool shallowCategoryLookup,
+ bool followSuper,
+ const ObjCCategoryDecl *C) const
+{
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
+ return nullptr;
const ObjCInterfaceDecl* ClassDecl = this;
- ObjCMethodDecl *MethodDecl = 0;
+ ObjCMethodDecl *MethodDecl = nullptr;
if (data().ExternallyCompleted)
LoadExternalDefinition();
- while (ClassDecl != NULL) {
+ while (ClassDecl) {
if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
return MethodDecl;
// Didn't find one yet - look through protocols.
- for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
- E = ClassDecl->protocol_end();
- I != E; ++I)
- if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+ for (const auto *I : ClassDecl->protocols())
+ if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
return MethodDecl;
// Didn't find one yet - now look through categories.
- for (ObjCInterfaceDecl::visible_categories_iterator
- Cat = ClassDecl->visible_categories_begin(),
- CatEnd = ClassDecl->visible_categories_end();
- Cat != CatEnd; ++Cat) {
+ for (const auto *Cat : ClassDecl->visible_categories()) {
if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
- if (C != (*Cat) || !MethodDecl->isImplicit())
+ if (C != Cat || !MethodDecl->isImplicit())
return MethodDecl;
if (!shallowCategoryLookup) {
@@ -497,14 +579,18 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
- if (C != (*Cat) || !MethodDecl->isImplicit())
+ if (C != Cat || !MethodDecl->isImplicit())
return MethodDecl;
}
}
-
+
+ if (!followSuper)
+ return nullptr;
+
+ // Get the super class (if any).
ClassDecl = ClassDecl->getSuperClass();
}
- return NULL;
+ return nullptr;
}
// Will search "local" class/category implementations for a method decl.
@@ -515,12 +601,12 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
bool Instance) const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
+ return nullptr;
if (data().ExternallyCompleted)
LoadExternalDefinition();
- ObjCMethodDecl *Method = 0;
+ ObjCMethodDecl *Method = nullptr;
if (ObjCImplementationDecl *ImpDecl = getImplementation())
Method = Instance ? ImpDecl->getInstanceMethod(Sel)
: ImpDecl->getClassMethod(Sel);
@@ -550,31 +636,38 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
// ObjCMethodDecl
//===----------------------------------------------------------------------===//
-ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
- SourceLocation beginLoc,
- SourceLocation endLoc,
- Selector SelInfo, QualType T,
- TypeSourceInfo *ResultTInfo,
- DeclContext *contextDecl,
- bool isInstance,
- bool isVariadic,
- bool isPropertyAccessor,
- bool isImplicitlyDeclared,
- bool isDefined,
- ImplementationControl impControl,
- bool HasRelatedResultType) {
- return new (C) ObjCMethodDecl(beginLoc, endLoc,
- SelInfo, T, ResultTInfo, contextDecl,
- isInstance, isVariadic, isPropertyAccessor,
- isImplicitlyDeclared, isDefined,
- impControl,
- HasRelatedResultType);
+ObjCMethodDecl *ObjCMethodDecl::Create(
+ ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
+ Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+ DeclContext *contextDecl, bool isInstance, bool isVariadic,
+ bool isPropertyAccessor, bool isImplicitlyDeclared, bool isDefined,
+ ImplementationControl impControl, bool HasRelatedResultType) {
+ return new (C, contextDecl) ObjCMethodDecl(
+ beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,
+ isVariadic, isPropertyAccessor, isImplicitlyDeclared, isDefined,
+ impControl, HasRelatedResultType);
}
ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCMethodDecl));
- return new (Mem) ObjCMethodDecl(SourceLocation(), SourceLocation(),
- Selector(), QualType(), 0, 0);
+ return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
+ Selector(), QualType(), nullptr, nullptr);
+}
+
+bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
+ return getMethodFamily() == OMF_init &&
+ hasAttr<ObjCDesignatedInitializerAttr>();
+}
+
+bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
+ const ObjCMethodDecl **InitMethod) const {
+ if (getMethodFamily() != OMF_init)
+ return false;
+ const DeclContext *DC = getDeclContext();
+ if (isa<ObjCProtocolDecl>(DC))
+ return false;
+ if (const ObjCInterfaceDecl *ID = getClassInterface())
+ return ID->isDesignatedInitializer(getSelector(), InitMethod);
+ return false;
}
Stmt *ObjCMethodDecl::getBody() const {
@@ -591,7 +684,7 @@ void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
ArrayRef<ParmVarDecl*> Params,
ArrayRef<SourceLocation> SelLocs) {
- ParamsAndSelLocs = 0;
+ ParamsAndSelLocs = nullptr;
NumParams = Params.size();
if (Params.empty() && SelLocs.empty())
return;
@@ -628,9 +721,9 @@ void ObjCMethodDecl::setMethodParams(ASTContext &C,
/// \brief A definition will return its interface declaration.
/// An interface declaration will return its definition.
/// Otherwise it will return itself.
-ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
+ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
ASTContext &Ctx = getASTContext();
- ObjCMethodDecl *Redecl = 0;
+ ObjCMethodDecl *Redecl = nullptr;
if (HasRedeclaration)
Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
if (Redecl)
@@ -730,7 +823,7 @@ ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
// init only has a conventional meaning for an instance method, and
// it has to return an object.
case OMF_init:
- if (!isInstanceMethod() || !getResultType()->isObjCObjectPointerType())
+ if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
family = OMF_None;
break;
@@ -740,7 +833,7 @@ ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
case OMF_copy:
case OMF_mutableCopy:
case OMF_new:
- if (!getResultType()->isObjCObjectPointerType())
+ if (!getReturnType()->isObjCObjectPointerType())
family = OMF_None;
break;
@@ -757,15 +850,14 @@ ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
break;
case OMF_performSelector:
- if (!isInstanceMethod() ||
- !getResultType()->isObjCIdType())
+ if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
family = OMF_None;
else {
unsigned noParams = param_size();
if (noParams < 1 || noParams > 3)
family = OMF_None;
else {
- ObjCMethodDecl::arg_type_iterator it = arg_type_begin();
+ ObjCMethodDecl::param_type_iterator it = param_type_begin();
QualType ArgT = (*it);
if (!ArgT->isObjCSelType()) {
family = OMF_None;
@@ -838,7 +930,7 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
setSelfDecl(self);
if (selfIsConsumed)
- self->addAttr(new (Context) NSConsumedAttr(SourceLocation(), Context));
+ self->addAttr(NSConsumedAttr::CreateImplicit(Context));
if (selfIsPseudoStrong)
self->setARCPseudoStrong(true);
@@ -855,8 +947,8 @@ ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
return CD->getClassInterface();
if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
return IMD->getClassInterface();
-
- assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
+ if (isa<ObjCProtocolDecl>(getDeclContext()))
+ return nullptr;
llvm_unreachable("unknown method context");
}
@@ -886,10 +978,8 @@ static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
return;
}
- for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
- PEnd = Category->protocol_end();
- P != PEnd; ++P)
- CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
+ for (const auto *P : Category->protocols())
+ CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
return;
}
@@ -906,26 +996,17 @@ static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
}
if (const ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
- for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
- PEnd = Protocol->protocol_end();
- P != PEnd; ++P)
- CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
+ for (const auto *P : Protocol->protocols())
+ CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
}
if (const ObjCInterfaceDecl *
Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
- for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
- PEnd = Interface->protocol_end();
- P != PEnd; ++P)
- CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
-
- for (ObjCInterfaceDecl::known_categories_iterator
- Cat = Interface->known_categories_begin(),
- CatEnd = Interface->known_categories_end();
- Cat != CatEnd; ++Cat) {
- CollectOverriddenMethodsRecurse(*Cat, Method, Methods,
- MovedToSuper);
- }
+ for (const auto *P : Interface->protocols())
+ CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
+
+ for (const auto *Cat : Interface->known_categories())
+ CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
return CollectOverriddenMethodsRecurse(Super, Method, Methods,
@@ -1002,11 +1083,11 @@ ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
Selector Sel = getSelector();
unsigned NumArgs = Sel.getNumArgs();
if (NumArgs > 1)
- return 0;
+ return nullptr;
if (!isInstanceMethod() || getMethodFamily() != OMF_None)
- return 0;
-
+ return nullptr;
+
if (isPropertyAccessor()) {
const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent());
// If container is class extension, find its primary class.
@@ -1016,20 +1097,18 @@ ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
bool IsGetter = (NumArgs == 0);
- for (ObjCContainerDecl::prop_iterator I = Container->prop_begin(),
- E = Container->prop_end();
- I != E; ++I) {
- Selector NextSel = IsGetter ? (*I)->getGetterName()
- : (*I)->getSetterName();
+ for (const auto *I : Container->properties()) {
+ Selector NextSel = IsGetter ? I->getGetterName()
+ : I->getSetterName();
if (NextSel == Sel)
- return *I;
+ return I;
}
llvm_unreachable("Marked as a property accessor but no property found!");
}
if (!CheckOverrides)
- return 0;
+ return nullptr;
typedef SmallVector<const ObjCMethodDecl *, 8> OverridesTy;
OverridesTy Overrides;
@@ -1040,8 +1119,7 @@ ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
return Prop;
}
- return 0;
-
+ return nullptr;
}
//===----------------------------------------------------------------------===//
@@ -1055,37 +1133,38 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
ObjCInterfaceDecl *PrevDecl,
SourceLocation ClassLoc,
bool isInternal){
- ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc,
- PrevDecl, isInternal);
+ ObjCInterfaceDecl *Result = new (C, DC)
+ ObjCInterfaceDecl(C, DC, atLoc, Id, ClassLoc, PrevDecl, isInternal);
Result->Data.setInt(!C.getLangOpts().Modules);
C.getObjCInterfaceType(Result, PrevDecl);
return Result;
}
-ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C,
+ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCInterfaceDecl));
- ObjCInterfaceDecl *Result = new (Mem) ObjCInterfaceDecl(0, SourceLocation(),
- 0, SourceLocation(),
- 0, false);
+ ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr,
+ SourceLocation(),
+ nullptr,
+ SourceLocation(),
+ nullptr, false);
Result->Data.setInt(!C.getLangOpts().Modules);
return Result;
}
-ObjCInterfaceDecl::
-ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
- SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
- bool isInternal)
- : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
- TypeForDecl(0), Data()
-{
+ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC,
+ SourceLocation AtLoc, IdentifierInfo *Id,
+ SourceLocation CLoc,
+ ObjCInterfaceDecl *PrevDecl,
+ bool IsInternal)
+ : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
+ redeclarable_base(C), TypeForDecl(nullptr), Data() {
setPreviousDecl(PrevDecl);
// Copy the 'data' pointer over.
if (PrevDecl)
Data = PrevDecl->Data;
- setImplicit(isInternal);
+ setImplicit(IsInternal);
}
void ObjCInterfaceDecl::LoadExternalDefinition() const {
@@ -1103,6 +1182,40 @@ void ObjCInterfaceDecl::setExternallyCompleted() {
data().ExternallyCompleted = true;
}
+void ObjCInterfaceDecl::setHasDesignatedInitializers() {
+ // Check for a complete definition and recover if not so.
+ if (!isThisDeclarationADefinition())
+ return;
+ data().HasDesignatedInitializers = true;
+}
+
+bool ObjCInterfaceDecl::hasDesignatedInitializers() const {
+ // Check for a complete definition and recover if not so.
+ if (!isThisDeclarationADefinition())
+ return false;
+ if (data().ExternallyCompleted)
+ LoadExternalDefinition();
+
+ return data().HasDesignatedInitializers;
+}
+
+StringRef
+ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {
+ if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
+ return ObjCRTName->getMetadataName();
+
+ return getName();
+}
+
+StringRef
+ObjCImplementationDecl::getObjCRuntimeNameAsString() const {
+ if (ObjCInterfaceDecl *ID =
+ const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
+ return ID->getObjCRuntimeNameAsString();
+
+ return getName();
+}
+
ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
if (const ObjCInterfaceDecl *Def = getDefinition()) {
if (data().ExternallyCompleted)
@@ -1113,7 +1226,7 @@ ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
}
// FIXME: Should make sure no callers ever do this.
- return 0;
+ return nullptr;
}
void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
@@ -1146,9 +1259,9 @@ namespace {
ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
-
- ObjCIvarDecl *curIvar = 0;
+ return nullptr;
+
+ ObjCIvarDecl *curIvar = nullptr;
if (!data().IvarList) {
if (!ivar_empty()) {
ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
@@ -1157,10 +1270,7 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
curIvar->setNextIvar(*I);
}
- for (ObjCInterfaceDecl::known_extensions_iterator
- Ext = known_extensions_begin(),
- ExtEnd = known_extensions_end();
- Ext != ExtEnd; ++Ext) {
+ for (const auto *Ext : known_extensions()) {
if (!Ext->ivar_empty()) {
ObjCCategoryDecl::ivar_iterator
I = Ext->ivar_begin(),
@@ -1184,19 +1294,17 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
data().IvarListMissingImplementation = false;
if (!ImplDecl->ivar_empty()) {
SmallVector<SynthesizeIvarChunk, 16> layout;
- for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
- E = ImplDecl->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *IV = *I;
+ for (auto *IV : ImplDecl->ivars()) {
if (IV->getSynthesize() && !IV->isInvalidDecl()) {
layout.push_back(SynthesizeIvarChunk(
IV->getASTContext().getTypeSize(IV->getType()), IV));
continue;
}
if (!data().IvarList)
- data().IvarList = *I;
+ data().IvarList = IV;
else
- curIvar->setNextIvar(*I);
- curIvar = *I;
+ curIvar->setNextIvar(IV);
+ curIvar = IV;
}
if (!layout.empty()) {
@@ -1223,47 +1331,37 @@ ObjCCategoryDecl *
ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
+ return nullptr;
if (data().ExternallyCompleted)
LoadExternalDefinition();
- for (visible_categories_iterator Cat = visible_categories_begin(),
- CatEnd = visible_categories_end();
- Cat != CatEnd;
- ++Cat) {
+ for (auto *Cat : visible_categories())
if (Cat->getIdentifier() == CategoryId)
- return *Cat;
- }
-
- return 0;
+ return Cat;
+
+ return nullptr;
}
ObjCMethodDecl *
ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
- for (visible_categories_iterator Cat = visible_categories_begin(),
- CatEnd = visible_categories_end();
- Cat != CatEnd;
- ++Cat) {
+ for (const auto *Cat : visible_categories()) {
if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
return MD;
}
- return 0;
+ return nullptr;
}
ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
- for (visible_categories_iterator Cat = visible_categories_begin(),
- CatEnd = visible_categories_end();
- Cat != CatEnd;
- ++Cat) {
+ for (const auto *Cat : visible_categories()) {
if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
return MD;
}
-
- return 0;
+
+ return nullptr;
}
/// ClassImplementsProtocol - Checks that 'lProto' protocol
@@ -1277,9 +1375,8 @@ bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
ObjCInterfaceDecl *IDecl = this;
// 1st, look up the class.
- for (ObjCInterfaceDecl::protocol_iterator
- PI = IDecl->protocol_begin(), E = IDecl->protocol_end(); PI != E; ++PI){
- if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
+ for (auto *PI : IDecl->protocols()){
+ if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
return true;
// This is dubious and is added to be compatible with gcc. In gcc, it is
// also allowed assigning a protocol-qualified 'id' type to a LHS object
@@ -1288,20 +1385,15 @@ bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
// FIXME: Treat this as an extension, and flag this as an error when GCC
// extensions are not enabled.
if (RHSIsQualifiedID &&
- getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
+ getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
return true;
}
// 2nd, look up the category.
if (lookupCategory)
- for (visible_categories_iterator Cat = visible_categories_begin(),
- CatEnd = visible_categories_end();
- Cat != CatEnd;
- ++Cat) {
- for (ObjCCategoryDecl::protocol_iterator PI = Cat->protocol_begin(),
- E = Cat->protocol_end();
- PI != E; ++PI)
- if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
+ for (const auto *Cat : visible_categories()) {
+ for (auto *PI : Cat->protocols())
+ if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
return true;
}
@@ -1325,8 +1417,7 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW,
- bool synthesized,
- bool backingIvarReferencedInAccessor) {
+ bool synthesized) {
if (DC) {
// Ivar's can only appear in interfaces, implementations (via synthesized
// properties), and class extensions (via direct declaration, or synthesized
@@ -1350,17 +1441,17 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
else
ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
}
- ID->setIvarList(0);
+ ID->setIvarList(nullptr);
}
- return new (C) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo,
- ac, BW, synthesized, backingIvarReferencedInAccessor);
+ return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
+ synthesized);
}
ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCIvarDecl));
- return new (Mem) ObjCIvarDecl(0, SourceLocation(), SourceLocation(), 0,
- QualType(), 0, ObjCIvarDecl::None, 0, false, false);
+ return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
+ nullptr, QualType(), nullptr,
+ ObjCIvarDecl::None, nullptr, false);
}
const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
@@ -1397,14 +1488,14 @@ ObjCAtDefsFieldDecl
*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T, Expr *BW) {
- return new (C) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
+ return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
}
-ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
+ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCAtDefsFieldDecl));
- return new (Mem) ObjCAtDefsFieldDecl(0, SourceLocation(), SourceLocation(),
- 0, QualType(), 0);
+ return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
+ SourceLocation(), nullptr, QualType(),
+ nullptr);
}
//===----------------------------------------------------------------------===//
@@ -1413,12 +1504,12 @@ ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
void ObjCProtocolDecl::anchor() { }
-ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
- SourceLocation nameLoc,
+ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
+ IdentifierInfo *Id, SourceLocation nameLoc,
SourceLocation atStartLoc,
ObjCProtocolDecl *PrevDecl)
- : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data()
-{
+ : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
+ redeclarable_base(C), Data() {
setPreviousDecl(PrevDecl);
if (PrevDecl)
Data = PrevDecl->Data;
@@ -1429,17 +1520,17 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation nameLoc,
SourceLocation atStartLoc,
ObjCProtocolDecl *PrevDecl) {
- ObjCProtocolDecl *Result
- = new (C) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl);
+ ObjCProtocolDecl *Result =
+ new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
Result->Data.setInt(!C.getLangOpts().Modules);
return Result;
}
-ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
+ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCProtocolDecl));
- ObjCProtocolDecl *Result = new (Mem) ObjCProtocolDecl(0, 0, SourceLocation(),
- SourceLocation(), 0);
+ ObjCProtocolDecl *Result =
+ new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
+ SourceLocation(), nullptr);
Result->Data.setInt(!C.getLangOpts().Modules);
return Result;
}
@@ -1450,32 +1541,32 @@ ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
if (Name == getIdentifier())
return PDecl;
- for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
- if ((PDecl = (*I)->lookupProtocolNamed(Name)))
+ for (auto *I : protocols())
+ if ((PDecl = I->lookupProtocolNamed(Name)))
return PDecl;
- return NULL;
+ return nullptr;
}
// lookupMethod - Lookup a instance/class method in the protocol and protocols
// it inherited.
ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
bool isInstance) const {
- ObjCMethodDecl *MethodDecl = NULL;
+ ObjCMethodDecl *MethodDecl = nullptr;
// If there is no definition or the definition is hidden, we don't find
// anything.
const ObjCProtocolDecl *Def = getDefinition();
if (!Def || Def->isHidden())
- return NULL;
+ return nullptr;
if ((MethodDecl = getMethod(Sel, isInstance)))
return MethodDecl;
- for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+ for (const auto *I : protocols())
+ if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
return MethodDecl;
- return NULL;
+ return nullptr;
}
void ObjCProtocolDecl::allocateDefinitionData() {
@@ -1488,8 +1579,7 @@ void ObjCProtocolDecl::startDefinition() {
allocateDefinitionData();
// Update all of the declarations with a pointer to the definition.
- for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
- RD != RDEnd; ++RD)
+ for (auto RD : redecls())
RD->Data = this->Data;
}
@@ -1497,17 +1587,14 @@ void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
PropertyDeclOrder &PO) const {
if (const ObjCProtocolDecl *PDecl = getDefinition()) {
- for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
- E = PDecl->prop_end(); P != E; ++P) {
- ObjCPropertyDecl *Prop = *P;
+ for (auto *Prop : PDecl->properties()) {
// Insert into PM if not there already.
PM.insert(std::make_pair(Prop->getIdentifier(), Prop));
PO.push_back(Prop);
}
// Scan through protocol's protocols.
- for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
- E = PDecl->protocol_end(); PI != E; ++PI)
- (*PI)->collectPropertiesToImplement(PM, PO);
+ for (const auto *PI : PDecl->protocols())
+ PI->collectPropertiesToImplement(PM, PO);
}
}
@@ -1517,9 +1604,7 @@ void ObjCProtocolDecl::collectInheritedProtocolProperties(
ProtocolPropertyMap &PM) const {
if (const ObjCProtocolDecl *PDecl = getDefinition()) {
bool MatchFound = false;
- for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
- E = PDecl->prop_end(); P != E; ++P) {
- ObjCPropertyDecl *Prop = *P;
+ for (auto *Prop : PDecl->properties()) {
if (Prop == Property)
continue;
if (Prop->getIdentifier() == Property->getIdentifier()) {
@@ -1530,12 +1615,19 @@ void ObjCProtocolDecl::collectInheritedProtocolProperties(
}
// Scan through protocol's protocols which did not have a matching property.
if (!MatchFound)
- for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
- E = PDecl->protocol_end(); PI != E; ++PI)
- (*PI)->collectInheritedProtocolProperties(Property, PM);
+ for (const auto *PI : PDecl->protocols())
+ PI->collectInheritedProtocolProperties(Property, PM);
}
}
+StringRef
+ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
+ if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
+ return ObjCRTName->getMetadataName();
+
+ return getName();
+}
+
//===----------------------------------------------------------------------===//
// ObjCCategoryDecl
//===----------------------------------------------------------------------===//
@@ -1543,17 +1635,16 @@ void ObjCProtocolDecl::collectInheritedProtocolProperties(
void ObjCCategoryDecl::anchor() { }
ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation AtLoc,
+ SourceLocation AtLoc,
SourceLocation ClassNameLoc,
SourceLocation CategoryNameLoc,
IdentifierInfo *Id,
ObjCInterfaceDecl *IDecl,
SourceLocation IvarLBraceLoc,
SourceLocation IvarRBraceLoc) {
- ObjCCategoryDecl *CatDecl = new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc,
- CategoryNameLoc, Id,
- IDecl,
- IvarLBraceLoc, IvarRBraceLoc);
+ ObjCCategoryDecl *CatDecl =
+ new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
+ IDecl, IvarLBraceLoc, IvarRBraceLoc);
if (IDecl) {
// Link this category into its class's category list.
CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
@@ -1567,11 +1658,11 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
return CatDecl;
}
-ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
+ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryDecl));
- return new (Mem) ObjCCategoryDecl(0, SourceLocation(), SourceLocation(),
- SourceLocation(), 0, 0);
+ return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ nullptr, nullptr);
}
ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
@@ -1599,22 +1690,22 @@ ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation CategoryNameLoc) {
if (ClassInterface && ClassInterface->hasDefinition())
ClassInterface = ClassInterface->getDefinition();
- return new (C) ObjCCategoryImplDecl(DC, Id, ClassInterface,
- nameLoc, atStartLoc, CategoryNameLoc);
+ return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
+ atStartLoc, CategoryNameLoc);
}
ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryImplDecl));
- return new (Mem) ObjCCategoryImplDecl(0, 0, 0, SourceLocation(),
- SourceLocation(), SourceLocation());
+ return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
+ SourceLocation(), SourceLocation(),
+ SourceLocation());
}
ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
// The class interface might be NULL if we are working with invalid code.
if (const ObjCInterfaceDecl *ID = getClassInterface())
return ID->FindCategoryDeclaration(getIdentifier());
- return 0;
+ return nullptr;
}
@@ -1649,13 +1740,11 @@ void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
///
ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
- for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
- ObjCPropertyImplDecl *PID = *i;
+ for (auto *PID : property_impls())
if (PID->getPropertyIvarDecl() &&
PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
return PID;
- }
- return 0;
+ return nullptr;
}
/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
@@ -1664,12 +1753,10 @@ FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
///
ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplDecl(IdentifierInfo *Id) const {
- for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
- ObjCPropertyImplDecl *PID = *i;
+ for (auto *PID : property_impls())
if (PID->getPropertyDecl()->getIdentifier() == Id)
return PID;
- }
- return 0;
+ return nullptr;
}
raw_ostream &clang::operator<<(raw_ostream &OS,
@@ -1695,16 +1782,15 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IvarRBraceLoc) {
if (ClassInterface && ClassInterface->hasDefinition())
ClassInterface = ClassInterface->getDefinition();
- return new (C) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
- nameLoc, atStartLoc, superLoc,
- IvarLBraceLoc, IvarRBraceLoc);
+ return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
+ nameLoc, atStartLoc, superLoc,
+ IvarLBraceLoc, IvarRBraceLoc);
}
ObjCImplementationDecl *
ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCImplementationDecl));
- return new (Mem) ObjCImplementationDecl(0, 0, 0, SourceLocation(),
- SourceLocation());
+ return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
+ SourceLocation(), SourceLocation());
}
void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
@@ -1737,13 +1823,13 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
IdentifierInfo *Id,
ObjCInterfaceDecl* AliasedClass) {
- return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
+ return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
}
ObjCCompatibleAliasDecl *
ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCompatibleAliasDecl));
- return new (Mem) ObjCCompatibleAliasDecl(0, SourceLocation(), 0, 0);
+ return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
+ nullptr, nullptr);
}
//===----------------------------------------------------------------------===//
@@ -1759,15 +1845,14 @@ ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation LParenLoc,
TypeSourceInfo *T,
PropertyControl propControl) {
- return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
+ return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
}
-ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
+ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void * Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyDecl));
- return new (Mem) ObjCPropertyDecl(0, SourceLocation(), 0, SourceLocation(),
- SourceLocation(),
- 0);
+ return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
+ SourceLocation(), SourceLocation(),
+ nullptr);
}
//===----------------------------------------------------------------------===//
@@ -1782,15 +1867,15 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Kind PK,
ObjCIvarDecl *ivar,
SourceLocation ivarLoc) {
- return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
- ivarLoc);
+ return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
+ ivarLoc);
}
-ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
+ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyImplDecl));
- return new (Mem) ObjCPropertyImplDecl(0, SourceLocation(), SourceLocation(),
- 0, Dynamic, 0, SourceLocation());
+ return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
+ SourceLocation(), nullptr, Dynamic,
+ nullptr, SourceLocation());
}
SourceRange ObjCPropertyImplDecl::getSourceRange() const {
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp b/contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp
index 0d195f7..5f8b42b 100644
--- a/contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/DeclOpenMP.cpp
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclBase.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/Expr.h"
@@ -29,12 +29,8 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
ArrayRef<Expr *> VL) {
- unsigned Size = sizeof(OMPThreadPrivateDecl) +
- (VL.size() * sizeof(Expr *));
-
- void *Mem = C.Allocate(Size, llvm::alignOf<OMPThreadPrivateDecl>());
- OMPThreadPrivateDecl *D = new (Mem) OMPThreadPrivateDecl(OMPThreadPrivate,
- DC, L);
+ OMPThreadPrivateDecl *D = new (C, DC, VL.size() * sizeof(Expr *))
+ OMPThreadPrivateDecl(OMPThreadPrivate, DC, L);
D->NumVars = VL.size();
D->setVars(VL);
return D;
@@ -43,11 +39,8 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C,
OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C,
unsigned ID,
unsigned N) {
- unsigned Size = sizeof(OMPThreadPrivateDecl) + (N * sizeof(Expr *));
-
- void *Mem = AllocateDeserializedDecl(C, ID, Size);
- OMPThreadPrivateDecl *D = new (Mem) OMPThreadPrivateDecl(OMPThreadPrivate,
- 0, SourceLocation());
+ OMPThreadPrivateDecl *D = new (C, ID, N * sizeof(Expr *))
+ OMPThreadPrivateDecl(OMPThreadPrivate, nullptr, SourceLocation());
D->NumVars = N;
return D;
}
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp b/contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp
index 767f662..e5e5130 100644
--- a/contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/DeclPrinter.cpp
@@ -85,7 +85,7 @@ namespace {
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
void PrintTemplateParameters(const TemplateParameterList *Params,
- const TemplateArgumentList *Args = 0);
+ const TemplateArgumentList *Args = nullptr);
void prettyPrintAttributes(Decl *D);
};
}
@@ -114,7 +114,7 @@ static QualType GetBaseType(QualType T) {
else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
BaseType = ATy->getElementType();
else if (const FunctionType* FTy = BaseType->getAs<FunctionType>())
- BaseType = FTy->getResultType();
+ BaseType = FTy->getReturnType();
else if (const VectorType *VTy = BaseType->getAs<VectorType>())
BaseType = VTy->getElementType();
else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
@@ -167,7 +167,7 @@ void Decl::printGroup(Decl** Begin, unsigned NumDecls,
}
}
-void DeclContext::dumpDeclContext() const {
+LLVM_DUMP_METHOD void DeclContext::dumpDeclContext() const {
// Get the translation unit
const DeclContext *DC = this;
while (!DC->isTranslationUnit())
@@ -238,17 +238,6 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
if (D->isImplicit())
continue;
- // FIXME: Ugly hack so we don't pretty-print the builtin declaration
- // of __builtin_va_list or __[u]int128_t. There should be some other way
- // to check that.
- if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) {
- if (IdentifierInfo *II = ND->getIdentifier()) {
- if (II->isStr("__builtin_va_list") ||
- II->isStr("__int128_t") || II->isStr("__uint128_t"))
- continue;
- }
- }
-
// The next bits of code handles stuff like "struct {int x;} a,b"; we're
// forced to merge the declarations because there's no other way to
// refer to the struct in question. This limited merging is safe without
@@ -293,21 +282,21 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
Visit(*D);
// FIXME: Need to be able to tell the DeclPrinter when
- const char *Terminator = 0;
+ const char *Terminator = nullptr;
if (isa<OMPThreadPrivateDecl>(*D))
- Terminator = 0;
+ Terminator = nullptr;
else if (isa<FunctionDecl>(*D) &&
cast<FunctionDecl>(*D)->isThisDeclarationADefinition())
- Terminator = 0;
+ Terminator = nullptr;
else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody())
- Terminator = 0;
+ Terminator = nullptr;
else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) ||
isa<ObjCImplementationDecl>(*D) ||
isa<ObjCInterfaceDecl>(*D) ||
isa<ObjCProtocolDecl>(*D) ||
isa<ObjCCategoryImplDecl>(*D) ||
isa<ObjCCategoryDecl>(*D))
- Terminator = 0;
+ Terminator = nullptr;
else if (isa<EnumConstantDecl>(*D)) {
DeclContext::decl_iterator Next = D;
++Next;
@@ -390,12 +379,13 @@ void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
Out << *D;
if (Expr *Init = D->getInitExpr()) {
Out << " = ";
- Init->printPretty(Out, 0, Policy, Indentation);
+ Init->printPretty(Out, nullptr, Policy, Indentation);
}
}
void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
+ CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
if (!Policy.SuppressSpecifiers) {
switch (D->getStorageClass()) {
case SC_None: break;
@@ -409,7 +399,9 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (D->isInlineSpecified()) Out << "inline ";
if (D->isVirtualAsWritten()) Out << "virtual ";
if (D->isModulePrivate()) Out << "__module_private__ ";
- if (CDecl && CDecl->isExplicitSpecified())
+ if (D->isConstexpr() && !D->isExplicitlyDefaulted()) Out << "constexpr ";
+ if ((CDecl && CDecl->isExplicitSpecified()) ||
+ (ConversionDecl && ConversionDecl->isExplicit()))
Out << "explicit ";
}
@@ -423,9 +415,8 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Ty = PT->getInnerType();
}
- if (isa<FunctionType>(Ty)) {
- const FunctionType *AFT = Ty->getAs<FunctionType>();
- const FunctionProtoType *FT = 0;
+ if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
+ const FunctionProtoType *FT = nullptr;
if (D->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(AFT);
@@ -459,6 +450,17 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Proto += " volatile";
if (FT->isRestrict())
Proto += " restrict";
+
+ switch (FT->getRefQualifier()) {
+ case RQ_None:
+ break;
+ case RQ_LValue:
+ Proto += " &";
+ break;
+ case RQ_RValue:
+ Proto += " &&";
+ break;
+ }
}
if (FT && FT->hasDynamicExceptionSpec()) {
@@ -478,7 +480,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (FT->getExceptionSpecType() == EST_ComputedNoexcept) {
Proto += "(";
llvm::raw_string_ostream EOut(Proto);
- FT->getNoexceptExpr()->printPretty(EOut, 0, SubPolicy,
+ FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy,
Indentation);
EOut.flush();
Proto += EOut.str();
@@ -488,10 +490,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (CDecl) {
bool HasInitializerList = false;
- for (CXXConstructorDecl::init_const_iterator B = CDecl->init_begin(),
- E = CDecl->init_end();
- B != E; ++B) {
- CXXCtorInitializer *BMInitializer = (*B);
+ for (const auto *BMInitializer : CDecl->inits()) {
if (BMInitializer->isInClassMemberInitializer())
continue;
@@ -519,9 +518,9 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Init = Tmp->getSubExpr();
Init = Init->IgnoreParens();
-
- Expr *SimpleInit = 0;
- Expr **Args = 0;
+
+ Expr *SimpleInit = nullptr;
+ Expr **Args = nullptr;
unsigned NumArgs = 0;
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
Args = ParenList->getExprs();
@@ -534,29 +533,32 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
SimpleInit = Init;
if (SimpleInit)
- SimpleInit->printPretty(Out, 0, Policy, Indentation);
+ SimpleInit->printPretty(Out, nullptr, Policy, Indentation);
else {
for (unsigned I = 0; I != NumArgs; ++I) {
+ assert(Args[I] != nullptr && "Expected non-null Expr");
if (isa<CXXDefaultArgExpr>(Args[I]))
break;
if (I)
Out << ", ";
- Args[I]->printPretty(Out, 0, Policy, Indentation);
+ Args[I]->printPretty(Out, nullptr, Policy, Indentation);
}
}
}
Out << ")";
+ if (BMInitializer->isPackExpansion())
+ Out << "...";
}
- if (!Proto.empty())
- Out << Proto;
- } else {
+ } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) {
if (FT && FT->hasTrailingReturn()) {
Out << "auto " << Proto << " -> ";
Proto.clear();
}
- AFT->getResultType().print(Out, Policy, Proto);
+ AFT->getReturnType().print(Out, Policy, Proto);
+ Proto.clear();
}
+ Out << Proto;
} else {
Ty.print(Out, Policy, Proto);
}
@@ -585,7 +587,8 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
} else
Out << ' ';
- D->getBody()->printPretty(Out, 0, SubPolicy, Indentation);
+ if (D->getBody())
+ D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation);
Out << '\n';
}
}
@@ -626,7 +629,7 @@ void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
if (D->isBitField()) {
Out << " : ";
- D->getBitWidth()->printPretty(Out, 0, Policy, Indentation);
+ D->getBitWidth()->printPretty(Out, nullptr, Policy, Indentation);
}
Expr *Init = D->getInClassInitializer();
@@ -635,7 +638,7 @@ void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
Out << " ";
else
Out << " = ";
- Init->printPretty(Out, 0, Policy, Indentation);
+ Init->printPretty(Out, nullptr, Policy, Indentation);
}
prettyPrintAttributes(D);
}
@@ -690,7 +693,7 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) {
else if (D->getInitStyle() == VarDecl::CInit) {
Out << " = ";
}
- Init->printPretty(Out, 0, Policy, Indentation);
+ Init->printPretty(Out, nullptr, Policy, Indentation);
if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
Out << ")";
}
@@ -704,7 +707,7 @@ void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) {
void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
Out << "__asm (";
- D->getAsmString()->printPretty(Out, 0, Policy, Indentation);
+ D->getAsmString()->printPretty(Out, nullptr, Policy, Indentation);
Out << ")";
}
@@ -715,9 +718,9 @@ void DeclPrinter::VisitImportDecl(ImportDecl *D) {
void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
Out << "static_assert(";
- D->getAssertExpr()->printPretty(Out, 0, Policy, Indentation);
+ D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation);
Out << ", ";
- D->getMessage()->printPretty(Out, 0, Policy, Indentation);
+ D->getMessage()->printPretty(Out, nullptr, Policy, Indentation);
Out << ")";
}
@@ -855,7 +858,8 @@ void DeclPrinter::PrintTemplateParameters(const TemplateParameterList *Params,
Args->get(i).print(Policy, Out);
} else if (NTTP->hasDefaultArgument()) {
Out << " = ";
- NTTP->getDefaultArgument()->printPretty(Out, 0, Policy, Indentation);
+ NTTP->getDefaultArgument()->printPretty(Out, nullptr, Policy,
+ Indentation);
}
} else if (const TemplateTemplateParmDecl *TTPD =
dyn_cast<TemplateTemplateParmDecl>(Param)) {
@@ -884,10 +888,9 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
if (PrintInstantiation) {
TemplateParameterList *Params = D->getTemplateParameters();
- for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end();
- I != E; ++I) {
- PrintTemplateParameters(Params, (*I)->getTemplateSpecializationArgs());
- Visit(*I);
+ for (auto *I : D->specializations()) {
+ PrintTemplateParameters(Params, I->getTemplateSpecializationArgs());
+ Visit(I);
}
}
@@ -897,10 +900,9 @@ void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (PrintInstantiation) {
TemplateParameterList *Params = D->getTemplateParameters();
- for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end();
- I != E; ++I) {
- PrintTemplateParameters(Params, &(*I)->getTemplateArgs());
- Visit(*I);
+ for (auto *I : D->specializations()) {
+ PrintTemplateParameters(Params, &I->getTemplateArgs());
+ Visit(I);
Out << '\n';
}
}
@@ -917,19 +919,19 @@ void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
Out << "- ";
else
Out << "+ ";
- if (!OMD->getResultType().isNull())
- Out << '(' << OMD->getASTContext().getUnqualifiedObjCPointerType(OMD->getResultType()).
- getAsString(Policy) << ")";
+ if (!OMD->getReturnType().isNull())
+ Out << '(' << OMD->getASTContext()
+ .getUnqualifiedObjCPointerType(OMD->getReturnType())
+ .getAsString(Policy) << ")";
std::string name = OMD->getSelector().getAsString();
std::string::size_type pos, lastPos = 0;
- for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
- E = OMD->param_end(); PI != E; ++PI) {
+ for (const auto *PI : OMD->params()) {
// FIXME: selector is missing here!
pos = name.find_first_of(':', lastPos);
Out << " " << name.substr(lastPos, pos - lastPos);
- Out << ":(" << (*PI)->getASTContext().getUnqualifiedObjCPointerType((*PI)->getType()).
- getAsString(Policy) << ')' << **PI;
+ Out << ":(" << PI->getASTContext().getUnqualifiedObjCPointerType(PI->getType()).
+ getAsString(Policy) << ')' << *PI;
lastPos = pos + 1;
}
@@ -941,7 +943,7 @@ void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
if (OMD->getBody() && !Policy.TerseOutput) {
Out << ' ';
- OMD->getBody()->printPretty(Out, 0, Policy);
+ OMD->getBody()->printPretty(Out, nullptr, Policy);
Out << '\n';
}
else if (Policy.PolishForDeclaration)
@@ -960,10 +962,9 @@ void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
if (OID->ivar_size() > 0) {
Out << "{\n";
Indentation += Policy.Indentation;
- for (ObjCImplementationDecl::ivar_iterator I = OID->ivar_begin(),
- E = OID->ivar_end(); I != E; ++I) {
+ for (const auto *I : OID->ivars()) {
Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
- getAsString(Policy) << ' ' << **I << ";\n";
+ getAsString(Policy) << ' ' << *I << ";\n";
}
Indentation -= Policy.Indentation;
Out << "}\n";
@@ -999,10 +1000,10 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
Out << "{\n";
eolnOut = true;
Indentation += Policy.Indentation;
- for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(),
- E = OID->ivar_end(); I != E; ++I) {
- Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
- getAsString(Policy) << ' ' << **I << ";\n";
+ for (const auto *I : OID->ivars()) {
+ Indent() << I->getASTContext()
+ .getUnqualifiedObjCPointerType(I->getType())
+ .getAsString(Policy) << ' ' << *I << ";\n";
}
Indentation -= Policy.Indentation;
Out << "}\n";
@@ -1051,11 +1052,9 @@ void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
if (PID->ivar_size() > 0) {
Out << "{\n";
Indentation += Policy.Indentation;
- for (ObjCCategoryDecl::ivar_iterator I = PID->ivar_begin(),
- E = PID->ivar_end(); I != E; ++I) {
+ for (const auto *I : PID->ivars())
Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
- getAsString(Policy) << ' ' << **I << ";\n";
- }
+ getAsString(Policy) << ' ' << *I << ";\n";
Indentation -= Policy.Indentation;
Out << "}\n";
}
@@ -1090,13 +1089,13 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
}
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
- Out << (first ? ' ' : ',') << "getter = "
- << PDecl->getGetterName().getAsString();
+ Out << (first ? ' ' : ',') << "getter = ";
+ PDecl->getGetterName().print(Out);
first = false;
}
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
- Out << (first ? ' ' : ',') << "setter = "
- << PDecl->getSetterName().getAsString();
+ Out << (first ? ' ' : ',') << "setter = ";
+ PDecl->getSetterName().print(Out);
first = false;
}
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp b/contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp
index 7172fb7..0d1d2a4 100644
--- a/contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/DeclTemplate.cpp
@@ -164,13 +164,13 @@ template <class EntryType>
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
RedeclarableTemplateDecl::findSpecializationImpl(
llvm::FoldingSetVector<EntryType> &Specs,
- const TemplateArgument *Args, unsigned NumArgs,
+ ArrayRef<TemplateArgument> Args,
void *&InsertPos) {
typedef SpecEntryTraits<EntryType> SETraits;
llvm::FoldingSetNodeID ID;
- EntryType::Profile(ID,Args,NumArgs, getASTContext());
+ EntryType::Profile(ID,Args, getASTContext());
EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
- return Entry ? SETraits::getMostRecentDecl(Entry) : 0;
+ return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr;
}
/// \brief Generate the injected template arguments for the given template
@@ -229,14 +229,13 @@ FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
TemplateParameterList *Params,
NamedDecl *Decl) {
AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
- return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
+ return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
}
FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl));
- return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
- 0, 0);
+ return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
+ DeclarationName(), nullptr, nullptr);
}
RedeclarableTemplateDecl::CommonBase *
@@ -251,7 +250,7 @@ void FunctionTemplateDecl::LoadLazySpecializations() const {
if (CommonPtr->LazySpecializations) {
ASTContext &Context = getASTContext();
uint32_t *Specs = CommonPtr->LazySpecializations;
- CommonPtr->LazySpecializations = 0;
+ CommonPtr->LazySpecializations = nullptr;
for (uint32_t I = 0, N = *Specs++; I != N; ++I)
(void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
}
@@ -264,9 +263,9 @@ FunctionTemplateDecl::getSpecializations() const {
}
FunctionDecl *
-FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos) {
- return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+ void *&InsertPos) {
+ return findSpecializationImpl(getSpecializations(), Args, InsertPos);
}
void FunctionTemplateDecl::addSpecialization(
@@ -308,15 +307,16 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
NamedDecl *Decl,
ClassTemplateDecl *PrevDecl) {
AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
- ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
+ ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
+ Params, Decl);
New->setPreviousDecl(PrevDecl);
return New;
}
-ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
+ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
- return new (Mem) ClassTemplateDecl(EmptyShell());
+ return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
+ DeclarationName(), nullptr, nullptr);
}
void ClassTemplateDecl::LoadLazySpecializations() const {
@@ -324,7 +324,7 @@ void ClassTemplateDecl::LoadLazySpecializations() const {
if (CommonPtr->LazySpecializations) {
ASTContext &Context = getASTContext();
uint32_t *Specs = CommonPtr->LazySpecializations;
- CommonPtr->LazySpecializations = 0;
+ CommonPtr->LazySpecializations = nullptr;
for (uint32_t I = 0, N = *Specs++; I != N; ++I)
(void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
}
@@ -350,9 +350,9 @@ ClassTemplateDecl::newCommon(ASTContext &C) const {
}
ClassTemplateSpecializationDecl *
-ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos) {
- return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+ void *&InsertPos) {
+ return findSpecializationImpl(getSpecializations(), Args, InsertPos);
}
void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
@@ -370,11 +370,9 @@ void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
}
ClassTemplatePartialSpecializationDecl *
-ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
- unsigned NumArgs,
+ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
void *&InsertPos) {
- return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
- InsertPos);
+ return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
}
void ClassTemplateDecl::AddPartialSpecialization(
@@ -418,7 +416,7 @@ ClassTemplateDecl::findPartialSpecialization(QualType T) {
return P->getMostRecentDecl();
}
- return 0;
+ return nullptr;
}
ClassTemplatePartialSpecializationDecl *
@@ -433,7 +431,7 @@ ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
return P->getMostRecentDecl();
}
- return 0;
+ return nullptr;
}
QualType
@@ -471,17 +469,16 @@ TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
unsigned D, unsigned P, IdentifierInfo *Id,
bool Typename, bool ParameterPack) {
TemplateTypeParmDecl *TTPDecl =
- new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
+ new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
- TTPDecl->TypeForDecl = TTPType.getTypePtr();
+ TTPDecl->setTypeForDecl(TTPType.getTypePtr());
return TTPDecl;
}
TemplateTypeParmDecl *
TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
- return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
- 0, false);
+ return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
+ SourceLocation(), nullptr, false);
}
SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
@@ -499,15 +496,15 @@ SourceRange TemplateTypeParmDecl::getSourceRange() const {
}
unsigned TemplateTypeParmDecl::getDepth() const {
- return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
+ return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
}
unsigned TemplateTypeParmDecl::getIndex() const {
- return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
+ return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
}
bool TemplateTypeParmDecl::isParameterPack() const {
- return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
+ return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
}
//===----------------------------------------------------------------------===//
@@ -525,7 +522,7 @@ NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
unsigned NumExpandedTypes,
TypeSourceInfo **ExpandedTInfos)
: DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
- TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
+ TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
ParameterPack(true), ExpandedParameterPack(true),
NumExpandedTypes(NumExpandedTypes)
{
@@ -544,8 +541,8 @@ NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
unsigned D, unsigned P, IdentifierInfo *Id,
QualType T, bool ParameterPack,
TypeSourceInfo *TInfo) {
- return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
- T, ParameterPack, TInfo);
+ return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
+ T, ParameterPack, TInfo);
}
NonTypeTemplateParmDecl *
@@ -557,34 +554,26 @@ NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
const QualType *ExpandedTypes,
unsigned NumExpandedTypes,
TypeSourceInfo **ExpandedTInfos) {
- unsigned Size = sizeof(NonTypeTemplateParmDecl)
- + NumExpandedTypes * 2 * sizeof(void*);
- void *Mem = C.Allocate(Size);
- return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
- D, P, Id, T, TInfo,
- ExpandedTypes, NumExpandedTypes,
- ExpandedTInfos);
+ unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
+ return new (C, DC, Extra) NonTypeTemplateParmDecl(
+ DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
+ ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
}
NonTypeTemplateParmDecl *
NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
- return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
- SourceLocation(), 0, 0, 0,
- QualType(), false, 0);
+ return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
+ SourceLocation(), 0, 0, nullptr,
+ QualType(), false, nullptr);
}
NonTypeTemplateParmDecl *
NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumExpandedTypes) {
- unsigned Size = sizeof(NonTypeTemplateParmDecl)
- + NumExpandedTypes * 2 * sizeof(void*);
-
- void *Mem = AllocateDeserializedDecl(C, ID, Size);
- return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
- SourceLocation(), 0, 0, 0,
- QualType(), 0, 0, NumExpandedTypes,
- 0);
+ unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
+ return new (C, ID, Extra) NonTypeTemplateParmDecl(
+ nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
+ nullptr, nullptr, NumExpandedTypes, nullptr);
}
SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
@@ -624,8 +613,8 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D, unsigned P,
bool ParameterPack, IdentifierInfo *Id,
TemplateParameterList *Params) {
- return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
- Params);
+ return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
+ Params);
}
TemplateTemplateParmDecl *
@@ -634,28 +623,23 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
TemplateParameterList *Params,
ArrayRef<TemplateParameterList *> Expansions) {
- void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
- sizeof(TemplateParameterList*) * Expansions.size());
- return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
- Expansions.size(),
- Expansions.data());
+ return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
+ TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
+ Expansions.size(), Expansions.data());
}
TemplateTemplateParmDecl *
TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
- return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
- 0, 0);
+ return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
+ false, nullptr, nullptr);
}
TemplateTemplateParmDecl *
TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumExpansions) {
- unsigned Size = sizeof(TemplateTemplateParmDecl) +
- sizeof(TemplateParameterList*) * NumExpansions;
- void *Mem = AllocateDeserializedDecl(C, ID, Size);
- return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
- NumExpansions, 0);
+ return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
+ TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
+ nullptr, NumExpansions, nullptr);
}
//===----------------------------------------------------------------------===//
@@ -682,7 +666,7 @@ FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
const TemplateArgumentList *TemplateArgs,
const TemplateArgumentListInfo *TemplateArgsAsWritten,
SourceLocation POI) {
- const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
+ const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
if (TemplateArgsAsWritten)
ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
*TemplateArgsAsWritten);
@@ -710,20 +694,20 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
const TemplateArgument *Args,
unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl)
- : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
+ : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
SpecializedTemplate->getIdentifier(),
PrevDecl),
SpecializedTemplate(SpecializedTemplate),
- ExplicitInfo(0),
+ ExplicitInfo(nullptr),
TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
SpecializationKind(TSK_Undeclared) {
}
-ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
- : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
- ExplicitInfo(0),
- SpecializationKind(TSK_Undeclared) {
-}
+ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
+ Kind DK)
+ : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
+ SourceLocation(), nullptr, nullptr),
+ ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
ClassTemplateSpecializationDecl *
ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
@@ -734,13 +718,10 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
const TemplateArgument *Args,
unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl) {
- ClassTemplateSpecializationDecl *Result
- = new (Context)ClassTemplateSpecializationDecl(Context,
- ClassTemplateSpecialization,
- TK, DC, StartLoc, IdLoc,
- SpecializedTemplate,
- Args, NumArgs,
- PrevDecl);
+ ClassTemplateSpecializationDecl *Result =
+ new (Context, DC) ClassTemplateSpecializationDecl(
+ Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
+ SpecializedTemplate, Args, NumArgs, PrevDecl);
Result->MayHaveOutOfDateDef = false;
Context.getTypeDeclType(Result, PrevDecl);
@@ -748,12 +729,10 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
}
ClassTemplateSpecializationDecl *
-ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
+ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID,
- sizeof(ClassTemplateSpecializationDecl));
ClassTemplateSpecializationDecl *Result =
- new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
+ new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Result->MayHaveOutOfDateDef = false;
return Result;
}
@@ -797,7 +776,7 @@ ClassTemplateSpecializationDecl::getSourceRange() const {
typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
- assert(inst_from != 0);
+ assert(inst_from != nullptr);
return inst_from->getSourceRange();
}
else {
@@ -836,7 +815,7 @@ ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
SpecializedTemplate,
Args, NumArgs, PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
- InstantiatedFromMember(0, false)
+ InstantiatedFromMember(nullptr, false)
{
AdoptTemplateParameterList(Params, this);
}
@@ -855,14 +834,10 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC,
const ASTTemplateArgumentListInfo *ASTArgInfos =
ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
- ClassTemplatePartialSpecializationDecl *Result
- = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
- StartLoc, IdLoc,
- Params,
- SpecializedTemplate,
- Args, NumArgs,
- ASTArgInfos,
- PrevDecl);
+ ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
+ ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
+ Params, SpecializedTemplate, Args,
+ NumArgs, ASTArgInfos, PrevDecl);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
Result->MayHaveOutOfDateDef = false;
@@ -873,10 +848,8 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC,
ClassTemplatePartialSpecializationDecl *
ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID,
- sizeof(ClassTemplatePartialSpecializationDecl));
- ClassTemplatePartialSpecializationDecl *Result
- = new (Mem) ClassTemplatePartialSpecializationDecl();
+ ClassTemplatePartialSpecializationDecl *Result =
+ new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Result->MayHaveOutOfDateDef = false;
return Result;
}
@@ -894,15 +867,13 @@ FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
TemplateParameterList **Params,
FriendUnion Friend,
SourceLocation FLoc) {
- FriendTemplateDecl *Result
- = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
- return Result;
+ return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
+ Friend, FLoc);
}
FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
- return new (Mem) FriendTemplateDecl(EmptyShell());
+ return new (C, ID) FriendTemplateDecl(EmptyShell());
}
//===----------------------------------------------------------------------===//
@@ -916,14 +887,13 @@ TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
TemplateParameterList *Params,
NamedDecl *Decl) {
AdoptTemplateParameterList(Params, DC);
- return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
+ return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
}
TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
- return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
- 0, 0);
+ return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
+ DeclarationName(), nullptr, nullptr);
}
void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
@@ -945,10 +915,8 @@ void ClassScopeFunctionSpecializationDecl::anchor() { }
ClassScopeFunctionSpecializationDecl *
ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID,
- sizeof(ClassScopeFunctionSpecializationDecl));
- return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
- false, TemplateArgumentListInfo());
+ return new (C, ID) ClassScopeFunctionSpecializationDecl(
+ nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
}
//===----------------------------------------------------------------------===//
@@ -966,33 +934,30 @@ VarTemplateDecl *VarTemplateDecl::getDefinition() {
return CurD;
CurD = CurD->getPreviousDecl();
}
- return 0;
+ return nullptr;
}
VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params,
- NamedDecl *Decl,
- VarTemplateDecl *PrevDecl) {
- VarTemplateDecl *New = new (C) VarTemplateDecl(DC, L, Name, Params, Decl);
- New->setPreviousDecl(PrevDecl);
- return New;
+ VarDecl *Decl) {
+ return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
}
VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarTemplateDecl));
- return new (Mem) VarTemplateDecl(EmptyShell());
+ return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
+ DeclarationName(), nullptr, nullptr);
}
-// TODO: Unify accross class, function and variable templates?
+// TODO: Unify across class, function and variable templates?
// May require moving this and Common to RedeclarableTemplateDecl.
void VarTemplateDecl::LoadLazySpecializations() const {
Common *CommonPtr = getCommonPtr();
if (CommonPtr->LazySpecializations) {
ASTContext &Context = getASTContext();
uint32_t *Specs = CommonPtr->LazySpecializations;
- CommonPtr->LazySpecializations = 0;
+ CommonPtr->LazySpecializations = nullptr;
for (uint32_t I = 0, N = *Specs++; I != N; ++I)
(void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
}
@@ -1018,9 +983,9 @@ VarTemplateDecl::newCommon(ASTContext &C) const {
}
VarTemplateSpecializationDecl *
-VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos) {
- return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+ void *&InsertPos) {
+ return findSpecializationImpl(getSpecializations(), Args, InsertPos);
}
void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
@@ -1038,10 +1003,9 @@ void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
}
VarTemplatePartialSpecializationDecl *
-VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos) {
- return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
- InsertPos);
+VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
+ void *&InsertPos) {
+ return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
}
void VarTemplateDecl::AddPartialSpecialization(
@@ -1084,47 +1048,43 @@ VarTemplateDecl::findPartialSpecInstantiatedFromMember(
return P->getMostRecentDecl();
}
- return 0;
+ return nullptr;
}
//===----------------------------------------------------------------------===//
// VarTemplateSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
- ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
unsigned NumArgs)
- : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T,
- TInfo, S),
- SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0),
+ : VarDecl(DK, Context, DC, StartLoc, IdLoc,
+ SpecializedTemplate->getIdentifier(), T, TInfo, S),
+ SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
SpecializationKind(TSK_Undeclared) {}
-VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK)
- : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0,
- SC_None),
- ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {}
+VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
+ ASTContext &C)
+ : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
+ QualType(), nullptr, SC_None),
+ ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
unsigned NumArgs) {
- VarTemplateSpecializationDecl *Result = new (Context)
- VarTemplateSpecializationDecl(Context, VarTemplateSpecialization, DC,
- StartLoc, IdLoc, SpecializedTemplate, T,
- TInfo, S, Args, NumArgs);
- return Result;
+ return new (Context, DC) VarTemplateSpecializationDecl(
+ VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
+ SpecializedTemplate, T, TInfo, S, Args, NumArgs);
}
VarTemplateSpecializationDecl *
VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem =
- AllocateDeserializedDecl(C, ID, sizeof(VarTemplateSpecializationDecl));
- VarTemplateSpecializationDecl *Result =
- new (Mem) VarTemplateSpecializationDecl(VarTemplateSpecialization);
- return Result;
+ return new (C, ID)
+ VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
}
void VarTemplateSpecializationDecl::getNameForDiagnostic(
@@ -1163,11 +1123,11 @@ VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
const ASTTemplateArgumentListInfo *ArgInfos)
- : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization,
+ : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
DC, StartLoc, IdLoc, SpecializedTemplate, T,
TInfo, S, Args, NumArgs),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
- InstantiatedFromMember(0, false) {
+ InstantiatedFromMember(nullptr, false) {
// TODO: The template parameters should be in DC by now. Verify.
// AdoptTemplateParameterList(Params, DC);
}
@@ -1183,7 +1143,7 @@ VarTemplatePartialSpecializationDecl::Create(
= ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
VarTemplatePartialSpecializationDecl *Result =
- new (Context) VarTemplatePartialSpecializationDecl(
+ new (Context, DC) VarTemplatePartialSpecializationDecl(
Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
S, Args, NumArgs, ASTArgInfos);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
@@ -1193,9 +1153,5 @@ VarTemplatePartialSpecializationDecl::Create(
VarTemplatePartialSpecializationDecl *
VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(
- C, ID, sizeof(VarTemplatePartialSpecializationDecl));
- VarTemplatePartialSpecializationDecl *Result =
- new (Mem) VarTemplatePartialSpecializationDecl();
- return Result;
+ return new (C, ID) VarTemplatePartialSpecializationDecl(C);
}
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp b/contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp
index e064e23..b7c2877 100644
--- a/contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/DeclarationName.cpp
@@ -143,13 +143,16 @@ raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
- return OS << N.getObjCSelector().getAsString();
+ N.getObjCSelector().print(OS);
+ return OS;
case DeclarationName::CXXConstructorName: {
QualType ClassType = N.getCXXNameType();
if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
return OS << *ClassRec->getDecl();
- return OS << ClassType.getAsString();
+ LangOptions LO;
+ LO.CPlusPlus = true;
+ return OS << ClassType.getAsString(PrintingPolicy(LO));
}
case DeclarationName::CXXDestructorName: {
@@ -157,12 +160,14 @@ raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
QualType Type = N.getCXXNameType();
if (const RecordType *Rec = Type->getAs<RecordType>())
return OS << *Rec->getDecl();
- return OS << Type.getAsString();
+ LangOptions LO;
+ LO.CPlusPlus = true;
+ return OS << Type.getAsString(PrintingPolicy(LO));
}
case DeclarationName::CXXOperatorName: {
static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
- 0,
+ nullptr,
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
Spelling,
#include "clang/Basic/OperatorKinds.def"
@@ -184,7 +189,10 @@ raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
QualType Type = N.getCXXNameType();
if (const RecordType *Rec = Type->getAs<RecordType>())
return OS << *Rec->getDecl();
- return OS << Type.getAsString();
+ LangOptions LO;
+ LO.CPlusPlus = true;
+ LO.Bool = true;
+ return OS << Type.getAsString(PrintingPolicy(LO));
}
case DeclarationName::CXXUsingDirective:
return OS << "<using-directive>";
@@ -265,7 +273,7 @@ IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
return CXXLit->ID;
else
- return 0;
+ return nullptr;
}
void *DeclarationName::getFETokenInfoAsVoidSlow() const {
@@ -338,7 +346,7 @@ DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
CXXOperatorNames[Op].ExtraKindOrNumArgs
= Op + DeclarationNameExtra::CXXConversionFunction;
- CXXOperatorNames[Op].FETokenInfo = 0;
+ CXXOperatorNames[Op].FETokenInfo = nullptr;
}
}
@@ -399,14 +407,14 @@ DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
ID.AddInteger(EKind);
ID.AddPointer(Ty.getAsOpaquePtr());
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
return DeclarationName(Name);
CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
SpecialName->ExtraKindOrNumArgs = EKind;
SpecialName->Type = Ty;
- SpecialName->FETokenInfo = 0;
+ SpecialName->FETokenInfo = nullptr;
SpecialNames->InsertNode(SpecialName, InsertPos);
return DeclarationName(SpecialName);
@@ -426,7 +434,7 @@ DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
llvm::FoldingSetNodeID ID;
ID.AddPointer(II);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (CXXLiteralOperatorIdName *Name =
LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
return DeclarationName (Name);
@@ -434,7 +442,7 @@ DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
LiteralName->ID = II;
- LiteralName->FETokenInfo = 0;
+ LiteralName->FETokenInfo = nullptr;
LiteralNames->InsertNode(LiteralName, InsertPos);
return DeclarationName(LiteralName);
@@ -447,7 +455,7 @@ DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName:
- NamedType.TInfo = 0;
+ NamedType.TInfo = nullptr;
break;
case DeclarationName::CXXOperatorName:
CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
@@ -537,7 +545,10 @@ void DeclarationNameInfo::printName(raw_ostream &OS) const {
OS << '~';
else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
OS << "operator ";
- OS << TInfo->getType().getAsString();
+ LangOptions LO;
+ LO.CPlusPlus = true;
+ LO.Bool = true;
+ OS << TInfo->getType().getAsString(PrintingPolicy(LO));
} else
OS << Name;
return;
diff --git a/contrib/llvm/tools/clang/lib/AST/Expr.cpp b/contrib/llvm/tools/clang/lib/AST/Expr.cpp
index 9055ddac..5f559b7 100644
--- a/contrib/llvm/tools/clang/lib/AST/Expr.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/Expr.cpp
@@ -44,7 +44,7 @@ const CXXRecordDecl *Expr::getBestDynamicClassType() const {
DerivedType = PTy->getPointeeType();
if (DerivedType->isDependentType())
- return NULL;
+ return nullptr;
const RecordType *Ty = DerivedType->castAs<RecordType>();
Decl *D = Ty->getDecl();
@@ -105,37 +105,6 @@ const Expr *Expr::skipRValueSubobjectAdjustments(
return E;
}
-const Expr *
-Expr::findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const {
- const Expr *E = this;
-
- // This might be a default initializer for a reference member. Walk over the
- // wrapper node for that.
- if (const CXXDefaultInitExpr *DAE = dyn_cast<CXXDefaultInitExpr>(E))
- E = DAE->getExpr();
-
- // Look through single-element init lists that claim to be lvalues. They're
- // just syntactic wrappers in this case.
- if (const InitListExpr *ILE = dyn_cast<InitListExpr>(E)) {
- if (ILE->getNumInits() == 1 && ILE->isGLValue()) {
- E = ILE->getInit(0);
- if (const CXXDefaultInitExpr *DAE = dyn_cast<CXXDefaultInitExpr>(E))
- E = DAE->getExpr();
- }
- }
-
- // Look through expressions for materialized temporaries (for now).
- if (const MaterializeTemporaryExpr *M
- = dyn_cast<MaterializeTemporaryExpr>(E)) {
- MTE = M;
- E = M->GetTemporaryExpr();
- }
-
- if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E))
- E = DAE->getExpr();
- return E;
-}
-
/// 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
@@ -152,6 +121,8 @@ bool Expr::isKnownToHaveBooleanValue() const {
switch (UO->getOpcode()) {
case UO_Plus:
return UO->getSubExpr()->isKnownToHaveBooleanValue();
+ case UO_LNot:
+ return true;
default:
return false;
}
@@ -431,7 +402,7 @@ DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context,
const TemplateArgumentListInfo *TemplateArgs) {
// Filter out cases where the found Decl is the same as the value refenenced.
if (D == FoundD)
- FoundD = 0;
+ FoundD = nullptr;
std::size_t Size = sizeof(DeclRefExpr);
if (QualifierLoc)
@@ -484,7 +455,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
if (IT == PredefinedExpr::FuncDName) {
if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurrentDecl)) {
- OwningPtr<MangleContext> MC;
+ std::unique_ptr<MangleContext> MC;
MC.reset(Context.createMangleContext());
if (MC->shouldMangleDeclName(ND)) {
@@ -507,7 +478,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
return "";
}
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
- if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual)
+ if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && IT != FuncSig)
return FD->getNameAsString();
SmallString<256> Name;
@@ -523,16 +494,28 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
PrintingPolicy Policy(Context.getLangOpts());
std::string Proto;
llvm::raw_string_ostream POut(Proto);
- FD->printQualifiedName(POut, Policy);
const FunctionDecl *Decl = FD;
if (const FunctionDecl* Pattern = FD->getTemplateInstantiationPattern())
Decl = Pattern;
const FunctionType *AFT = Decl->getType()->getAs<FunctionType>();
- const FunctionProtoType *FT = 0;
+ const FunctionProtoType *FT = nullptr;
if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(AFT);
+ if (IT == FuncSig) {
+ switch (FT->getCallConv()) {
+ case CC_C: POut << "__cdecl "; break;
+ case CC_X86StdCall: POut << "__stdcall "; break;
+ case CC_X86FastCall: POut << "__fastcall "; break;
+ case CC_X86ThisCall: POut << "__thiscall "; break;
+ // Only bother printing the conventions that MSVC knows about.
+ default: break;
+ }
+ }
+
+ FD->printQualifiedName(POut, Policy);
+
POut << "(";
if (FT) {
for (unsigned i = 0, e = Decl->getNumParams(); i != e; ++i) {
@@ -619,13 +602,15 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
// not a constructor or destructor.
if ((isa<CXXMethodDecl>(FD) &&
cast<CXXMethodDecl>(FD)->getParent()->isLambda()) ||
- (FT && FT->getResultType()->getAs<AutoType>()))
+ (FT && FT->getReturnType()->getAs<AutoType>()))
Proto = "auto " + Proto;
- else if (FT && FT->getResultType()->getAs<DecltypeType>())
- FT->getResultType()->getAs<DecltypeType>()->getUnderlyingType()
+ else if (FT && FT->getReturnType()->getAs<DecltypeType>())
+ FT->getReturnType()
+ ->getAs<DecltypeType>()
+ ->getUnderlyingType()
.getAsStringInternal(Proto, Policy);
else if (!isa<CXXConstructorDecl>(FD) && !isa<CXXDestructorDecl>(FD))
- AFT->getResultType().getAsStringInternal(Proto, Policy);
+ AFT->getReturnType().getAsStringInternal(Proto, Policy);
Out << Proto;
@@ -658,7 +643,7 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
Out << '(' << *CID << ')';
Out << ' ';
- Out << MD->getSelector().getAsString();
+ MD->getSelector().print(Out);
Out << ']';
Out.flush();
@@ -810,6 +795,9 @@ StringLiteral *StringLiteral::Create(const ASTContext &C, StringRef Str,
StringKind Kind, bool Pascal, QualType Ty,
const SourceLocation *Loc,
unsigned NumStrs) {
+ assert(C.getAsConstantArrayType(Ty) &&
+ "StringLiteral must be of constant array type!");
+
// Allocate enough space for the StringLiteral plus an array of locations for
// any concatenated string tokens.
void *Mem = C.Allocate(sizeof(StringLiteral)+
@@ -1010,7 +998,7 @@ getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
TheLexer.LexFromRawLexer(TheTok);
// Use the StringLiteralParser to compute the length of the string in bytes.
- StringLiteralParser SLP(&TheTok, 1, SM, Features, Target);
+ StringLiteralParser SLP(TheTok, SM, Features, Target);
unsigned TokNumBytes = SLP.GetStringLength();
// If the byte is in this token, return the location of the byte.
@@ -1144,7 +1132,7 @@ CallExpr::CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args,
}
CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), SubExprs(0), NumArgs(0) {
+ : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) {
// FIXME: Why do we allocate this?
SubExprs = new (C) Stmt*[PREARGS_START];
CallExprBits.NumPreArgs = 0;
@@ -1152,7 +1140,7 @@ CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty)
CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
EmptyShell Empty)
- : Expr(SC, Empty), SubExprs(0), NumArgs(0) {
+ : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) {
// FIXME: Why do we allocate this?
SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs];
CallExprBits.NumPreArgs = NumPreArgs;
@@ -1179,7 +1167,7 @@ Decl *CallExpr::getCalleeDecl() {
if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))
return ME->getMemberDecl();
- return 0;
+ return nullptr;
}
FunctionDecl *CallExpr::getDirectCallee() {
@@ -1208,16 +1196,16 @@ void CallExpr::setNumArgs(const ASTContext& C, unsigned NumArgs) {
// Null out new args.
for (unsigned i = getNumArgs()+PREARGS_START+NumPreArgs;
i != NumArgs+PREARGS_START+NumPreArgs; ++i)
- NewSubExprs[i] = 0;
+ NewSubExprs[i] = nullptr;
if (SubExprs) C.Deallocate(SubExprs);
SubExprs = NewSubExprs;
this->NumArgs = NumArgs;
}
-/// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If
+/// getBuiltinCallee - If this is a call to a builtin, return the builtin ID. If
/// not, return 0.
-unsigned CallExpr::isBuiltinCall() const {
+unsigned CallExpr::getBuiltinCallee() const {
// All simple function calls (e.g. func()) are implicitly cast to pointer to
// function. As a result, we try and obtain the DeclRefExpr from the
// ImplicitCastExpr.
@@ -1240,7 +1228,7 @@ unsigned CallExpr::isBuiltinCall() const {
}
bool CallExpr::isUnevaluatedBuiltinCall(ASTContext &Ctx) const {
- if (unsigned BI = isBuiltinCall())
+ if (unsigned BI = getBuiltinCallee())
return Ctx.BuiltinInfo.isUnevaluated(BI);
return false;
}
@@ -1256,7 +1244,7 @@ QualType CallExpr::getCallReturnType() const {
CalleeType = Expr::findBoundMemberType(getCallee());
const FunctionType *FnType = CalleeType->castAs<FunctionType>();
- return FnType->getResultType();
+ return FnType->getReturnType();
}
SourceLocation CallExpr::getLocStart() const {
@@ -1421,7 +1409,7 @@ SourceLocation MemberExpr::getLocEnd() const {
return EndLoc;
}
-void CastExpr::CheckCastConsistency() const {
+bool CastExpr::CastConsistency() const {
switch (getCastKind()) {
case CK_DerivedToBase:
case CK_UncheckedDerivedToBase:
@@ -1474,6 +1462,11 @@ void CastExpr::CheckCastConsistency() const {
assert(getSubExpr()->getType()->isFunctionType());
goto CheckNoBasePath;
+ case CK_AddressSpaceConversion:
+ assert(getType()->isPointerType());
+ assert(getSubExpr()->getType()->isPointerType());
+ assert(getType()->getPointeeType().getAddressSpace() !=
+ getSubExpr()->getType()->getPointeeType().getAddressSpace());
// These should not have an inheritance path.
case CK_Dynamic:
case CK_ToUnion:
@@ -1524,6 +1517,7 @@ void CastExpr::CheckCastConsistency() const {
assert(path_empty() && "Cast kind should not have a base path!");
break;
}
+ return true;
}
const char *CastExpr::getCastKindName() const {
@@ -1625,7 +1619,7 @@ const char *CastExpr::getCastKindName() const {
case CK_ARCReclaimReturnedObject:
return "ARCReclaimReturnedObject";
case CK_ARCExtendBlockObject:
- return "ARCCExtendBlockObject";
+ return "ARCExtendBlockObject";
case CK_AtomicToNonAtomic:
return "AtomicToNonAtomic";
case CK_NonAtomicToAtomic:
@@ -1636,13 +1630,15 @@ const char *CastExpr::getCastKindName() const {
return "BuiltinFnToFnPtr";
case CK_ZeroToOCLEvent:
return "ZeroToOCLEvent";
+ case CK_AddressSpaceConversion:
+ return "AddressSpaceConversion";
}
llvm_unreachable("Unhandled cast kind!");
}
Expr *CastExpr::getSubExprAsWritten() {
- Expr *SubExpr = 0;
+ Expr *SubExpr = nullptr;
CastExpr *E = this;
do {
SubExpr = E->getSubExpr();
@@ -1838,7 +1834,7 @@ InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
: Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
false, false),
InitExprs(C, initExprs.size()),
- LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(0, true)
+ LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, true)
{
sawArrayRangeDesignator(false);
for (unsigned I = 0; I != initExprs.size(); ++I) {
@@ -1861,18 +1857,18 @@ void InitListExpr::reserveInits(const ASTContext &C, unsigned NumInits) {
}
void InitListExpr::resizeInits(const ASTContext &C, unsigned NumInits) {
- InitExprs.resize(C, NumInits, 0);
+ InitExprs.resize(C, NumInits, nullptr);
}
Expr *InitListExpr::updateInit(const ASTContext &C, unsigned Init, Expr *expr) {
if (Init >= InitExprs.size()) {
- InitExprs.insert(C, InitExprs.end(), Init - InitExprs.size() + 1, 0);
- InitExprs.back() = expr;
- return 0;
+ InitExprs.insert(C, InitExprs.end(), Init - InitExprs.size() + 1, nullptr);
+ setInit(Init, expr);
+ return nullptr;
}
Expr *Result = cast_or_null<Expr>(InitExprs[Init]);
- InitExprs[Init] = expr;
+ setInit(Init, expr);
return Result;
}
@@ -1882,7 +1878,7 @@ void InitListExpr::setArrayFiller(Expr *filler) {
// Fill out any "holes" in the array due to designated initializers.
Expr **inits = getInits();
for (unsigned i = 0, e = getNumInits(); i != e; ++i)
- if (inits[i] == 0)
+ if (inits[i] == nullptr)
inits[i] = filler;
}
@@ -1892,7 +1888,11 @@ bool InitListExpr::isStringLiteralInit() const {
const ArrayType *AT = getType()->getAsArrayTypeUnsafe();
if (!AT || !AT->getElementType()->isIntegerType())
return false;
- const Expr *Init = getInit(0)->IgnoreParens();
+ // It is possible for getInit() to return null.
+ const Expr *Init = getInit(0);
+ if (!Init)
+ return false;
+ Init = Init->IgnoreParens();
return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init);
}
@@ -2078,15 +2078,25 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
return true;
case CXXOperatorCallExprClass: {
- // We warn about operator== and operator!= even when user-defined operator
+ // Warn about operator ==,!=,<,>,<=, and >= even when user-defined operator
// overloads as there is no reasonable way to define these such that they
// have non-trivial, desirable side-effects. See the -Wunused-comparison
- // warning: these operators are commonly typo'ed, and so warning on them
+ // warning: operators == and != are commonly typo'ed, and so warning on them
// provides additional value as well. If this list is updated,
// DiagnoseUnusedComparison should be as well.
const CXXOperatorCallExpr *Op = cast<CXXOperatorCallExpr>(this);
- if (Op->getOperator() == OO_EqualEqual ||
- Op->getOperator() == OO_ExclaimEqual) {
+ switch (Op->getOperator()) {
+ default:
+ break;
+ case OO_EqualEqual:
+ case OO_ExclaimEqual:
+ case OO_Less:
+ case OO_Greater:
+ case OO_GreaterEqual:
+ case OO_LessEqual:
+ if (Op->getCallReturnType()->isReferenceType() ||
+ Op->getCallReturnType()->isVoidType())
+ break;
WarnE = this;
Loc = Op->getOperatorLoc();
R1 = Op->getSourceRange();
@@ -2106,8 +2116,8 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
//
// Note: If new cases are added here, DiagnoseUnusedExprResult should be
// updated to match for QoI.
- if (FD->getAttr<WarnUnusedResultAttr>() ||
- FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) {
+ if (FD->hasAttr<WarnUnusedResultAttr>() ||
+ FD->hasAttr<PureAttr>() || FD->hasAttr<ConstAttr>()) {
WarnE = this;
Loc = CE->getCallee()->getLocStart();
R1 = CE->getCallee()->getSourceRange();
@@ -2151,12 +2161,15 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
return true;
}
- const ObjCMethodDecl *MD = ME->getMethodDecl();
- if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
- WarnE = this;
- Loc = getExprLoc();
- return true;
- }
+ if (const ObjCMethodDecl *MD = ME->getMethodDecl())
+ if (MD->hasAttr<WarnUnusedResultAttr>() ||
+ (MD->isPropertyAccessor() && !MD->getReturnType()->isVoidType() &&
+ !ME->getReceiverType()->isObjCIdType())) {
+ WarnE = this;
+ Loc = getExprLoc();
+ return true;
+ }
+
return false;
}
@@ -2393,6 +2406,27 @@ Expr *Expr::IgnoreParenCasts() {
}
}
+Expr *Expr::IgnoreCasts() {
+ Expr *E = this;
+ while (true) {
+ if (CastExpr *P = dyn_cast<CastExpr>(E)) {
+ E = P->getSubExpr();
+ continue;
+ }
+ if (MaterializeTemporaryExpr *Materialize
+ = dyn_cast<MaterializeTemporaryExpr>(E)) {
+ E = Materialize->GetTemporaryExpr();
+ continue;
+ }
+ if (SubstNonTypeTemplateParmExpr *NTTP
+ = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
+ E = NTTP->getReplacement();
+ continue;
+ }
+ return E;
+ }
+}
+
/// IgnoreParenLValueCasts - Ignore parentheses and lvalue-to-rvalue
/// casts. This is intended purely as a temporary workaround for code
/// that hasn't yet been rewritten to do the right thing about those
@@ -2638,7 +2672,8 @@ bool Expr::hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs) {
return false;
}
-bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
+bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
+ const Expr **Culprit) const {
// This function is attempting whether an expression is an initializer
// which can be evaluated at compile-time. It very closely parallels
// ConstExprEmitter in CGExprConstant.cpp; if they don't match, it
@@ -2650,7 +2685,11 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
if (IsForRef) {
EvalResult Result;
- return EvaluateAsLValue(Result, Ctx) && !Result.HasSideEffects;
+ if (EvaluateAsLValue(Result, Ctx) && !Result.HasSideEffects)
+ return true;
+ if (Culprit)
+ *Culprit = this;
+ return false;
}
switch (getStmtClass()) {
@@ -2669,7 +2708,7 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
// Trivial copy constructor
assert(CE->getNumArgs() == 1 && "trivial ctor with > 1 argument");
- return CE->getArg(0)->isConstantInitializer(Ctx, false);
+ return CE->getArg(0)->isConstantInitializer(Ctx, false, Culprit);
}
break;
@@ -2679,14 +2718,14 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
// "struct x {int x;} x = (struct x) {};".
// FIXME: This accepts other cases it shouldn't!
const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer();
- return Exp->isConstantInitializer(Ctx, false);
+ return Exp->isConstantInitializer(Ctx, false, Culprit);
}
case InitListExprClass: {
const InitListExpr *ILE = cast<InitListExpr>(this);
if (ILE->getType()->isArrayType()) {
unsigned numInits = ILE->getNumInits();
for (unsigned i = 0; i < numInits; i++) {
- if (!ILE->getInit(i)->isConstantInitializer(Ctx, false))
+ if (!ILE->getInit(i)->isConstantInitializer(Ctx, false, Culprit))
return false;
}
return true;
@@ -2710,11 +2749,14 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
if (Field->isBitField()) {
// Bitfields have to evaluate to an integer.
llvm::APSInt ResultTmp;
- if (!Elt->EvaluateAsInt(ResultTmp, Ctx))
+ if (!Elt->EvaluateAsInt(ResultTmp, Ctx)) {
+ if (Culprit)
+ *Culprit = Elt;
return false;
+ }
} else {
bool RefType = Field->getType()->isReferenceType();
- if (!Elt->isConstantInitializer(Ctx, RefType))
+ if (!Elt->isConstantInitializer(Ctx, RefType, Culprit))
return false;
}
}
@@ -2728,19 +2770,22 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
return true;
case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()
- ->isConstantInitializer(Ctx, IsForRef);
+ ->isConstantInitializer(Ctx, IsForRef, Culprit);
case GenericSelectionExprClass:
return cast<GenericSelectionExpr>(this)->getResultExpr()
- ->isConstantInitializer(Ctx, IsForRef);
+ ->isConstantInitializer(Ctx, IsForRef, Culprit);
case ChooseExprClass:
- if (cast<ChooseExpr>(this)->isConditionDependent())
+ if (cast<ChooseExpr>(this)->isConditionDependent()) {
+ if (Culprit)
+ *Culprit = this;
return false;
+ }
return cast<ChooseExpr>(this)->getChosenSubExpr()
- ->isConstantInitializer(Ctx, IsForRef);
+ ->isConstantInitializer(Ctx, IsForRef, Culprit);
case UnaryOperatorClass: {
const UnaryOperator* Exp = cast<UnaryOperator>(this);
if (Exp->getOpcode() == UO_Extension)
- return Exp->getSubExpr()->isConstantInitializer(Ctx, false);
+ return Exp->getSubExpr()->isConstantInitializer(Ctx, false, Culprit);
break;
}
case CXXFunctionalCastExprClass:
@@ -2760,25 +2805,29 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
CE->getCastKind() == CK_ConstructorConversion ||
CE->getCastKind() == CK_NonAtomicToAtomic ||
CE->getCastKind() == CK_AtomicToNonAtomic)
- return CE->getSubExpr()->isConstantInitializer(Ctx, false);
+ return CE->getSubExpr()->isConstantInitializer(Ctx, false, Culprit);
break;
}
case MaterializeTemporaryExprClass:
return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()
- ->isConstantInitializer(Ctx, false);
+ ->isConstantInitializer(Ctx, false, Culprit);
case SubstNonTypeTemplateParmExprClass:
return cast<SubstNonTypeTemplateParmExpr>(this)->getReplacement()
- ->isConstantInitializer(Ctx, false);
+ ->isConstantInitializer(Ctx, false, Culprit);
case CXXDefaultArgExprClass:
return cast<CXXDefaultArgExpr>(this)->getExpr()
- ->isConstantInitializer(Ctx, false);
+ ->isConstantInitializer(Ctx, false, Culprit);
case CXXDefaultInitExprClass:
return cast<CXXDefaultInitExpr>(this)->getExpr()
- ->isConstantInitializer(Ctx, false);
+ ->isConstantInitializer(Ctx, false, Culprit);
}
- return isEvaluatable(Ctx);
+ if (isEvaluatable(Ctx))
+ return true;
+ if (Culprit)
+ *Culprit = this;
+ return false;
}
bool Expr::HasSideEffects(const ASTContext &Ctx) const {
@@ -2821,8 +2870,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx) const {
case CXXThisExprClass:
case CXXScalarValueInitExprClass:
case TypeTraitExprClass:
- case UnaryTypeTraitExprClass:
- case BinaryTypeTraitExprClass:
case ArrayTypeTraitExprClass:
case ExpressionTraitExprClass:
case CXXNoexceptExprClass:
@@ -3055,7 +3102,7 @@ Expr::NullPointerConstantKind
Expr::isNullPointerConstant(ASTContext &Ctx,
NullPointerConstantValueDependence NPC) const {
if (isValueDependent() &&
- (!Ctx.getLangOpts().CPlusPlus11 || Ctx.getLangOpts().MicrosoftMode)) {
+ (!Ctx.getLangOpts().CPlusPlus11 || Ctx.getLangOpts().MSVCCompat)) {
switch (NPC) {
case NPC_NeverValueDependent:
llvm_unreachable("Unexpected value dependent expression!");
@@ -3141,8 +3188,7 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
const IntegerLiteral *Lit = dyn_cast<IntegerLiteral>(this);
if (Lit && !Lit->getValue())
return NPCK_ZeroLiteral;
- else if (!Ctx.getLangOpts().MicrosoftMode ||
- !isCXX98IntegralConstantExpr(Ctx))
+ else if (!Ctx.getLangOpts().MSVCCompat || !isCXX98IntegralConstantExpr(Ctx))
return NPCK_NotNull;
} else {
// If we have an integer constant expression, we need to *evaluate* it and
@@ -3233,7 +3279,7 @@ FieldDecl *Expr::getSourceBitField() {
return BinOp->getRHS()->getSourceBitField();
}
- return 0;
+ return nullptr;
}
bool Expr::refersToVectorElement() const {
@@ -3339,8 +3385,9 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T,
SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
: Sel.getAsOpaquePtr())),
Kind(IsInstanceSuper? SuperInstance : SuperClass),
- HasMethod(Method != 0), IsDelegateInitCall(false), IsImplicit(isImplicit),
- SuperLoc(SuperLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
+ HasMethod(Method != nullptr), IsDelegateInitCall(false),
+ IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
+ RBracLoc(RBracLoc)
{
initArgsAndSelLocs(Args, SelLocs, SelLocsK);
setReceiverPointer(SuperType.getAsOpaquePtr());
@@ -3363,8 +3410,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T,
SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
: Sel.getAsOpaquePtr())),
Kind(Class),
- HasMethod(Method != 0), IsDelegateInitCall(false), IsImplicit(isImplicit),
- LBracLoc(LBracLoc), RBracLoc(RBracLoc)
+ HasMethod(Method != nullptr), IsDelegateInitCall(false),
+ IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
{
initArgsAndSelLocs(Args, SelLocs, SelLocsK);
setReceiverPointer(Receiver);
@@ -3388,8 +3435,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T,
SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
: Sel.getAsOpaquePtr())),
Kind(Instance),
- HasMethod(Method != 0), IsDelegateInitCall(false), IsImplicit(isImplicit),
- LBracLoc(LBracLoc), RBracLoc(RBracLoc)
+ HasMethod(Method != nullptr), IsDelegateInitCall(false),
+ IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
{
initArgsAndSelLocs(Args, SelLocs, SelLocsK);
setReceiverPointer(Receiver);
@@ -3571,7 +3618,7 @@ ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
return Ty->getInterface();
- return 0;
+ return nullptr;
}
StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
@@ -3806,30 +3853,21 @@ SourceLocation DesignatedInitExpr::getLocEnd() const {
Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) const {
assert(D.Kind == Designator::ArrayDesignator && "Requires array designator");
- char *Ptr = static_cast<char *>(
- const_cast<void *>(static_cast<const void *>(this)));
- Ptr += sizeof(DesignatedInitExpr);
- Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+ Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1);
return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
}
Expr *DesignatedInitExpr::getArrayRangeStart(const Designator &D) const {
assert(D.Kind == Designator::ArrayRangeDesignator &&
"Requires array range designator");
- char *Ptr = static_cast<char *>(
- const_cast<void *>(static_cast<const void *>(this)));
- Ptr += sizeof(DesignatedInitExpr);
- Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+ Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1);
return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
}
Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator &D) const {
assert(D.Kind == Designator::ArrayRangeDesignator &&
"Requires array range designator");
- char *Ptr = static_cast<char *>(
- const_cast<void *>(static_cast<const void *>(this)));
- Ptr += sizeof(DesignatedInitExpr);
- Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+ Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1);
return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 2));
}
@@ -3953,7 +3991,7 @@ PseudoObjectExpr::PseudoObjectExpr(QualType type, ExprValueKind VK,
ExprBits.ContainsUnexpandedParameterPack = true;
if (isa<OpaqueValueExpr>(E))
- assert(cast<OpaqueValueExpr>(E)->getSourceExpr() != 0 &&
+ assert(cast<OpaqueValueExpr>(E)->getSourceExpr() != nullptr &&
"opaque-value semantic expressions for pseudo-object "
"operations must have sources");
}
diff --git a/contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp b/contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp
index 3738c0e..64c21dd 100644
--- a/contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ExprCXX.cpp
@@ -55,8 +55,8 @@ QualType CXXUuidofExpr::getTypeOperand(ASTContext &Context) const {
}
// static
-UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT,
- bool *RDHasMultipleGUIDsPtr) {
+const UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT,
+ bool *RDHasMultipleGUIDsPtr) {
// Optionally remove one level of pointer, reference or array indirection.
const Type *Ty = QT.getTypePtr();
if (QT->isPointerType() || QT->isReferenceType())
@@ -64,22 +64,23 @@ UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT,
else if (QT->isArrayType())
Ty = Ty->getBaseElementTypeUnsafe();
- // Loop all record redeclaration looking for an uuid attribute.
- CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+ const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
if (!RD)
- return 0;
+ return nullptr;
+
+ if (const UuidAttr *Uuid = RD->getMostRecentDecl()->getAttr<UuidAttr>())
+ return Uuid;
// __uuidof can grab UUIDs from template arguments.
- if (ClassTemplateSpecializationDecl *CTSD =
+ if (const ClassTemplateSpecializationDecl *CTSD =
dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
- UuidAttr *UuidForRD = 0;
+ const UuidAttr *UuidForRD = nullptr;
- for (unsigned I = 0, N = TAL.size(); I != N; ++I) {
- const TemplateArgument &TA = TAL[I];
+ for (const TemplateArgument &TA : TAL.asArray()) {
bool SeenMultipleGUIDs = false;
- UuidAttr *UuidForTA = 0;
+ const UuidAttr *UuidForTA = nullptr;
if (TA.getKind() == TemplateArgument::Type)
UuidForTA = GetUuidAttrOfType(TA.getAsType(), &SeenMultipleGUIDs);
else if (TA.getKind() == TemplateArgument::Declaration)
@@ -101,20 +102,14 @@ UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT,
if (SeenMultipleGUIDs) {
if (RDHasMultipleGUIDsPtr)
*RDHasMultipleGUIDsPtr = true;
- return 0;
+ return nullptr;
}
}
return UuidForRD;
}
- for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(),
- E = RD->redecls_end();
- I != E; ++I)
- if (UuidAttr *Uuid = I->getAttr<UuidAttr>())
- return Uuid;
-
- return 0;
+ return nullptr;
}
StringRef CXXUuidofExpr::getUuidAsStringRef(ASTContext &Context) const {
@@ -151,14 +146,15 @@ CXXNewExpr::CXXNewExpr(const ASTContext &C, bool globalNew,
ty->isDependentType(), ty->isDependentType(),
ty->isInstantiationDependentType(),
ty->containsUnexpandedParameterPack()),
- SubExprs(0), OperatorNew(operatorNew), OperatorDelete(operatorDelete),
+ SubExprs(nullptr), OperatorNew(operatorNew), OperatorDelete(operatorDelete),
AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens),
Range(Range), DirectInitRange(directInitRange),
GlobalNew(globalNew), UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) {
- assert((initializer != 0 || initializationStyle == NoInit) &&
+ assert((initializer != nullptr || initializationStyle == NoInit) &&
"Only NoInit can have no initializer.");
StoredInitializationStyle = initializer ? initializationStyle + 1 : 0;
- AllocateArgsArray(C, arraySize != 0, placementArgs.size(), initializer != 0);
+ AllocateArgsArray(C, arraySize != nullptr, placementArgs.size(),
+ initializer != nullptr);
unsigned i = 0;
if (Array) {
if (arraySize->isInstantiationDependent())
@@ -203,7 +199,7 @@ CXXNewExpr::CXXNewExpr(const ASTContext &C, bool globalNew,
void CXXNewExpr::AllocateArgsArray(const ASTContext &C, bool isArray,
unsigned numPlaceArgs, bool hasInitializer){
- assert(SubExprs == 0 && "SubExprs already allocated");
+ assert(SubExprs == nullptr && "SubExprs already allocated");
Array = isArray;
NumPlacementArgs = numPlaceArgs;
@@ -345,9 +341,9 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
QualifierLoc.getNestedNameSpecifier()
->containsUnexpandedParameterPack()))),
NameInfo(NameInfo), QualifierLoc(QualifierLoc),
- Results(0), NumResults(End - Begin),
- HasTemplateKWAndArgsInfo(TemplateArgs != 0 || TemplateKWLoc.isValid())
-{
+ Results(nullptr), NumResults(End - Begin),
+ HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
+ TemplateKWLoc.isValid()) {
NumResults = End - Begin;
if (NumResults) {
// Determine whether this expression is type-dependent.
@@ -398,7 +394,7 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
void OverloadExpr::initializeResults(const ASTContext &C,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
- assert(Results == 0 && "Results already initialized!");
+ assert(!Results && "Results already initialized!");
NumResults = End - Begin;
if (NumResults) {
Results = static_cast<DeclAccessPair *>(
@@ -433,7 +429,7 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T,
QualifierLoc.getNestedNameSpecifier()
->containsUnexpandedParameterPack()))),
QualifierLoc(QualifierLoc), NameInfo(NameInfo),
- HasTemplateKWAndArgsInfo(Args != 0 || TemplateKWLoc.isValid())
+ HasTemplateKWAndArgsInfo(Args != nullptr || TemplateKWLoc.isValid())
{
if (Args) {
bool Dependent = true;
@@ -478,7 +474,7 @@ DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &C,
DependentScopeDeclRefExpr *E
= new (Mem) DependentScopeDeclRefExpr(QualType(), NestedNameSpecifierLoc(),
SourceLocation(),
- DeclarationNameInfo(), 0);
+ DeclarationNameInfo(), nullptr);
E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
return E;
}
@@ -544,7 +540,7 @@ Expr *CXXMemberCallExpr::getImplicitObjectArgument() const {
return BO->getLHS();
// FIXME: Will eventually need to cope with member pointers.
- return 0;
+ return nullptr;
}
CXXMethodDecl *CXXMemberCallExpr::getMethodDecl() const {
@@ -553,14 +549,14 @@ CXXMethodDecl *CXXMemberCallExpr::getMethodDecl() const {
return cast<CXXMethodDecl>(MemExpr->getMemberDecl());
// FIXME: Will eventually need to cope with member pointers.
- return 0;
+ return nullptr;
}
CXXRecordDecl *CXXMemberCallExpr::getRecordDecl() const {
Expr* ThisArg = getImplicitObjectArgument();
if (!ThisArg)
- return 0;
+ return nullptr;
if (ThisArg->getType()->isAnyPointerType())
return ThisArg->getType()->getPointeeType()->getAsCXXRecordDecl();
@@ -810,13 +806,16 @@ CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C,
SourceRange ParenOrBraceRange,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization)
: CXXConstructExpr(C, CXXTemporaryObjectExprClass,
Type->getType().getNonReferenceType(),
Type->getTypeLoc().getBeginLoc(),
Cons, false, Args,
HadMultipleCandidates,
- ListInitialization, ZeroInitialization,
+ ListInitialization,
+ StdInitListInitialization,
+ ZeroInitialization,
CXXConstructExpr::CK_Complete, ParenOrBraceRange),
Type(Type) {
}
@@ -838,12 +837,14 @@ CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T,
ArrayRef<Expr*> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange) {
return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Elidable, Args,
HadMultipleCandidates, ListInitialization,
+ StdInitListInitialization,
ZeroInitialization, ConstructKind,
ParenOrBraceRange);
}
@@ -854,6 +855,7 @@ CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC,
ArrayRef<Expr*> args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange)
@@ -865,8 +867,9 @@ CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC,
NumArgs(args.size()),
Elidable(elidable), HadMultipleCandidates(HadMultipleCandidates),
ListInitialization(ListInitialization),
+ StdInitListInitialization(StdInitListInitialization),
ZeroInitialization(ZeroInitialization),
- ConstructKind(ConstructKind), Args(0)
+ ConstructKind(ConstructKind), Args(nullptr)
{
if (NumArgs) {
Args = new (C) Stmt*[args.size()];
@@ -886,7 +889,7 @@ CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC,
}
}
-LambdaExpr::Capture::Capture(SourceLocation Loc, bool Implicit,
+LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit,
LambdaCaptureKind Kind, VarDecl *Var,
SourceLocation EllipsisLoc)
: DeclAndBits(Var, 0), Loc(Loc), EllipsisLoc(EllipsisLoc)
@@ -896,8 +899,8 @@ LambdaExpr::Capture::Capture(SourceLocation Loc, bool Implicit,
Bits |= Capture_Implicit;
switch (Kind) {
- case LCK_This:
- assert(Var == 0 && "'this' capture cannot have a variable!");
+ case LCK_This:
+ assert(!Var && "'this' capture cannot have a variable!");
break;
case LCK_ByCopy:
@@ -910,7 +913,7 @@ LambdaExpr::Capture::Capture(SourceLocation Loc, bool Implicit,
DeclAndBits.setInt(Bits);
}
-LambdaCaptureKind LambdaExpr::Capture::getCaptureKind() const {
+LambdaCaptureKind LambdaCapture::getCaptureKind() const {
Decl *D = DeclAndBits.getPointer();
if (!D)
return LCK_This;
@@ -1031,6 +1034,10 @@ LambdaExpr::capture_iterator LambdaExpr::capture_end() const {
return capture_begin() + NumCaptures;
}
+LambdaExpr::capture_range LambdaExpr::captures() const {
+ return capture_range(capture_begin(), capture_end());
+}
+
LambdaExpr::capture_iterator LambdaExpr::explicit_capture_begin() const {
return capture_begin();
}
@@ -1041,6 +1048,10 @@ LambdaExpr::capture_iterator LambdaExpr::explicit_capture_end() const {
return Data.Captures + Data.NumExplicitCaptures;
}
+LambdaExpr::capture_range LambdaExpr::explicit_captures() const {
+ return capture_range(explicit_capture_begin(), explicit_capture_end());
+}
+
LambdaExpr::capture_iterator LambdaExpr::implicit_capture_begin() const {
return explicit_capture_end();
}
@@ -1049,6 +1060,10 @@ LambdaExpr::capture_iterator LambdaExpr::implicit_capture_end() const {
return capture_end();
}
+LambdaExpr::capture_range LambdaExpr::implicit_captures() const {
+ return capture_range(implicit_capture_begin(), implicit_capture_end());
+}
+
ArrayRef<VarDecl *>
LambdaExpr::getCaptureInitIndexVars(capture_init_iterator Iter) const {
assert(HasArrayIndexVars && "No array index-var data?");
@@ -1187,7 +1202,8 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(const ASTContext &C,
->containsUnexpandedParameterPack()) ||
MemberNameInfo.containsUnexpandedParameterPack())),
Base(Base), BaseType(BaseType), IsArrow(IsArrow),
- HasTemplateKWAndArgsInfo(TemplateArgs != 0 || TemplateKWLoc.isValid()),
+ HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
+ TemplateKWLoc.isValid()),
OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
MemberNameInfo(MemberNameInfo) {
@@ -1260,26 +1276,26 @@ CXXDependentScopeMemberExpr::CreateEmpty(const ASTContext &C,
bool HasTemplateKWAndArgsInfo,
unsigned NumTemplateArgs) {
if (!HasTemplateKWAndArgsInfo)
- return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(),
+ return new (C) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
0, SourceLocation(),
- NestedNameSpecifierLoc(), 0,
- DeclarationNameInfo());
+ NestedNameSpecifierLoc(),
+ nullptr, DeclarationNameInfo());
std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
void *Mem = C.Allocate(size, llvm::alignOf<CXXDependentScopeMemberExpr>());
CXXDependentScopeMemberExpr *E
- = new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(),
+ = new (Mem) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
0, SourceLocation(),
NestedNameSpecifierLoc(),
- SourceLocation(), 0,
- DeclarationNameInfo(), 0);
+ SourceLocation(), nullptr,
+ DeclarationNameInfo(), nullptr);
E->HasTemplateKWAndArgsInfo = true;
return E;
}
bool CXXDependentScopeMemberExpr::isImplicitAccess() const {
- if (Base == 0)
+ if (!Base)
return true;
return cast<Expr>(Base)->isImplicitCXXThis();
@@ -1291,16 +1307,11 @@ static bool hasOnlyNonStaticMemberFunctions(UnresolvedSetIterator begin,
NamedDecl *decl = *begin;
if (isa<UnresolvedUsingValueDecl>(decl))
return false;
- if (isa<UsingShadowDecl>(decl))
- decl = cast<UsingShadowDecl>(decl)->getUnderlyingDecl();
// Unresolved member expressions should only contain methods and
// method templates.
- assert(isa<CXXMethodDecl>(decl) || isa<FunctionTemplateDecl>(decl));
-
- if (isa<FunctionTemplateDecl>(decl))
- decl = cast<FunctionTemplateDecl>(decl)->getTemplatedDecl();
- if (cast<CXXMethodDecl>(decl)->isStatic())
+ if (cast<CXXMethodDecl>(decl->getUnderlyingDecl()->getAsFunction())
+ ->isStatic())
return false;
} while (++begin != end);
@@ -1338,7 +1349,7 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(const ASTContext &C,
}
bool UnresolvedMemberExpr::isImplicitAccess() const {
- if (Base == 0)
+ if (!Base)
return true;
return cast<Expr>(Base)->isImplicitCXXThis();
@@ -1387,7 +1398,7 @@ CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
// If there was a nested name specifier, it names the naming class.
// It can't be dependent: after all, we were actually able to do the
// lookup.
- CXXRecordDecl *Record = 0;
+ CXXRecordDecl *Record = nullptr;
if (getQualifier()) {
const Type *T = getQualifier()->getAsType();
assert(T && "qualifier in member expression does not name type");
@@ -1450,7 +1461,26 @@ FunctionParmPackExpr::CreateEmpty(const ASTContext &Context,
unsigned NumParams) {
return new (Context.Allocate(sizeof(FunctionParmPackExpr) +
sizeof(ParmVarDecl*) * NumParams))
- FunctionParmPackExpr(QualType(), 0, SourceLocation(), 0, 0);
+ FunctionParmPackExpr(QualType(), nullptr, SourceLocation(), 0, nullptr);
+}
+
+void MaterializeTemporaryExpr::setExtendingDecl(const ValueDecl *ExtendedBy,
+ unsigned ManglingNumber) {
+ // We only need extra state if we have to remember more than just the Stmt.
+ if (!ExtendedBy)
+ return;
+
+ // We may need to allocate extra storage for the mangling number and the
+ // extended-by ValueDecl.
+ if (!State.is<ExtraState *>()) {
+ auto ES = new (ExtendedBy->getASTContext()) ExtraState;
+ ES->Temporary = State.get<Stmt *>();
+ State = ES;
+ }
+
+ auto ES = State.get<ExtraState *>();
+ ES->ExtendingDecl = ExtendedBy;
+ ES->ManglingNumber = ManglingNumber;
}
TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
diff --git a/contrib/llvm/tools/clang/lib/AST/ExprClassification.cpp b/contrib/llvm/tools/clang/lib/AST/ExprClassification.cpp
index 54f77ef..d3d2530 100644
--- a/contrib/llvm/tools/clang/lib/AST/ExprClassification.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ExprClassification.cpp
@@ -165,8 +165,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::FloatingLiteralClass:
case Expr::CXXNoexceptExprClass:
case Expr::CXXScalarValueInitExprClass:
- case Expr::UnaryTypeTraitExprClass:
- case Expr::BinaryTypeTraitExprClass:
case Expr::TypeTraitExprClass:
case Expr::ArrayTypeTraitExprClass:
case Expr::ExpressionTraitExprClass:
@@ -348,7 +346,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::ObjCMessageExprClass:
if (const ObjCMethodDecl *Method =
cast<ObjCMessageExpr>(E)->getMethodDecl()) {
- Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getResultType());
+ Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getReturnType());
return (kind == Cl::CL_PRValue) ? Cl::CL_ObjCMessageRValue : kind;
}
return Cl::CL_PRValue;
@@ -543,10 +541,21 @@ static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *True,
"This is only relevant for C++.");
// C++ [expr.cond]p2
- // If either the second or the third operand has type (cv) void, [...]
- // the result [...] is a prvalue.
- if (True->getType()->isVoidType() || False->getType()->isVoidType())
+ // If either the second or the third operand has type (cv) void,
+ // one of the following shall hold:
+ if (True->getType()->isVoidType() || False->getType()->isVoidType()) {
+ // The second or the third operand (but not both) is a (possibly
+ // parenthesized) throw-expression; the result is of the [...] value
+ // category of the other.
+ bool TrueIsThrow = isa<CXXThrowExpr>(True->IgnoreParenImpCasts());
+ bool FalseIsThrow = isa<CXXThrowExpr>(False->IgnoreParenImpCasts());
+ if (const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ? nullptr : False)
+ : (FalseIsThrow ? True : nullptr))
+ return ClassifyInternal(Ctx, NonThrow);
+
+ // [Otherwise] the result [...] is a prvalue.
return Cl::CL_PRValue;
+ }
// Note that at this point, we have already performed all conversions
// according to [expr.cond]p3.
@@ -584,7 +593,8 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
// Assignment to a property in ObjC is an implicit setter access. But a
// setter might not exist.
if (const ObjCPropertyRefExpr *Expr = dyn_cast<ObjCPropertyRefExpr>(E)) {
- if (Expr->isImplicitProperty() && Expr->getImplicitPropertySetter() == 0)
+ if (Expr->isImplicitProperty() &&
+ Expr->getImplicitPropertySetter() == nullptr)
return Cl::CM_NoSetterProperty;
}
diff --git a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp
index 4cac4fa..7d7ca99 100644
--- a/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ExprConstant.cpp
@@ -320,7 +320,7 @@ namespace {
APValue *getTemporary(const void *Key) {
MapTy::iterator I = Temporaries.find(Key);
- return I == Temporaries.end() ? 0 : &I->second;
+ return I == Temporaries.end() ? nullptr : &I->second;
}
APValue &createTemporary(const void *Key, bool IsLifetimeExtended);
};
@@ -347,7 +347,8 @@ namespace {
PartialDiagnostic *Diag;
public:
- explicit OptionalDiagnostic(PartialDiagnostic *Diag = 0) : Diag(Diag) {}
+ explicit OptionalDiagnostic(PartialDiagnostic *Diag = nullptr)
+ : Diag(Diag) {}
template<typename T>
OptionalDiagnostic &operator<<(const T &v) {
@@ -474,13 +475,30 @@ namespace {
/// Evaluate in any way we know how. Don't worry about side-effects that
/// can't be modeled.
- EM_IgnoreSideEffects
+ EM_IgnoreSideEffects,
+
+ /// Evaluate as a constant expression. Stop if we find that the expression
+ /// is not a constant expression. Some expressions can be retried in the
+ /// optimizer if we don't constant fold them here, but in an unevaluated
+ /// context we try to fold them immediately since the optimizer never
+ /// gets a chance to look at it.
+ EM_ConstantExpressionUnevaluated,
+
+ /// Evaluate as a potential constant expression. Keep going if we hit a
+ /// construct that we can't evaluate yet (because we don't yet know the
+ /// value of something) but stop if we hit something that could never be
+ /// a constant expression. Some expressions can be retried in the
+ /// optimizer if we don't constant fold them here, but in an unevaluated
+ /// context we try to fold them immediately since the optimizer never
+ /// gets a chance to look at it.
+ EM_PotentialConstantExpressionUnevaluated
} EvalMode;
/// Are we checking whether the expression is a potential constant
/// expression?
bool checkingPotentialConstantExpression() const {
- return EvalMode == EM_PotentialConstantExpression;
+ return EvalMode == EM_PotentialConstantExpression ||
+ EvalMode == EM_PotentialConstantExpressionUnevaluated;
}
/// Are we checking an expression for overflow?
@@ -489,12 +507,13 @@ namespace {
bool checkingForOverflow() { return EvalMode == EM_EvaluateForOverflow; }
EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
- : Ctx(const_cast<ASTContext&>(C)), EvalStatus(S), CurrentCall(0),
+ : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
CallStackDepth(0), NextCallIndex(1),
StepsLeft(getLangOpts().ConstexprStepLimit),
- BottomFrame(*this, SourceLocation(), 0, 0, 0),
- EvaluatingDecl((const ValueDecl*)0), EvaluatingDeclValue(0),
- HasActiveDiagnostic(false), EvalMode(Mode) {}
+ BottomFrame(*this, SourceLocation(), nullptr, nullptr, nullptr),
+ EvaluatingDecl((const ValueDecl *)nullptr),
+ EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
+ EvalMode(Mode) {}
void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
EvaluatingDecl = Base;
@@ -527,7 +546,7 @@ namespace {
CallStackFrame *Frame = CurrentCall;
while (Frame->Index > CallIndex)
Frame = Frame->Caller;
- return (Frame->Index == CallIndex) ? Frame : 0;
+ return (Frame->Index == CallIndex) ? Frame : nullptr;
}
bool nextStep(const Stmt *S) {
@@ -573,6 +592,8 @@ namespace {
// some later problem.
case EM_ConstantExpression:
case EM_PotentialConstantExpression:
+ case EM_ConstantExpressionUnevaluated:
+ case EM_PotentialConstantExpressionUnevaluated:
HasActiveDiagnostic = false;
return OptionalDiagnostic();
}
@@ -644,11 +665,13 @@ namespace {
bool keepEvaluatingAfterSideEffect() {
switch (EvalMode) {
case EM_PotentialConstantExpression:
+ case EM_PotentialConstantExpressionUnevaluated:
case EM_EvaluateForOverflow:
case EM_IgnoreSideEffects:
return true;
case EM_ConstantExpression:
+ case EM_ConstantExpressionUnevaluated:
case EM_ConstantFold:
return false;
}
@@ -670,10 +693,12 @@ namespace {
switch (EvalMode) {
case EM_PotentialConstantExpression:
+ case EM_PotentialConstantExpressionUnevaluated:
case EM_EvaluateForOverflow:
return true;
case EM_ConstantExpression:
+ case EM_ConstantExpressionUnevaluated:
case EM_ConstantFold:
case EM_IgnoreSideEffects:
return false;
@@ -696,7 +721,9 @@ namespace {
Info.EvalStatus.Diag->empty() &&
!Info.EvalStatus.HasSideEffects),
OldMode(Info.EvalMode) {
- if (Enabled && Info.EvalMode == EvalInfo::EM_ConstantExpression)
+ if (Enabled &&
+ (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
+ Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
Info.EvalMode = EvalInfo::EM_ConstantFold;
}
void keepDiagnostics() { Enabled = false; }
@@ -716,7 +743,7 @@ namespace {
public:
SpeculativeEvaluationRAII(EvalInfo &Info,
- SmallVectorImpl<PartialDiagnosticAt> *NewDiag = 0)
+ SmallVectorImpl<PartialDiagnosticAt> *NewDiag = nullptr)
: Info(Info), Old(Info.EvalStatus) {
Info.EvalStatus.Diag = NewDiag;
// If we're speculatively evaluating, we may have skipped over some
@@ -943,7 +970,7 @@ namespace {
// any object: we won't use such a designator for anything.
if (!Info.getLangOpts().CPlusPlus11)
Designator.setInvalid();
- return checkNullPointer(Info, E, CSK) &&
+ return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
Designator.checkSubobject(Info, E, CSK);
}
@@ -961,7 +988,7 @@ namespace {
Designator.addComplexUnchecked(EltTy, Imag);
}
void adjustIndex(EvalInfo &Info, const Expr *E, uint64_t N) {
- if (checkNullPointer(Info, E, CSK_ArrayIndex))
+ if (N && checkNullPointer(Info, E, CSK_ArrayIndex))
Designator.adjustIndex(Info, E, N);
}
};
@@ -1141,7 +1168,7 @@ static int64_t getExtValue(const APSInt &Value) {
/// Should this call expression be treated as a string literal?
static bool IsStringLiteralCall(const CallExpr *E) {
- unsigned Builtin = E->isBuiltinCall();
+ unsigned Builtin = E->getBuiltinCallee();
return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
}
@@ -1242,11 +1269,29 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
LVal.getLValueCallIndex() == 0) &&
"have call index for global lvalue");
- // Check if this is a thread-local variable.
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
if (const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
+ // Check if this is a thread-local variable.
if (Var->getTLSKind())
return false;
+
+ // A dllimport variable never acts like a constant.
+ if (Var->hasAttr<DLLImportAttr>())
+ return false;
+ }
+ if (const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
+ // __declspec(dllimport) must be handled very carefully:
+ // We must never initialize an expression with the thunk in C++.
+ // Doing otherwise would allow the same id-expression to yield
+ // different addresses for the same function in different translation
+ // units. However, this means that we must dynamically initialize the
+ // expression with the contents of the import address table at runtime.
+ //
+ // The C language has no notion of ODR; furthermore, it has no notion of
+ // dynamic initialization. This means that we are permitted to
+ // perform initialization with the address of the thunk.
+ if (Info.getLangOpts().CPlusPlus && FD->hasAttr<DLLImportAttr>())
+ return false;
}
}
@@ -1276,7 +1321,7 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
/// Check that this core constant expression is of literal type, and if not,
/// produce an appropriate diagnostic.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E,
- const LValue *This = 0) {
+ const LValue *This = nullptr) {
if (!E->isRValue() || E->getType()->isLiteralType(Info.Ctx))
return true;
@@ -1307,6 +1352,11 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
return false;
}
+ // We allow _Atomic(T) to be initialized from anything that T can be
+ // initialized from.
+ if (const AtomicType *AT = Type->getAs<AtomicType>())
+ Type = AT->getValueType();
+
// Core issue 1454: For a literal constant expression of array or class type,
// each subobject of its value shall have been initialized by a constant
// expression.
@@ -1338,8 +1388,7 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
return false;
}
}
- for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
- I != E; ++I) {
+ for (const auto *I : RD->fields()) {
if (!CheckConstantExpression(Info, DiagLoc, I->getType(),
Value.getStructField(I->getFieldIndex())))
return false;
@@ -1738,7 +1787,7 @@ static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result,
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj,
const CXXRecordDecl *Derived,
const CXXRecordDecl *Base,
- const ASTRecordLayout *RL = 0) {
+ const ASTRecordLayout *RL = nullptr) {
if (!RL) {
if (Derived->isInvalidDecl()) return false;
RL = &Info.Ctx.getASTRecordLayout(Derived);
@@ -1791,7 +1840,7 @@ static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E,
/// currently described by LVal.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal,
const FieldDecl *FD,
- const ASTRecordLayout *RL = 0) {
+ const ASTRecordLayout *RL = nullptr) {
if (!RL) {
if (FD->getParent()->isInvalidDecl()) return false;
RL = &Info.Ctx.getASTRecordLayout(FD->getParent());
@@ -1807,9 +1856,8 @@ static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal,
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E,
LValue &LVal,
const IndirectFieldDecl *IFD) {
- for (IndirectFieldDecl::chain_iterator C = IFD->chain_begin(),
- CE = IFD->chain_end(); C != CE; ++C)
- if (!HandleLValueMember(Info, E, LVal, cast<FieldDecl>(*C)))
+ for (const auto *C : IFD->chain())
+ if (!HandleLValueMember(Info, E, LVal, cast<FieldDecl>(C)))
return false;
return true;
}
@@ -2047,7 +2095,7 @@ struct CompleteObject {
/// The type of the complete object.
QualType Type;
- CompleteObject() : Value(0) {}
+ CompleteObject() : Value(nullptr) {}
CompleteObject(APValue *Value, QualType Type)
: Value(Value), Type(Type) {
assert(Value && "missing value for complete object");
@@ -2075,7 +2123,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
APValue *O = Obj.Value;
QualType ObjType = Obj.Type;
- const FieldDecl *LastField = 0;
+ const FieldDecl *LastField = nullptr;
// Walk the designator's path to find the subobject.
for (unsigned I = 0, N = Sub.Entries.size(); /**/; ++I) {
@@ -2098,7 +2146,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
return true;
}
- LastField = 0;
+ LastField = nullptr;
if (ObjType->isArrayType()) {
// Next subobject is an array element.
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(ObjType);
@@ -2381,7 +2429,7 @@ CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK,
return CompleteObject();
}
- CallStackFrame *Frame = 0;
+ CallStackFrame *Frame = nullptr;
if (LVal.CallIndex) {
Frame = Info.getCallFrame(LVal.CallIndex);
if (!Frame) {
@@ -2406,7 +2454,7 @@ CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK,
}
// Compute value storage location and type of base object.
- APValue *BaseVal = 0;
+ APValue *BaseVal = nullptr;
QualType BaseType = getType(LVal.Base);
if (const ValueDecl *D = LVal.Base.dyn_cast<const ValueDecl*>()) {
@@ -2776,7 +2824,7 @@ struct IncDecSubobjectHandler {
// if we're post-incrementing a complex.
if (Old) {
*Old = Subobj;
- Old = 0;
+ Old = nullptr;
}
switch (Subobj.getKind()) {
@@ -2913,6 +2961,7 @@ static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object,
if (Object->getType()->isLiteralType(Info.Ctx))
return EvaluateTemporary(Object, This, Info);
+ Info.Diag(Object, diag::note_constexpr_nonliteral) << Object->getType();
return false;
}
@@ -2934,14 +2983,14 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info,
bool IncludeMember = true) {
MemberPtr MemPtr;
if (!EvaluateMemberPointer(RHS, MemPtr, Info))
- return 0;
+ return nullptr;
// C++11 [expr.mptr.oper]p6: If the second operand is the null pointer to
// member value, the behavior is undefined.
if (!MemPtr.getDecl()) {
// FIXME: Specific diagnostic.
Info.Diag(RHS);
- return 0;
+ return nullptr;
}
if (MemPtr.isDerivedMember()) {
@@ -2951,7 +3000,7 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info,
if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
LV.Designator.Entries.size()) {
Info.Diag(RHS);
- return 0;
+ return nullptr;
}
unsigned PathLengthToMember =
LV.Designator.Entries.size() - MemPtr.Path.size();
@@ -2961,14 +3010,14 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info,
const CXXRecordDecl *MPDecl = MemPtr.Path[I];
if (LVDecl->getCanonicalDecl() != MPDecl->getCanonicalDecl()) {
Info.Diag(RHS);
- return 0;
+ return nullptr;
}
}
// Truncate the lvalue to the appropriate derived class.
if (!CastToDerivedClass(Info, RHS, LV, MemPtr.getContainingRecord(),
PathLengthToMember))
- return 0;
+ return nullptr;
} else if (!MemPtr.Path.empty()) {
// Extend the LValue path with the member pointer's path.
LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
@@ -2983,24 +3032,24 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info,
for (unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
const CXXRecordDecl *Base = MemPtr.Path[N - I - 1];
if (!HandleLValueDirectBase(Info, RHS, LV, RD, Base))
- return 0;
+ return nullptr;
RD = Base;
}
// Finally cast to the class containing the member.
if (!HandleLValueDirectBase(Info, RHS, LV, RD,
MemPtr.getContainingRecord()))
- return 0;
+ return nullptr;
}
// Add the member. Note that we cannot build bound member functions here.
if (IncludeMember) {
if (const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
if (!HandleLValueMember(Info, RHS, LV, FD))
- return 0;
+ return nullptr;
} else if (const IndirectFieldDecl *IFD =
dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
if (!HandleLValueIndirectMember(Info, RHS, LV, IFD))
- return 0;
+ return nullptr;
} else {
llvm_unreachable("can't construct reference to bound member function");
}
@@ -3020,7 +3069,7 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info,
MemberPtr MemPtr;
EvaluateMemberPointer(BO->getRHS(), MemPtr, Info);
}
- return 0;
+ return nullptr;
}
return HandleMemberPointerAccess(Info, BO->getLHS()->getType(), LV,
@@ -3092,14 +3141,18 @@ static bool EvaluateDecl(EvalInfo &Info, const Decl *D) {
Result.set(VD, Info.CurrentCall->Index);
APValue &Val = Info.CurrentCall->createTemporary(VD, true);
- if (!VD->getInit()) {
+ const Expr *InitE = VD->getInit();
+ if (!InitE) {
Info.Diag(D->getLocStart(), diag::note_constexpr_uninitialized)
<< false << VD->getType();
Val = APValue();
return false;
}
- if (!EvaluateInPlace(Val, Info, Result, VD->getInit())) {
+ if (InitE->isValueDependent())
+ return false;
+
+ if (!EvaluateInPlace(Val, Info, Result, InitE)) {
// Wipe out any partially-computed value, to allow tracking that this
// evaluation failed.
Val = APValue();
@@ -3120,12 +3173,13 @@ static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl,
}
static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
- const Stmt *S, const SwitchCase *SC = 0);
+ const Stmt *S,
+ const SwitchCase *SC = nullptr);
/// Evaluate the body of a loop, and translate the result as appropriate.
static EvalStmtResult EvaluateLoopBody(APValue &Result, EvalInfo &Info,
const Stmt *Body,
- const SwitchCase *Case = 0) {
+ const SwitchCase *Case = nullptr) {
BlockScopeRAII Scope(Info);
switch (EvalStmtResult ESR = EvaluateStmt(Result, Info, Body, Case)) {
case ESR_Break:
@@ -3159,7 +3213,7 @@ static EvalStmtResult EvaluateSwitch(APValue &Result, EvalInfo &Info,
// Find the switch case corresponding to the value of the condition.
// FIXME: Cache this lookup.
- const SwitchCase *Found = 0;
+ const SwitchCase *Found = nullptr;
for (const SwitchCase *SC = SS->getSwitchCaseList(); SC;
SC = SC->getNextSwitchCase()) {
if (isa<DefaultStmt>(SC)) {
@@ -3224,7 +3278,7 @@ static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
case Stmt::CaseStmtClass:
case Stmt::DefaultStmtClass:
if (Case == S)
- Case = 0;
+ Case = nullptr;
break;
case Stmt::IfStmtClass: {
@@ -3291,13 +3345,12 @@ static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
case Stmt::DeclStmtClass: {
const DeclStmt *DS = cast<DeclStmt>(S);
- for (DeclStmt::const_decl_iterator DclIt = DS->decl_begin(),
- DclEnd = DS->decl_end(); DclIt != DclEnd; ++DclIt) {
+ for (const auto *DclIt : DS->decls()) {
// Each declaration initialization is its own full-expression.
// FIXME: This isn't quite right; if we're performing aggregate
// initialization, each braced subexpression is its own full-expression.
FullExpressionRAII Scope(Info);
- if (!EvaluateDecl(Info, *DclIt) && !Info.keepEvaluatingAfterFailure())
+ if (!EvaluateDecl(Info, DclIt) && !Info.keepEvaluatingAfterFailure())
return ESR_Failed;
}
return ESR_Succeeded;
@@ -3315,11 +3368,10 @@ static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
BlockScopeRAII Scope(Info);
const CompoundStmt *CS = cast<CompoundStmt>(S);
- for (CompoundStmt::const_body_iterator BI = CS->body_begin(),
- BE = CS->body_end(); BI != BE; ++BI) {
- EvalStmtResult ESR = EvaluateStmt(Result, Info, *BI, Case);
+ for (const auto *BI : CS->body()) {
+ EvalStmtResult ESR = EvaluateStmt(Result, Info, BI, Case);
if (ESR == ESR_Succeeded)
- Case = 0;
+ Case = nullptr;
else if (ESR != ESR_CaseNotFound)
return ESR;
}
@@ -3368,7 +3420,7 @@ static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
EvalStmtResult ESR = EvaluateLoopBody(Result, Info, DS->getBody(), Case);
if (ESR != ESR_Continue)
return ESR;
- Case = 0;
+ Case = nullptr;
FullExpressionRAII CondScope(Info);
if (!EvaluateAsBooleanCondition(DS->getCond(), Continue, Info))
@@ -3593,7 +3645,7 @@ static bool HandleFunctionCall(SourceLocation CallLoc,
EvalStmtResult ESR = EvaluateStmt(Result, Info, Body);
if (ESR == ESR_Succeeded) {
- if (Callee->getResultType()->isVoidType())
+ if (Callee->getReturnType()->isVoidType())
return true;
Info.Diag(Callee->getLocEnd(), diag::note_constexpr_no_return);
}
@@ -3659,15 +3711,14 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
#ifndef NDEBUG
CXXRecordDecl::base_class_const_iterator BaseIt = RD->bases_begin();
#endif
- for (CXXConstructorDecl::init_const_iterator I = Definition->init_begin(),
- E = Definition->init_end(); I != E; ++I) {
+ for (const auto *I : Definition->inits()) {
LValue Subobject = This;
APValue *Value = &Result;
// Determine the subobject to initialize.
- FieldDecl *FD = 0;
- if ((*I)->isBaseInitializer()) {
- QualType BaseType((*I)->getBaseClass(), 0);
+ FieldDecl *FD = nullptr;
+ if (I->isBaseInitializer()) {
+ QualType BaseType(I->getBaseClass(), 0);
#ifndef NDEBUG
// Non-virtual base classes are initialized in the order in the class
// definition. We have already checked for virtual base classes.
@@ -3676,12 +3727,12 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
"base class initializers not in expected order");
++BaseIt;
#endif
- if (!HandleLValueDirectBase(Info, (*I)->getInit(), Subobject, RD,
+ if (!HandleLValueDirectBase(Info, I->getInit(), Subobject, RD,
BaseType->getAsCXXRecordDecl(), &Layout))
return false;
Value = &Result.getStructBase(BasesSeen++);
- } else if ((FD = (*I)->getMember())) {
- if (!HandleLValueMember(Info, (*I)->getInit(), Subobject, FD, &Layout))
+ } else if ((FD = I->getMember())) {
+ if (!HandleLValueMember(Info, I->getInit(), Subobject, FD, &Layout))
return false;
if (RD->isUnion()) {
Result = APValue(FD);
@@ -3689,13 +3740,11 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
} else {
Value = &Result.getStructField(FD->getFieldIndex());
}
- } else if (IndirectFieldDecl *IFD = (*I)->getIndirectMember()) {
+ } else if (IndirectFieldDecl *IFD = I->getIndirectMember()) {
// Walk the indirect field decl's chain to find the object to initialize,
// and make sure we've initialized every step along it.
- for (IndirectFieldDecl::chain_iterator C = IFD->chain_begin(),
- CE = IFD->chain_end();
- C != CE; ++C) {
- FD = cast<FieldDecl>(*C);
+ for (auto *C : IFD->chain()) {
+ FD = cast<FieldDecl>(C);
CXXRecordDecl *CD = cast<CXXRecordDecl>(FD->getParent());
// Switch the union field if it differs. This happens if we had
// preceding zero-initialization, and we're now initializing a union
@@ -3710,7 +3759,7 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
*Value = APValue(APValue::UninitStruct(), CD->getNumBases(),
std::distance(CD->field_begin(), CD->field_end()));
}
- if (!HandleLValueMember(Info, (*I)->getInit(), Subobject, FD))
+ if (!HandleLValueMember(Info, I->getInit(), Subobject, FD))
return false;
if (CD->isUnion())
Value = &Value->getUnionValue();
@@ -3722,8 +3771,8 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
}
FullExpressionRAII InitScope(Info);
- if (!EvaluateInPlace(*Value, Info, Subobject, (*I)->getInit()) ||
- (FD && FD->isBitField() && !truncateBitfieldValue(Info, (*I)->getInit(),
+ if (!EvaluateInPlace(*Value, Info, Subobject, I->getInit()) ||
+ (FD && FD->isBitField() && !truncateBitfieldValue(Info, I->getInit(),
*Value, FD))) {
// If we're checking for a potential constant expression, evaluate all
// initializers even if some of them fail.
@@ -3742,15 +3791,14 @@ static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This,
//===----------------------------------------------------------------------===//
namespace {
-// FIXME: RetTy is always bool. Remove it.
-template <class Derived, typename RetTy=bool>
+template <class Derived>
class ExprEvaluatorBase
- : public ConstStmtVisitor<Derived, RetTy> {
+ : public ConstStmtVisitor<Derived, bool> {
private:
- RetTy DerivedSuccess(const APValue &V, const Expr *E) {
+ bool DerivedSuccess(const APValue &V, const Expr *E) {
return static_cast<Derived*>(this)->Success(V, E);
}
- RetTy DerivedZeroInitialization(const Expr *E) {
+ bool DerivedZeroInitialization(const Expr *E) {
return static_cast<Derived*>(this)->ZeroInitialization(E);
}
@@ -3795,14 +3843,14 @@ private:
protected:
EvalInfo &Info;
- typedef ConstStmtVisitor<Derived, RetTy> StmtVisitorTy;
+ typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
OptionalDiagnostic CCEDiag(const Expr *E, diag::kind D) {
return Info.CCEDiag(E, D);
}
- RetTy ZeroInitialization(const Expr *E) { return Error(E); }
+ bool ZeroInitialization(const Expr *E) { return Error(E); }
public:
ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
@@ -3819,28 +3867,28 @@ public:
return Error(E, diag::note_invalid_subexpr_in_const_expr);
}
- RetTy VisitStmt(const Stmt *) {
+ bool VisitStmt(const Stmt *) {
llvm_unreachable("Expression evaluator should not be called on stmts");
}
- RetTy VisitExpr(const Expr *E) {
+ bool VisitExpr(const Expr *E) {
return Error(E);
}
- RetTy VisitParenExpr(const ParenExpr *E)
+ bool VisitParenExpr(const ParenExpr *E)
{ return StmtVisitorTy::Visit(E->getSubExpr()); }
- RetTy VisitUnaryExtension(const UnaryOperator *E)
+ bool VisitUnaryExtension(const UnaryOperator *E)
{ return StmtVisitorTy::Visit(E->getSubExpr()); }
- RetTy VisitUnaryPlus(const UnaryOperator *E)
+ bool VisitUnaryPlus(const UnaryOperator *E)
{ return StmtVisitorTy::Visit(E->getSubExpr()); }
- RetTy VisitChooseExpr(const ChooseExpr *E)
+ bool VisitChooseExpr(const ChooseExpr *E)
{ return StmtVisitorTy::Visit(E->getChosenSubExpr()); }
- RetTy VisitGenericSelectionExpr(const GenericSelectionExpr *E)
+ bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
{ return StmtVisitorTy::Visit(E->getResultExpr()); }
- RetTy VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
+ bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
{ return StmtVisitorTy::Visit(E->getReplacement()); }
- RetTy VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
+ bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
{ return StmtVisitorTy::Visit(E->getExpr()); }
- RetTy VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
+ bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
// The initializer may not have been parsed yet, or might be erroneous.
if (!E->getExpr())
return Error(E);
@@ -3848,19 +3896,19 @@ public:
}
// We cannot create any objects for which cleanups are required, so there is
// nothing to do here; all cleanups must come from unevaluated subexpressions.
- RetTy VisitExprWithCleanups(const ExprWithCleanups *E)
+ bool VisitExprWithCleanups(const ExprWithCleanups *E)
{ return StmtVisitorTy::Visit(E->getSubExpr()); }
- RetTy VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E) {
+ bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E) {
CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
return static_cast<Derived*>(this)->VisitCastExpr(E);
}
- RetTy VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
+ bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
return static_cast<Derived*>(this)->VisitCastExpr(E);
}
- RetTy VisitBinaryOperator(const BinaryOperator *E) {
+ bool VisitBinaryOperator(const BinaryOperator *E) {
switch (E->getOpcode()) {
default:
return Error(E);
@@ -3882,7 +3930,7 @@ public:
}
}
- RetTy VisitBinaryConditionalOperator(const BinaryConditionalOperator *E) {
+ bool VisitBinaryConditionalOperator(const BinaryConditionalOperator *E) {
// Evaluate and cache the common expression. We treat it as a temporary,
// even though it's not quite the same thing.
if (!Evaluate(Info.CurrentCall->createTemporary(E->getOpaqueValue(), false),
@@ -3892,7 +3940,7 @@ public:
return HandleConditionalOperator(E);
}
- RetTy VisitConditionalOperator(const ConditionalOperator *E) {
+ bool VisitConditionalOperator(const ConditionalOperator *E) {
bool IsBcpCall = false;
// If the condition (ignoring parens) is a __builtin_constant_p call,
// the result is a constant expression if it can be folded without
@@ -3900,7 +3948,7 @@ public:
// for discussion.
if (const CallExpr *CallCE =
dyn_cast<CallExpr>(E->getCond()->IgnoreParenCasts()))
- if (CallCE->isBuiltinCall() == Builtin::BI__builtin_constant_p)
+ if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
IsBcpCall = true;
// Always assume __builtin_constant_p(...) ? ... : ... is a potential
@@ -3917,7 +3965,7 @@ public:
return true;
}
- RetTy VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
+ bool VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
if (APValue *Value = Info.CurrentCall->getTemporary(E))
return DerivedSuccess(*Value, E);
@@ -3931,18 +3979,18 @@ public:
return StmtVisitorTy::Visit(Source);
}
- RetTy VisitCallExpr(const CallExpr *E) {
+ bool VisitCallExpr(const CallExpr *E) {
const Expr *Callee = E->getCallee()->IgnoreParens();
QualType CalleeType = Callee->getType();
- const FunctionDecl *FD = 0;
- LValue *This = 0, ThisVal;
+ const FunctionDecl *FD = nullptr;
+ LValue *This = nullptr, ThisVal;
ArrayRef<const Expr *> Args(E->getArgs(), E->getNumArgs());
bool HasQualifier = false;
// Extract function decl and 'this' pointer from the callee.
if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
- const ValueDecl *Member = 0;
+ const ValueDecl *Member = nullptr;
if (const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
// Explicit bound member calls, such as x.f() or p->g();
if (!EvaluateObjectArgument(Info, ME->getBase(), ThisVal))
@@ -4004,7 +4052,7 @@ public:
isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
return Error(E, diag::note_constexpr_virtual_call);
- const FunctionDecl *Definition = 0;
+ const FunctionDecl *Definition = nullptr;
Stmt *Body = FD->getBody(Definition);
APValue Result;
@@ -4016,28 +4064,28 @@ public:
return DerivedSuccess(Result, E);
}
- RetTy VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
+ bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
return StmtVisitorTy::Visit(E->getInitializer());
}
- RetTy VisitInitListExpr(const InitListExpr *E) {
+ bool VisitInitListExpr(const InitListExpr *E) {
if (E->getNumInits() == 0)
return DerivedZeroInitialization(E);
if (E->getNumInits() == 1)
return StmtVisitorTy::Visit(E->getInit(0));
return Error(E);
}
- RetTy VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
+ bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
return DerivedZeroInitialization(E);
}
- RetTy VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
+ bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
return DerivedZeroInitialization(E);
}
- RetTy VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
+ bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
return DerivedZeroInitialization(E);
}
/// A member expression where the object is a prvalue is itself a prvalue.
- RetTy VisitMemberExpr(const MemberExpr *E) {
+ bool VisitMemberExpr(const MemberExpr *E) {
assert(!E->isArrow() && "missing call to bound member function?");
APValue Val;
@@ -4061,7 +4109,7 @@ public:
DerivedSuccess(Result, E);
}
- RetTy VisitCastExpr(const CastExpr *E) {
+ bool VisitCastExpr(const CastExpr *E) {
switch (E->getCastKind()) {
default:
break;
@@ -4093,13 +4141,13 @@ public:
return Error(E);
}
- RetTy VisitUnaryPostInc(const UnaryOperator *UO) {
+ bool VisitUnaryPostInc(const UnaryOperator *UO) {
return VisitUnaryPostIncDec(UO);
}
- RetTy VisitUnaryPostDec(const UnaryOperator *UO) {
+ bool VisitUnaryPostDec(const UnaryOperator *UO) {
return VisitUnaryPostIncDec(UO);
}
- RetTy VisitUnaryPostIncDec(const UnaryOperator *UO) {
+ bool VisitUnaryPostIncDec(const UnaryOperator *UO) {
if (!Info.getLangOpts().CPlusPlus1y && !Info.keepEvaluatingAfterFailure())
return Error(UO);
@@ -4113,7 +4161,7 @@ public:
return DerivedSuccess(RVal, UO);
}
- RetTy VisitStmtExpr(const StmtExpr *E) {
+ bool VisitStmtExpr(const StmtExpr *E) {
// We will have checked the full-expressions inside the statement expression
// when they were completed, and don't need to check them again now.
if (Info.checkingForOverflow())
@@ -4162,11 +4210,11 @@ public:
namespace {
template<class Derived>
class LValueExprEvaluatorBase
- : public ExprEvaluatorBase<Derived, bool> {
+ : public ExprEvaluatorBase<Derived> {
protected:
LValue &Result;
typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
- typedef ExprEvaluatorBase<Derived, bool> ExprEvaluatorBaseTy;
+ typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
bool Success(APValue::LValueBase B) {
Result.set(B);
@@ -4356,7 +4404,7 @@ bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
}
bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
- CallStackFrame *Frame = 0;
+ CallStackFrame *Frame = nullptr;
if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1)
Frame = Info.CurrentCall;
@@ -4533,7 +4581,7 @@ bool LValueExprEvaluator::VisitUnaryPreIncDec(const UnaryOperator *UO) {
return handleIncDec(
this->Info, UO, Result, UO->getSubExpr()->getType(),
- UO->isIncrementOp(), 0);
+ UO->isIncrementOp(), nullptr);
}
bool LValueExprEvaluator::VisitCompoundAssignOperator(
@@ -4584,7 +4632,7 @@ bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) {
namespace {
class PointerExprEvaluator
- : public ExprEvaluatorBase<PointerExprEvaluator, bool> {
+ : public ExprEvaluatorBase<PointerExprEvaluator> {
LValue &Result;
bool Success(const Expr *E) {
@@ -4601,7 +4649,7 @@ public:
return true;
}
bool ZeroInitialization(const Expr *E) {
- return Success((Expr*)0);
+ return Success((Expr*)nullptr);
}
bool VisitBinaryOperator(const BinaryOperator *E);
@@ -4623,8 +4671,13 @@ public:
// Can't look at 'this' when checking a potential constant expression.
if (Info.checkingPotentialConstantExpression())
return false;
- if (!Info.CurrentCall->This)
- return Error(E);
+ if (!Info.CurrentCall->This) {
+ if (Info.getLangOpts().CPlusPlus11)
+ Info.Diag(E, diag::note_constexpr_this) << E->isImplicit();
+ else
+ Info.Diag(E);
+ return false;
+ }
Result = *Info.CurrentCall->This;
return true;
}
@@ -4729,7 +4782,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
if (Value.isInt()) {
unsigned Size = Info.Ctx.getTypeSize(E->getType());
uint64_t N = Value.getInt().extOrTrunc(Size).getZExtValue();
- Result.Base = (Expr*)0;
+ Result.Base = (Expr*)nullptr;
Result.Offset = CharUnits::fromQuantity(N);
Result.CallIndex = 0;
Result.Designator.setInvalid();
@@ -4769,7 +4822,7 @@ bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) {
if (IsStringLiteralCall(E))
return Success(E);
- switch (E->isBuiltinCall()) {
+ switch (E->getBuiltinCallee()) {
case Builtin::BI__builtin_addressof:
return EvaluateLValue(E->getArg(0), Result, Info);
@@ -4784,7 +4837,7 @@ bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) {
namespace {
class MemberPointerExprEvaluator
- : public ExprEvaluatorBase<MemberPointerExprEvaluator, bool> {
+ : public ExprEvaluatorBase<MemberPointerExprEvaluator> {
MemberPtr &Result;
bool Success(const ValueDecl *D) {
@@ -4801,7 +4854,7 @@ public:
return true;
}
bool ZeroInitialization(const Expr *E) {
- return Success((const ValueDecl*)0);
+ return Success((const ValueDecl*)nullptr);
}
bool VisitCastExpr(const CastExpr *E);
@@ -4872,7 +4925,7 @@ bool MemberPointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
namespace {
class RecordExprEvaluator
- : public ExprEvaluatorBase<RecordExprEvaluator, bool> {
+ : public ExprEvaluatorBase<RecordExprEvaluator> {
const LValue &This;
APValue &Result;
public:
@@ -4925,14 +4978,13 @@ static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E,
}
}
- for (RecordDecl::field_iterator I = RD->field_begin(), End = RD->field_end();
- I != End; ++I) {
+ for (const auto *I : RD->fields()) {
// -- if T is a reference type, no initialization is performed.
if (I->getType()->isReferenceType())
continue;
LValue Subobject = This;
- if (!HandleLValueMember(Info, E, Subobject, *I, &Layout))
+ if (!HandleLValueMember(Info, E, Subobject, I, &Layout))
return false;
ImplicitValueInitExpr VIE(I->getType());
@@ -4952,7 +5004,7 @@ bool RecordExprEvaluator::ZeroInitialization(const Expr *E) {
// object's first non-static named data member is zero-initialized
RecordDecl::field_iterator I = RD->field_begin();
if (I == RD->field_end()) {
- Result = APValue((const FieldDecl*)0);
+ Result = APValue((const FieldDecl*)nullptr);
return true;
}
@@ -5040,8 +5092,7 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
std::distance(RD->field_begin(), RD->field_end()));
unsigned ElementNo = 0;
bool Success = true;
- for (RecordDecl::field_iterator Field = RD->field_begin(),
- FieldEnd = RD->field_end(); Field != FieldEnd; ++Field) {
+ for (const auto *Field : RD->fields()) {
// Anonymous bit-fields are not considered members of the class for
// purposes of aggregate initialization.
if (Field->isUnnamedBitfield())
@@ -5054,7 +5105,7 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
// FIXME: Diagnostics here should point to the end of the initializer
// list, not the start.
if (!HandleLValueMember(Info, HaveInit ? E->getInit(ElementNo) : E,
- Subobject, *Field, &Layout))
+ Subobject, Field, &Layout))
return false;
// Perform an implicit value-initialization for members beyond the end of
@@ -5069,7 +5120,7 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
if (!EvaluateInPlace(FieldVal, Info, Subobject, Init) ||
(Field->isBitField() && !truncateBitfieldValue(Info, Init,
- FieldVal, *Field))) {
+ FieldVal, Field))) {
if (!Info.keepEvaluatingAfterFailure())
return false;
Success = false;
@@ -5100,7 +5151,7 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
return ZeroInitialization(E);
}
- const FunctionDecl *Definition = 0;
+ const FunctionDecl *Definition = nullptr;
FD->getBody(Definition);
if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition))
@@ -5234,7 +5285,7 @@ static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info) {
namespace {
class VectorExprEvaluator
- : public ExprEvaluatorBase<VectorExprEvaluator, bool> {
+ : public ExprEvaluatorBase<VectorExprEvaluator> {
APValue &Result;
public:
@@ -5415,7 +5466,7 @@ bool VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
namespace {
class ArrayExprEvaluator
- : public ExprEvaluatorBase<ArrayExprEvaluator, bool> {
+ : public ExprEvaluatorBase<ArrayExprEvaluator> {
const LValue &This;
APValue &Result;
public:
@@ -5487,7 +5538,7 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
unsigned NumEltsToInit = E->getNumInits();
unsigned NumElts = CAT->getSize().getZExtValue();
- const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : 0;
+ const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : nullptr;
// If the initializer might depend on the array index, run it for each
// array element. For now, just whitelist non-class value-initialization.
@@ -5582,7 +5633,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
return EvaluateInPlace(*Value, Info, Subobject, &VIE);
}
- const FunctionDecl *Definition = 0;
+ const FunctionDecl *Definition = nullptr;
FD->getBody(Definition);
if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition))
@@ -5610,7 +5661,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
namespace {
class IntExprEvaluator
- : public ExprEvaluatorBase<IntExprEvaluator, bool> {
+ : public ExprEvaluatorBase<IntExprEvaluator> {
APValue &Result;
public:
IntExprEvaluator(EvalInfo &info, APValue &result)
@@ -5716,14 +5767,6 @@ public:
return ZeroInitialization(E);
}
- bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
- return Success(E->getValue(), E);
- }
-
- bool VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
- return Success(E->getValue(), E);
- }
-
bool VisitTypeTraitExpr(const TypeTraitExpr *E) {
return Success(E->getValue(), E);
}
@@ -5964,7 +6007,7 @@ bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(const CallExpr *E) {
}
bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
- switch (unsigned BuiltinOp = E->isBuiltinCall()) {
+ switch (unsigned BuiltinOp = E->getBuiltinCallee()) {
default:
return ExprEvaluatorBaseTy::VisitCallExpr(E);
@@ -5983,7 +6026,17 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
// Expression had no side effects, but we couldn't statically determine the
// size of the referenced object.
- return Error(E);
+ switch (Info.EvalMode) {
+ case EvalInfo::EM_ConstantExpression:
+ case EvalInfo::EM_PotentialConstantExpression:
+ case EvalInfo::EM_ConstantFold:
+ case EvalInfo::EM_EvaluateForOverflow:
+ case EvalInfo::EM_IgnoreSideEffects:
+ return Error(E);
+ case EvalInfo::EM_ConstantExpressionUnevaluated:
+ case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
+ return Success(-1ULL, E);
+ }
}
case Builtin::BI__builtin_bswap16:
@@ -6005,7 +6058,8 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
case Builtin::BI__builtin_clz:
case Builtin::BI__builtin_clzl:
- case Builtin::BI__builtin_clzll: {
+ case Builtin::BI__builtin_clzll:
+ case Builtin::BI__builtin_clzs: {
APSInt Val;
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;
@@ -6020,7 +6074,8 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
case Builtin::BI__builtin_ctz:
case Builtin::BI__builtin_ctzl:
- case Builtin::BI__builtin_ctzll: {
+ case Builtin::BI__builtin_ctzll:
+ case Builtin::BI__builtin_ctzs: {
APSInt Val;
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;
@@ -6256,11 +6311,11 @@ class DataRecursiveIntBinOpEvaluator {
const Expr *E;
EvalResult LHSResult; // meaningful only for binary operator expression.
enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind } Kind;
-
- Job() : StoredInfo(0) { }
+
+ Job() : StoredInfo(nullptr) {}
void startSpeculativeEval(EvalInfo &Info) {
OldEvalStatus = Info.EvalStatus;
- Info.EvalStatus.Diag = 0;
+ Info.EvalStatus.Diag = nullptr;
StoredInfo = &Info;
}
~Job() {
@@ -6886,8 +6941,9 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
}
CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
- // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
- // result shall be the alignment of the referenced type."
+ // C++ [expr.alignof]p3:
+ // When alignof is applied to a reference type, the result is the
+ // alignment of the referenced type.
if (const ReferenceType *Ref = T->getAs<ReferenceType>())
T = Ref->getPointeeType();
@@ -6906,7 +6962,7 @@ CharUnits IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
// alignof decl is always accepted, even if it doesn't make sense: we default
// to 1 in those cases.
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
- return Info.Ctx.getDeclAlign(DRE->getDecl(),
+ return Info.Ctx.getDeclAlign(DRE->getDecl(),
/*RefAsPointee*/true);
if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
@@ -7109,6 +7165,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_BuiltinFnToFnPtr:
case CK_ZeroToOCLEvent:
case CK_NonAtomicToAtomic:
+ case CK_AddressSpaceConversion:
llvm_unreachable("invalid cast kind for integral value");
case CK_BitCast:
@@ -7247,7 +7304,7 @@ bool IntExprEvaluator::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
namespace {
class FloatExprEvaluator
- : public ExprEvaluatorBase<FloatExprEvaluator, bool> {
+ : public ExprEvaluatorBase<FloatExprEvaluator> {
APFloat &Result;
public:
FloatExprEvaluator(EvalInfo &info, APFloat &result)
@@ -7308,7 +7365,7 @@ static bool TryEvaluateBuiltinNaN(const ASTContext &Context,
}
bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
- switch (E->isBuiltinCall()) {
+ switch (E->getBuiltinCallee()) {
default:
return ExprEvaluatorBaseTy::VisitCallExpr(E);
@@ -7463,7 +7520,7 @@ bool FloatExprEvaluator::VisitCastExpr(const CastExpr *E) {
namespace {
class ComplexExprEvaluator
- : public ExprEvaluatorBase<ComplexExprEvaluator, bool> {
+ : public ExprEvaluatorBase<ComplexExprEvaluator> {
ComplexValue &Result;
public:
@@ -7581,6 +7638,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_BuiltinFnToFnPtr:
case CK_ZeroToOCLEvent:
case CK_NonAtomicToAtomic:
+ case CK_AddressSpaceConversion:
llvm_unreachable("invalid cast kind for complex value");
case CK_LValueToRValue:
@@ -7847,7 +7905,7 @@ bool ComplexExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
namespace {
class AtomicExprEvaluator :
- public ExprEvaluatorBase<AtomicExprEvaluator, bool> {
+ public ExprEvaluatorBase<AtomicExprEvaluator> {
APValue &Result;
public:
AtomicExprEvaluator(EvalInfo &Info, APValue &Result)
@@ -7887,7 +7945,7 @@ static bool EvaluateAtomic(const Expr *E, APValue &Result, EvalInfo &Info) {
namespace {
class VoidExprEvaluator
- : public ExprEvaluatorBase<VoidExprEvaluator, bool> {
+ : public ExprEvaluatorBase<VoidExprEvaluator> {
public:
VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
@@ -7902,6 +7960,16 @@ public:
return true;
}
}
+
+ bool VisitCallExpr(const CallExpr *E) {
+ switch (E->getBuiltinCallee()) {
+ default:
+ return ExprEvaluatorBaseTy::VisitCallExpr(E);
+ case Builtin::BI__assume:
+ // The argument is not evaluated!
+ return true;
+ }
+ }
};
} // end anonymous namespace
@@ -7989,6 +8057,8 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) {
/// an object can indirectly refer to subobjects which were initialized earlier.
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
const Expr *E, bool AllowNonLiteralTypes) {
+ assert(!E->isValueDependent());
+
if (!AllowNonLiteralTypes && !CheckLiteralType(Info, E, &This))
return false;
@@ -8008,6 +8078,9 @@ static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
/// EvaluateAsRValue - Try to evaluate this expression, performing an implicit
/// lvalue-to-rvalue cast if it is an lvalue.
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
+ if (E->getType().isNull())
+ return false;
+
if (!CheckLiteralType(Info, E))
return false;
@@ -8035,6 +8108,13 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
IsConst = true;
return true;
}
+
+ // This case should be rare, but we need to check it before we check on
+ // the type below.
+ if (Exp->getType().isNull()) {
+ IsConst = false;
+ return true;
+ }
// FIXME: Evaluating values of large array and record types can cause
// performance problems. Only do so in C++11 for now.
@@ -8292,10 +8372,20 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::MaterializeTemporaryExprClass:
case Expr::PseudoObjectExprClass:
case Expr::AtomicExprClass:
- case Expr::InitListExprClass:
case Expr::LambdaExprClass:
return ICEDiag(IK_NotICE, E->getLocStart());
+ case Expr::InitListExprClass: {
+ // C++03 [dcl.init]p13: If T is a scalar type, then a declaration of the
+ // form "T x = { a };" is equivalent to "T x = a;".
+ // Unless we're initializing a reference, T is a scalar as it is known to be
+ // of integral or enumeration type.
+ if (E->isRValue())
+ if (cast<InitListExpr>(E)->getNumInits() == 1)
+ return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
+ return ICEDiag(IK_NotICE, E->getLocStart());
+ }
+
case Expr::SizeOfPackExprClass:
case Expr::GNUNullExprClass:
// GCC considers the GNU __null value to be an integral constant expression.
@@ -8314,8 +8404,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::ObjCBoolLiteralExprClass:
case Expr::CXXBoolLiteralExprClass:
case Expr::CXXScalarValueInitExprClass:
- case Expr::UnaryTypeTraitExprClass:
- case Expr::BinaryTypeTraitExprClass:
case Expr::TypeTraitExprClass:
case Expr::ArrayTypeTraitExprClass:
case Expr::ExpressionTraitExprClass:
@@ -8327,7 +8415,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
// constant expressions, but they can never be ICEs because an ICE cannot
// contain an operand of (pointer to) function type.
const CallExpr *CE = cast<CallExpr>(E);
- if (CE->isBuiltinCall())
+ if (CE->getBuiltinCallee())
return CheckEvalInICE(E, Ctx);
return ICEDiag(IK_NotICE, E->getLocStart());
}
@@ -8544,7 +8632,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
// extension. See GCC PR38377 for discussion.
if (const CallExpr *CallCE
= dyn_cast<CallExpr>(Exp->getCond()->IgnoreParenCasts()))
- if (CallCE->isBuiltinCall() == Builtin::BI__builtin_constant_p)
+ if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
return CheckEvalInICE(E, Ctx);
ICEDiag CondResult = CheckICE(Exp->getCond(), Ctx);
if (CondResult.Kind == IK_NotICE)
@@ -8602,7 +8690,7 @@ static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx,
bool Expr::isIntegerConstantExpr(const ASTContext &Ctx,
SourceLocation *Loc) const {
if (Ctx.getLangOpts().CPlusPlus11)
- return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, 0, Loc);
+ return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, nullptr, Loc);
ICEDiag D = CheckICE(this, Ctx);
if (D.Kind != IK_ICE) {
@@ -8654,6 +8742,28 @@ bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result,
return IsConstExpr;
}
+bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
+ const FunctionDecl *Callee,
+ ArrayRef<const Expr*> Args) const {
+ Expr::EvalStatus Status;
+ EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
+
+ ArgVector ArgValues(Args.size());
+ for (ArrayRef<const Expr*>::iterator I = Args.begin(), E = Args.end();
+ I != E; ++I) {
+ if (!Evaluate(ArgValues[I - Args.begin()], Info, *I))
+ // If evaluation fails, throw away the argument entirely.
+ ArgValues[I - Args.begin()] = APValue();
+ if (Info.EvalStatus.HasSideEffects)
+ return false;
+ }
+
+ // Build fake call to Callee.
+ CallStackFrame Frame(Info, Callee->getLocation(), Callee, /*This*/nullptr,
+ ArgValues.data());
+ return Evaluate(Value, Info, this) && !Info.EvalStatus.HasSideEffects;
+}
+
bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
SmallVectorImpl<
PartialDiagnosticAt> &Diags) {
@@ -8670,7 +8780,7 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
EvalInfo::EM_PotentialConstantExpression);
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
- const CXXRecordDecl *RD = MD ? MD->getParent()->getCanonicalDecl() : 0;
+ const CXXRecordDecl *RD = MD ? MD->getParent()->getCanonicalDecl() : nullptr;
// Fabricate an arbitrary expression on the stack and pretend that it
// is a temporary being used as the 'this' pointer.
@@ -8689,8 +8799,32 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
HandleConstructorCall(Loc, This, Args, CD, Info, Scratch);
} else
- HandleFunctionCall(Loc, FD, (MD && MD->isInstance()) ? &This : 0,
+ HandleFunctionCall(Loc, FD, (MD && MD->isInstance()) ? &This : nullptr,
Args, FD->getBody(), Info, Scratch);
return Diags.empty();
}
+
+bool Expr::isPotentialConstantExprUnevaluated(Expr *E,
+ const FunctionDecl *FD,
+ SmallVectorImpl<
+ PartialDiagnosticAt> &Diags) {
+ Expr::EvalStatus Status;
+ Status.Diag = &Diags;
+
+ EvalInfo Info(FD->getASTContext(), Status,
+ EvalInfo::EM_PotentialConstantExpressionUnevaluated);
+
+ // Fabricate a call stack frame to give the arguments a plausible cover story.
+ ArrayRef<const Expr*> Args;
+ ArgVector ArgValues(0);
+ bool Success = EvaluateArgs(Args, ArgValues, Info);
+ (void)Success;
+ assert(Success &&
+ "Failed to set up arguments for potential constant evaluation");
+ CallStackFrame Frame(Info, SourceLocation(), FD, nullptr, ArgValues.data());
+
+ APValue ResultScratch;
+ Evaluate(ResultScratch, Info, E);
+ return Diags.empty();
+}
diff --git a/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp b/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp
index 96ebe92..8894107 100644
--- a/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ExternalASTSource.cpp
@@ -14,16 +14,44 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclarationName.h"
+#include "llvm/Support/ErrorHandling.h"
using namespace clang;
ExternalASTSource::~ExternalASTSource() { }
+void ExternalASTSource::FindFileRegionDecls(FileID File, unsigned Offset,
+ unsigned Length,
+ SmallVectorImpl<Decl *> &Decls) {}
+
+void ExternalASTSource::CompleteRedeclChain(const Decl *D) {}
+
+void ExternalASTSource::CompleteType(TagDecl *Tag) {}
+
+void ExternalASTSource::CompleteType(ObjCInterfaceDecl *Class) {}
+
+void ExternalASTSource::ReadComments() {}
+
+void ExternalASTSource::StartedDeserializing() {}
+
+void ExternalASTSource::FinishedDeserializing() {}
+
+void ExternalASTSource::StartTranslationUnit(ASTConsumer *Consumer) {}
+
void ExternalASTSource::PrintStats() { }
+bool ExternalASTSource::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) {
+ return false;
+}
+
Decl *ExternalASTSource::GetExternalDecl(uint32_t ID) {
- return 0;
+ return nullptr;
}
Selector ExternalASTSource::GetExternalSelector(uint32_t ID) {
@@ -35,12 +63,12 @@ uint32_t ExternalASTSource::GetNumExternalSelectors() {
}
Stmt *ExternalASTSource::GetExternalDeclStmt(uint64_t Offset) {
- return 0;
+ return nullptr;
}
CXXBaseSpecifier *
ExternalASTSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
- return 0;
+ return nullptr;
}
bool
@@ -60,3 +88,21 @@ ExternalASTSource::FindExternalLexicalDecls(const DeclContext *DC,
}
void ExternalASTSource::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { }
+
+uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) {
+ uint32_t OldGeneration = CurrentGeneration;
+
+ // Make sure the generation of the topmost external source for the context is
+ // incremented. That might not be us.
+ auto *P = C.getExternalSource();
+ if (P && P != this)
+ CurrentGeneration = P->incrementGeneration(C);
+ else {
+ // FIXME: Only bump the generation counter if the current generation number
+ // has been observed?
+ if (!++CurrentGeneration)
+ llvm::report_fatal_error("generation counter overflowed", false);
+ }
+
+ return OldGeneration;
+}
diff --git a/contrib/llvm/tools/clang/lib/AST/InheritViz.cpp b/contrib/llvm/tools/clang/lib/AST/InheritViz.cpp
index 3d64310..eb3020c 100644
--- a/contrib/llvm/tools/clang/lib/AST/InheritViz.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/InheritViz.cpp
@@ -93,26 +93,25 @@ void InheritanceHierarchyWriter::WriteNode(QualType Type, bool FromVirtual) {
// Display the base classes.
const CXXRecordDecl *Decl
= static_cast<const CXXRecordDecl *>(Type->getAs<RecordType>()->getDecl());
- for (CXXRecordDecl::base_class_const_iterator Base = Decl->bases_begin();
- Base != Decl->bases_end(); ++Base) {
- QualType CanonBaseType = Context.getCanonicalType(Base->getType());
+ for (const auto &Base : Decl->bases()) {
+ QualType CanonBaseType = Context.getCanonicalType(Base.getType());
// If this is not virtual inheritance, bump the direct base
// count for the type.
- if (!Base->isVirtual())
+ if (!Base.isVirtual())
++DirectBaseCount[CanonBaseType];
// Write out the node (if we need to).
- WriteNode(Base->getType(), Base->isVirtual());
+ WriteNode(Base.getType(), Base.isVirtual());
// Write out the edge.
Out << " ";
WriteNodeReference(Type, FromVirtual);
Out << " -> ";
- WriteNodeReference(Base->getType(), Base->isVirtual());
+ WriteNodeReference(Base.getType(), Base.isVirtual());
// Write out edge attributes to show the kind of inheritance.
- if (Base->isVirtual()) {
+ if (Base.isVirtual()) {
Out << " [ style=\"dashed\" ]";
}
Out << ";";
@@ -140,7 +139,7 @@ void CXXRecordDecl::viewInheritance(ASTContext& Context) const {
int FD;
SmallString<128> Filename;
- error_code EC =
+ std::error_code EC =
sys::fs::createTemporaryFile(Self.getAsString(), "dot", FD, Filename);
if (EC) {
llvm::errs() << "Error: " << EC.message() << "\n";
diff --git a/contrib/llvm/tools/clang/lib/AST/ItaniumCXXABI.cpp b/contrib/llvm/tools/clang/lib/AST/ItaniumCXXABI.cpp
index 5784660..b5f8c0f 100644
--- a/contrib/llvm/tools/clang/lib/AST/ItaniumCXXABI.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ItaniumCXXABI.cpp
@@ -33,12 +33,17 @@ namespace {
/// literals within a particular context.
class ItaniumNumberingContext : public MangleNumberingContext {
llvm::DenseMap<IdentifierInfo*, unsigned> VarManglingNumbers;
+ llvm::DenseMap<IdentifierInfo*, unsigned> TagManglingNumbers;
public:
/// Variable decls are numbered by identifier.
- virtual unsigned getManglingNumber(const VarDecl *VD) {
+ unsigned getManglingNumber(const VarDecl *VD, unsigned) override {
return ++VarManglingNumbers[VD->getIdentifier()];
}
+
+ unsigned getManglingNumber(const TagDecl *TD, unsigned) override {
+ return ++TagManglingNumbers[TD->getIdentifier()];
+ }
};
class ItaniumCXXABI : public CXXABI {
@@ -48,7 +53,7 @@ public:
ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { }
std::pair<uint64_t, unsigned>
- getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const {
+ getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override {
const TargetInfo &Target = Context.getTargetInfo();
TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0);
uint64_t Width = Target.getTypeWidth(PtrDiff);
@@ -58,13 +63,17 @@ public:
return std::make_pair(Width, Align);
}
- CallingConv getDefaultMethodCallConv(bool isVariadic) const {
+ CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
+ const llvm::Triple &T = Context.getTargetInfo().getTriple();
+ if (!isVariadic && T.isWindowsGNUEnvironment() &&
+ T.getArch() == llvm::Triple::x86)
+ return CC_X86ThisCall;
return CC_C;
}
// We cheat and just check that the class has a vtable pointer, and that it's
// only big enough to have a vtable pointer and nothing more (or less).
- bool isNearlyEmpty(const CXXRecordDecl *RD) const {
+ bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
// Check that the class has a vtable pointer.
if (!RD->isDynamicClass())
@@ -76,21 +85,12 @@ public:
return Layout.getNonVirtualSize() == PointerSize;
}
- virtual MangleNumberingContext *createMangleNumberingContext() const {
+ MangleNumberingContext *createMangleNumberingContext() const override {
return new ItaniumNumberingContext();
}
};
-
-class ARMCXXABI : public ItaniumCXXABI {
-public:
- ARMCXXABI(ASTContext &Ctx) : ItaniumCXXABI(Ctx) { }
-};
}
CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) {
return new ItaniumCXXABI(Ctx);
}
-
-CXXABI *clang::CreateARMCXXABI(ASTContext &Ctx) {
- return new ARMCXXABI(Ctx);
-}
diff --git a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp
index 0621d7b..977d6fc 100644
--- a/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ItaniumMangle.cpp
@@ -11,7 +11,7 @@
// which is used in GCC 3.2 and newer (and many compilers that are
// ABI-compatible with GCC):
//
-// http://www.codesourcery.com/public/cxx-abi/abi.html
+// http://mentorembedded.github.io/cxx-abi/abi.html#mangling
//
//===----------------------------------------------------------------------===//
#include "clang/AST/Mangle.h"
@@ -21,6 +21,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeLoc.h"
@@ -87,7 +88,7 @@ static const RecordDecl *GetLocalClassDecl(const Decl *D) {
D = cast<Decl>(DC);
DC = getEffectiveDeclContext(D);
}
- return 0;
+ return nullptr;
}
static const FunctionDecl *getStructor(const FunctionDecl *fn) {
@@ -101,11 +102,18 @@ static const NamedDecl *getStructor(const NamedDecl *decl) {
const FunctionDecl *fn = dyn_cast_or_null<FunctionDecl>(decl);
return (fn ? getStructor(fn) : decl);
}
-
+
+static bool isLambda(const NamedDecl *ND) {
+ const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
+ if (!Record)
+ return false;
+
+ return Record->isLambda();
+}
+
static const unsigned UnknownArity = ~0U;
class ItaniumMangleContextImpl : public ItaniumMangleContext {
- llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
typedef std::pair<const DeclContext*, IdentifierInfo*> DiscriminatorKeyTy;
llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
@@ -115,52 +123,47 @@ public:
DiagnosticsEngine &Diags)
: ItaniumMangleContext(Context, Diags) {}
- 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 shouldMangleCXXName(const NamedDecl *D);
- void mangleCXXName(const NamedDecl *D, raw_ostream &);
- void mangleThunk(const CXXMethodDecl *MD,
- const ThunkInfo &Thunk,
- raw_ostream &);
+ bool shouldMangleCXXName(const NamedDecl *D) override;
+ bool shouldMangleStringLiteral(const StringLiteral *) override {
+ return false;
+ }
+ void mangleCXXName(const NamedDecl *D, raw_ostream &) override;
+ void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
+ raw_ostream &) override;
void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
const ThisAdjustment &ThisAdjustment,
- raw_ostream &);
- void mangleReferenceTemporary(const VarDecl *D,
- raw_ostream &);
- void mangleCXXVTable(const CXXRecordDecl *RD,
- raw_ostream &);
- void mangleCXXVTT(const CXXRecordDecl *RD,
- raw_ostream &);
+ raw_ostream &) override;
+ void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber,
+ raw_ostream &) override;
+ void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) override;
+ void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) override;
void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
- const CXXRecordDecl *Type,
- raw_ostream &);
- void mangleCXXRTTI(QualType T, raw_ostream &);
- void mangleCXXRTTIName(QualType T, raw_ostream &);
- void mangleTypeName(QualType T, raw_ostream &);
+ const CXXRecordDecl *Type, raw_ostream &) override;
+ void mangleCXXRTTI(QualType T, raw_ostream &) override;
+ void mangleCXXRTTIName(QualType T, raw_ostream &) override;
+ void mangleTypeName(QualType T, raw_ostream &) override;
void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
- raw_ostream &);
+ raw_ostream &) override;
void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
- raw_ostream &);
+ raw_ostream &) override;
+
+ void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) override;
+ void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
+ void mangleDynamicAtExitDestructor(const VarDecl *D,
+ raw_ostream &Out) override;
+ void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &) override;
+ void mangleItaniumThreadLocalWrapper(const VarDecl *D,
+ raw_ostream &) override;
- void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &);
- void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
- void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &Out);
- void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &);
- void mangleItaniumThreadLocalWrapper(const VarDecl *D, raw_ostream &);
+ void mangleStringLiteral(const StringLiteral *, raw_ostream &) override;
bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
// Lambda closure types are already numbered.
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND))
- if (RD->isLambda())
- return false;
+ if (isLambda(ND))
+ return false;
// Anonymous tags are already numbered.
if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
@@ -250,7 +253,7 @@ class CXXNameMangler {
public:
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
- const NamedDecl *D = 0)
+ const NamedDecl *D = nullptr)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0),
SeqID(0) {
// These can't be mangled without a ctor type or dtor type.
@@ -285,11 +288,13 @@ public:
void mangleNumber(int64_t Number);
void mangleFloat(const llvm::APFloat &F);
void mangleFunctionEncoding(const FunctionDecl *FD);
+ void mangleSeqID(unsigned SeqID);
void mangleName(const NamedDecl *ND);
void mangleType(QualType T);
void mangleNameOrStandardSubstitution(const NamedDecl *ND);
private:
+
bool mangleSubstitution(const NamedDecl *ND);
bool mangleSubstitution(QualType T);
bool mangleSubstitution(TemplateName Template);
@@ -454,6 +459,25 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
if (!Context.shouldMangleDeclName(FD))
return;
+ if (FD->hasAttr<EnableIfAttr>()) {
+ FunctionTypeDepthState Saved = FunctionTypeDepth.push();
+ Out << "Ua9enable_ifI";
+ // FIXME: specific_attr_iterator iterates in reverse order. Fix that and use
+ // it here.
+ for (AttrVec::const_reverse_iterator I = FD->getAttrs().rbegin(),
+ E = FD->getAttrs().rend();
+ I != E; ++I) {
+ EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
+ if (!EIA)
+ continue;
+ Out << 'X';
+ mangleExpression(EIA->getCond());
+ Out << 'E';
+ }
+ Out << 'E';
+ FunctionTypeDepth.pop(Saved);
+ }
+
// Whether the mangling of a function type includes the return type depends on
// the context and the nature of the function. The rules for deciding whether
// the return type is included are:
@@ -535,15 +559,7 @@ isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
return Spec->getSpecializedTemplate();
}
- return 0;
-}
-
-static bool isLambda(const NamedDecl *ND) {
- const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
- if (!Record)
- return false;
-
- return Record->isLambda();
+ return nullptr;
}
void CXXNameMangler::mangleName(const NamedDecl *ND) {
@@ -570,7 +586,7 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
// Check if we have a template.
- const TemplateArgumentList *TemplateArgs = 0;
+ const TemplateArgumentList *TemplateArgs = nullptr;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleUnscopedTemplateName(TD);
mangleTemplateArgs(*TemplateArgs);
@@ -833,6 +849,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
switch (type->getTypeClass()) {
case Type::Builtin:
case Type::Complex:
+ case Type::Adjusted:
case Type::Decayed:
case Type::Pointer:
case Type::BlockPointer:
@@ -983,26 +1000,27 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
// Pretend we had a different nested name specifier.
newQualifier = NestedNameSpecifier::Create(getASTContext(),
- /*prefix*/ 0,
+ /*prefix*/ nullptr,
/*template*/ false,
type.getTypePtr());
} else if (NamespaceDecl *nspace =
dyn_cast<NamespaceDecl>(firstQualifierLookup)) {
newQualifier = NestedNameSpecifier::Create(getASTContext(),
- /*prefix*/ 0,
+ /*prefix*/ nullptr,
nspace);
} else if (NamespaceAliasDecl *alias =
dyn_cast<NamespaceAliasDecl>(firstQualifierLookup)) {
newQualifier = NestedNameSpecifier::Create(getASTContext(),
- /*prefix*/ 0,
+ /*prefix*/ nullptr,
alias);
} else {
// No sensible mangling to do here.
- newQualifier = 0;
+ newQualifier = nullptr;
}
if (newQualifier)
- return mangleUnresolvedPrefix(newQualifier, /*lookup*/ 0, recursive);
+ return mangleUnresolvedPrefix(newQualifier, /*lookup*/ nullptr,
+ recursive);
} else {
Out << "sr";
@@ -1025,26 +1043,25 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *qualifier,
DeclarationName name,
unsigned knownArity) {
if (qualifier) mangleUnresolvedPrefix(qualifier, firstQualifierLookup);
- mangleUnqualifiedName(0, name, knownArity);
+ mangleUnqualifiedName(nullptr, name, knownArity);
}
static const FieldDecl *FindFirstNamedDataMember(const RecordDecl *RD) {
assert(RD->isAnonymousStructOrUnion() &&
"Expected anonymous struct or union!");
- for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
- I != E; ++I) {
+ for (const auto *I : RD->fields()) {
if (I->getIdentifier())
- return *I;
+ return I;
if (const RecordType *RT = I->getType()->getAs<RecordType>())
if (const FieldDecl *NamedDataMember =
FindFirstNamedDataMember(RT->getDecl()))
return NamedDataMember;
- }
+ }
// We didn't find a named data member.
- return 0;
+ return nullptr;
}
void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
@@ -1148,7 +1165,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
}
// Get a unique id for the anonymous struct.
- uint64_t AnonStructId = Context.getAnonymousStructId(TD);
+ unsigned AnonStructId = Context.getAnonymousStructId(TD);
// Mangle it as a source name in the form
// [n] $_<id>
@@ -1250,7 +1267,7 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
}
// Check if we have a template.
- const TemplateArgumentList *TemplateArgs = 0;
+ const TemplateArgumentList *TemplateArgs = nullptr;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleTemplatePrefix(TD, NoFunction);
mangleTemplateArgs(*TemplateArgs);
@@ -1490,7 +1507,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
return;
// Check if we have a template.
- const TemplateArgumentList *TemplateArgs = 0;
+ const TemplateArgumentList *TemplateArgs = nullptr;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleTemplatePrefix(TD);
mangleTemplateArgs(*TemplateArgs);
@@ -1514,7 +1531,7 @@ void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) {
if (OverloadedTemplateStorage *Overloaded
= Template.getAsOverloadedTemplate()) {
- mangleUnqualifiedName(0, (*Overloaded->begin())->getDeclName(),
+ mangleUnqualifiedName(nullptr, (*Overloaded->begin())->getDeclName(),
UnknownArity);
return;
}
@@ -1556,8 +1573,8 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND,
void CXXNameMangler::mangleType(TemplateName TN) {
if (mangleSubstitution(TN))
return;
-
- TemplateDecl *TD = 0;
+
+ TemplateDecl *TD = nullptr;
switch (TN.getKind()) {
case TemplateName::QualifiedTemplate:
@@ -1584,7 +1601,7 @@ void CXXNameMangler::mangleType(TemplateName TN) {
// <class-enum-type> ::= <name>
// <name> ::= <nested-name>
- mangleUnresolvedPrefix(Dependent->getQualifier(), 0);
+ mangleUnresolvedPrefix(Dependent->getQualifier(), nullptr);
mangleSourceName(Dependent->getIdentifier());
break;
}
@@ -1919,7 +1936,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
// ::= x # long long, __int64
// ::= y # unsigned long long, __int64
// ::= n # __int128
- // UNSUPPORTED: ::= o # unsigned __int128
+ // ::= o # unsigned __int128
// ::= f # float
// ::= d # double
// ::= e # long double, __float80
@@ -2012,11 +2029,11 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
// <bare-function-type> ::= <signature type>+
if (MangleReturnType) {
FunctionTypeDepth.enterResultType();
- mangleType(Proto->getResultType());
+ mangleType(Proto->getReturnType());
FunctionTypeDepth.leaveResultType();
}
- if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
+ if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
// <builtin-type> ::= v # void
Out << 'v';
@@ -2024,10 +2041,8 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
return;
}
- for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
- ArgEnd = Proto->arg_type_end();
- Arg != ArgEnd; ++Arg)
- mangleType(Context.getASTContext().getSignatureParameterType(*Arg));
+ for (const auto &Arg : Proto->param_types())
+ mangleType(Context.getASTContext().getSignatureParameterType(Arg));
FunctionTypeDepth.pop(saved);
@@ -2158,11 +2173,20 @@ void CXXNameMangler::mangleType(const ComplexType *T) {
void CXXNameMangler::mangleNeonVectorType(const VectorType *T) {
QualType EltType = T->getElementType();
assert(EltType->isBuiltinType() && "Neon vector element not a BuiltinType");
- const char *EltName = 0;
+ const char *EltName = nullptr;
if (T->getVectorKind() == VectorType::NeonPolyVector) {
switch (cast<BuiltinType>(EltType)->getKind()) {
- case BuiltinType::SChar: EltName = "poly8_t"; break;
- case BuiltinType::Short: EltName = "poly16_t"; break;
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+ EltName = "poly8_t";
+ break;
+ case BuiltinType::Short:
+ case BuiltinType::UShort:
+ EltName = "poly16_t";
+ break;
+ case BuiltinType::ULongLong:
+ EltName = "poly64_t";
+ break;
default: llvm_unreachable("unexpected Neon polynomial vector element type");
}
} else {
@@ -2175,13 +2199,14 @@ void CXXNameMangler::mangleNeonVectorType(const VectorType *T) {
case BuiltinType::UInt: EltName = "uint32_t"; break;
case BuiltinType::LongLong: EltName = "int64_t"; break;
case BuiltinType::ULongLong: EltName = "uint64_t"; break;
+ case BuiltinType::Double: EltName = "float64_t"; break;
case BuiltinType::Float: EltName = "float32_t"; break;
case BuiltinType::Half: EltName = "float16_t";break;
default:
llvm_unreachable("unexpected Neon vector element type");
}
}
- const char *BaseName = 0;
+ const char *BaseName = nullptr;
unsigned BitSize = (T->getNumElements() *
getASTContext().getTypeSize(EltType));
if (BitSize == 64)
@@ -2202,6 +2227,7 @@ static StringRef mangleAArch64VectorBase(const BuiltinType *EltType) {
return "Int16";
case BuiltinType::Int:
return "Int32";
+ case BuiltinType::Long:
case BuiltinType::LongLong:
return "Int64";
case BuiltinType::UChar:
@@ -2210,6 +2236,7 @@ static StringRef mangleAArch64VectorBase(const BuiltinType *EltType) {
return "Uint16";
case BuiltinType::UInt:
return "Uint32";
+ case BuiltinType::ULong:
case BuiltinType::ULongLong:
return "Uint64";
case BuiltinType::Half:
@@ -2245,7 +2272,7 @@ void CXXNameMangler::mangleAArch64NeonVectorType(const VectorType *T) {
case BuiltinType::UShort:
EltName = "Poly16";
break;
- case BuiltinType::ULongLong:
+ case BuiltinType::ULong:
EltName = "Poly64";
break;
default:
@@ -2270,8 +2297,13 @@ void CXXNameMangler::mangleAArch64NeonVectorType(const VectorType *T) {
void CXXNameMangler::mangleType(const VectorType *T) {
if ((T->getVectorKind() == VectorType::NeonVector ||
T->getVectorKind() == VectorType::NeonPolyVector)) {
- if (getASTContext().getTargetInfo().getTriple().getArch() ==
- llvm::Triple::aarch64)
+ llvm::Triple Target = getASTContext().getTargetInfo().getTriple();
+ llvm::Triple::ArchType Arch =
+ getASTContext().getTargetInfo().getTriple().getArch();
+ if ((Arch == llvm::Triple::aarch64 ||
+ Arch == llvm::Triple::aarch64_be ||
+ Arch == llvm::Triple::arm64_be ||
+ Arch == llvm::Triple::arm64) && !Target.isOSDarwin())
mangleAArch64NeonVectorType(T);
else
mangleNeonVectorType(T);
@@ -2311,9 +2343,8 @@ void CXXNameMangler::mangleType(const ObjCObjectType *T) {
SmallString<64> QualStr;
llvm::raw_svector_ostream QualOS(QualStr);
QualOS << "objcproto";
- ObjCObjectType::qual_iterator i = T->qual_begin(), e = T->qual_end();
- for ( ; i != e; ++i) {
- StringRef name = (*i)->getName();
+ for (const auto *I : T->quals()) {
+ StringRef name = I->getName();
QualOS << name.size() << name;
}
QualOS.flush();
@@ -2352,10 +2383,37 @@ void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
}
void CXXNameMangler::mangleType(const DependentNameType *T) {
+ // Proposal by cxx-abi-dev, 2014-03-26
+ // <class-enum-type> ::= <name> # non-dependent or dependent type name or
+ // # dependent elaborated type specifier using
+ // # 'typename'
+ // ::= Ts <name> # dependent elaborated type specifier using
+ // # 'struct' or 'class'
+ // ::= Tu <name> # dependent elaborated type specifier using
+ // # 'union'
+ // ::= Te <name> # dependent elaborated type specifier using
+ // # 'enum'
+ switch (T->getKeyword()) {
+ case ETK_Typename:
+ break;
+ case ETK_Struct:
+ case ETK_Class:
+ case ETK_Interface:
+ Out << "Ts";
+ break;
+ case ETK_Union:
+ Out << "Tu";
+ break;
+ case ETK_Enum:
+ Out << "Te";
+ break;
+ default:
+ llvm_unreachable("unexpected keyword for dependent type name");
+ }
// Typename types are always nested
Out << 'N';
manglePrefix(T->getQualifier());
- mangleSourceName(T->getIdentifier());
+ mangleSourceName(T->getIdentifier());
Out << 'E';
}
@@ -2438,7 +2496,7 @@ void CXXNameMangler::mangleType(const AutoType *T) {
}
void CXXNameMangler::mangleType(const AtomicType *T) {
- // <type> ::= U <source-name> <type> # vendor extended type qualifier
+ // <type> ::= U <source-name> <type> # vendor extended type qualifier
// (Until there's a standardized mangling...)
Out << "U7_Atomic";
mangleType(T->getValueType());
@@ -2581,8 +2639,6 @@ recurse:
case Expr::ShuffleVectorExprClass:
case Expr::ConvertVectorExprClass:
case Expr::StmtExprClass:
- case Expr::UnaryTypeTraitExprClass:
- case Expr::BinaryTypeTraitExprClass:
case Expr::TypeTraitExprClass:
case Expr::ArrayTypeTraitExprClass:
case Expr::ExpressionTraitExprClass:
@@ -2618,7 +2674,6 @@ recurse:
llvm_unreachable("cannot mangle opaque value; mangling wrong thing?");
case Expr::InitListExprClass: {
- // Proposal by Jason Merrill, 2012-01-03
Out << "il";
const InitListExpr *InitList = cast<InitListExpr>(E);
for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)
@@ -2683,7 +2738,6 @@ recurse:
Out << '_';
mangleType(New->getAllocatedType());
if (New->hasInitializer()) {
- // Proposal by Jason Merrill, 2012-01-03
if (New->getInitializationStyle() == CXXNewExpr::ListInit)
Out << "il";
else
@@ -2714,15 +2768,15 @@ recurse:
case Expr::MemberExprClass: {
const MemberExpr *ME = cast<MemberExpr>(E);
mangleMemberExpr(ME->getBase(), ME->isArrow(),
- ME->getQualifier(), 0, ME->getMemberDecl()->getDeclName(),
- Arity);
+ ME->getQualifier(), nullptr,
+ ME->getMemberDecl()->getDeclName(), Arity);
break;
}
case Expr::UnresolvedMemberExprClass: {
const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E);
mangleMemberExpr(ME->getBase(), ME->isArrow(),
- ME->getQualifier(), 0, ME->getMemberName(),
+ ME->getQualifier(), nullptr, ME->getMemberName(),
Arity);
if (ME->hasExplicitTemplateArgs())
mangleTemplateArgs(ME->getExplicitTemplateArgs());
@@ -2742,7 +2796,7 @@ recurse:
case Expr::UnresolvedLookupExprClass: {
const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E);
- mangleUnresolvedName(ULE->getQualifier(), 0, ULE->getName(), Arity);
+ mangleUnresolvedName(ULE->getQualifier(), nullptr, ULE->getName(), Arity);
// All the <unresolved-name> productions end in a
// base-unresolved-name, where <template-args> are just tacked
@@ -2769,7 +2823,6 @@ recurse:
const CXXConstructExpr *CE = cast<CXXConstructExpr>(E);
unsigned N = CE->getNumArgs();
- // Proposal by Jason Merrill, 2012-01-03
if (CE->isListInitialization())
Out << "tl";
else
@@ -3005,7 +3058,8 @@ recurse:
case Expr::DependentScopeDeclRefExprClass: {
const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E);
- mangleUnresolvedName(DRE->getQualifier(), 0, DRE->getDeclName(), Arity);
+ mangleUnresolvedName(DRE->getQualifier(), nullptr, DRE->getDeclName(),
+ Arity);
// All the <unresolved-name> productions end in a
// base-unresolved-name, where <template-args> are just tacked
@@ -3342,10 +3396,8 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {
case TemplateArgument::Pack: {
// <template-arg> ::= J <template-arg>* E
Out << 'J';
- for (TemplateArgument::pack_iterator PA = A.pack_begin(),
- PAEnd = A.pack_end();
- PA != PAEnd; ++PA)
- mangleTemplateArg(*PA);
+ for (const auto &P : A.pack_elements())
+ mangleTemplateArg(P);
Out << 'E';
}
}
@@ -3360,6 +3412,27 @@ void CXXNameMangler::mangleTemplateParameter(unsigned Index) {
Out << 'T' << (Index - 1) << '_';
}
+void CXXNameMangler::mangleSeqID(unsigned SeqID) {
+ if (SeqID == 1)
+ Out << '0';
+ else if (SeqID > 1) {
+ SeqID--;
+
+ // <seq-id> is encoded in base-36, using digits and upper case letters.
+ char Buffer[7]; // log(2**32) / log(36) ~= 7
+ MutableArrayRef<char> BufferRef(Buffer);
+ MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
+
+ for (; SeqID != 0; SeqID /= 36) {
+ unsigned C = SeqID % 36;
+ *I++ = (C < 10 ? '0' + C : 'A' + C - 10);
+ }
+
+ Out.write(I.base(), I - BufferRef.rbegin());
+ }
+ Out << '_';
+}
+
void CXXNameMangler::mangleExistingSubstitution(QualType type) {
bool result = mangleSubstitution(type);
assert(result && "no existing substitution for type");
@@ -3416,30 +3489,8 @@ bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
return false;
unsigned SeqID = I->second;
- if (SeqID == 0)
- Out << "S_";
- else {
- SeqID--;
-
- // <seq-id> is encoded in base-36, using digits and upper case letters.
- char Buffer[10];
- char *BufferPtr = llvm::array_endof(Buffer);
-
- if (SeqID == 0) *--BufferPtr = '0';
-
- while (SeqID) {
- assert(BufferPtr > Buffer && "Buffer overflow!");
-
- char c = static_cast<char>(SeqID % 36);
-
- *--BufferPtr = (c < 10 ? '0' + c : 'A' + c - 10);
- SeqID /= 36;
- }
-
- Out << 'S'
- << StringRef(BufferPtr, llvm::array_endof(Buffer)-BufferPtr)
- << '_';
- }
+ Out << 'S';
+ mangleSeqID(SeqID);
return true;
}
@@ -3732,12 +3783,15 @@ ItaniumMangleContextImpl::mangleItaniumThreadLocalWrapper(const VarDecl *D,
}
void ItaniumMangleContextImpl::mangleReferenceTemporary(const VarDecl *D,
+ unsigned ManglingNumber,
raw_ostream &Out) {
// We match the GCC mangling here.
// <special-name> ::= GR <object name>
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZGR";
Mangler.mangleName(D);
+ assert(ManglingNumber > 0 && "Reference temporary mangling number is zero!");
+ Mangler.mangleSeqID(ManglingNumber - 1);
}
void ItaniumMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *RD,
@@ -3789,6 +3843,10 @@ void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out) {
mangleCXXRTTIName(Ty, Out);
}
+void ItaniumMangleContextImpl::mangleStringLiteral(const StringLiteral *, raw_ostream &) {
+ llvm_unreachable("Can't mangle string literals");
+}
+
ItaniumMangleContext *
ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
return new ItaniumMangleContextImpl(Context, Diags);
diff --git a/contrib/llvm/tools/clang/lib/AST/Mangle.cpp b/contrib/llvm/tools/clang/lib/AST/Mangle.cpp
index 231ef03..fdc00e3 100644
--- a/contrib/llvm/tools/clang/lib/AST/Mangle.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/Mangle.cpp
@@ -11,13 +11,13 @@
//
//===----------------------------------------------------------------------===//
#include "clang/AST/Attr.h"
-#include "clang/AST/Mangle.h"
#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/ExprCXX.h"
+#include "clang/AST/Mangle.h"
#include "clang/Basic/ABI.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -64,7 +64,7 @@ static bool isExternC(const NamedDecl *ND) {
static StdOrFastCC getStdOrFastCallMangling(const ASTContext &Context,
const NamedDecl *ND) {
const TargetInfo &TI = Context.getTargetInfo();
- llvm::Triple Triple = TI.getTriple();
+ const llvm::Triple &Triple = TI.getTriple();
if (!Triple.isOSWindows() || Triple.getArch() != llvm::Triple::x86)
return SOF_OTHER;
@@ -163,13 +163,9 @@ void MangleContext::mangleName(const NamedDecl *D, raw_ostream &Out) {
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
if (!MD->isStatic())
++ArgWords;
- for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
- ArgEnd = Proto->arg_type_end();
- Arg != ArgEnd; ++Arg) {
- QualType AT = *Arg;
+ for (const auto &AT : Proto->param_types())
// Size should be aligned to DWORD boundary
ArgWords += llvm::RoundUpToAlignment(ASTContext.getTypeSize(AT), 32) / 32;
- }
Out << 4 * ArgWords;
}
@@ -246,7 +242,9 @@ void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
OS << '(' << *CID << ')';
- OS << ' ' << MD->getSelector().getAsString() << ']';
+ OS << ' ';
+ MD->getSelector().print(OS);
+ OS << ']';
Out << OS.str().size() << OS.str();
}
diff --git a/contrib/llvm/tools/clang/lib/AST/MangleNumberingContext.cpp b/contrib/llvm/tools/clang/lib/AST/MangleNumberingContext.cpp
index 91ef0e2..5f40f03 100644
--- a/contrib/llvm/tools/clang/lib/AST/MangleNumberingContext.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/MangleNumberingContext.cpp
@@ -24,7 +24,7 @@ MangleNumberingContext::getManglingNumber(const CXXMethodDecl *CallOperator) {
= CallOperator->getType()->getAs<FunctionProtoType>();
ASTContext &Context = CallOperator->getASTContext();
- QualType Key = Context.getFunctionType(Context.VoidTy, Proto->getArgTypes(),
+ QualType Key = Context.getFunctionType(Context.VoidTy, Proto->getParamTypes(),
FunctionProtoType::ExtProtoInfo());
Key = Context.getCanonicalType(Key);
return ++ManglingNumbers[Key->castAs<FunctionProtoType>()];
@@ -33,11 +33,13 @@ MangleNumberingContext::getManglingNumber(const CXXMethodDecl *CallOperator) {
unsigned
MangleNumberingContext::getManglingNumber(const BlockDecl *BD) {
// FIXME: Compute a BlockPointerType? Not obvious how.
- const Type *Ty = 0;
+ const Type *Ty = nullptr;
return ++ManglingNumbers[Ty];
}
unsigned
-MangleNumberingContext::getManglingNumber(const TagDecl *TD) {
- return ++TagManglingNumbers[TD->getIdentifier()];
+MangleNumberingContext::getStaticLocalNumber(const VarDecl *VD) {
+ // FIXME: Compute a BlockPointerType? Not obvious how.
+ const Type *Ty = nullptr;
+ return ++ManglingNumbers[Ty];
}
diff --git a/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp b/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp
index 4a93ea1..6870315 100644
--- a/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/MicrosoftCXXABI.cpp
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
#include "CXXABI.h"
-#include "clang/AST/Attr.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/MangleNumberingContext.h"
#include "clang/AST/RecordLayout.h"
@@ -28,15 +28,15 @@ namespace {
/// \brief Numbers things which need to correspond across multiple TUs.
/// Typically these are things like static locals, lambdas, or blocks.
class MicrosoftNumberingContext : public MangleNumberingContext {
- unsigned NumStaticLocals;
-
public:
- MicrosoftNumberingContext() : NumStaticLocals(0) { }
+ unsigned getManglingNumber(const VarDecl *VD,
+ unsigned MSLocalManglingNumber) override {
+ return MSLocalManglingNumber;
+ }
- /// Static locals are numbered by source order.
- virtual unsigned getManglingNumber(const VarDecl *VD) {
- assert(VD->isStaticLocal());
- return ++NumStaticLocals;
+ unsigned getManglingNumber(const TagDecl *TD,
+ unsigned MSLocalManglingNumber) override {
+ return MSLocalManglingNumber;
}
};
@@ -46,16 +46,16 @@ public:
MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
std::pair<uint64_t, unsigned>
- getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const;
+ getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override;
- CallingConv getDefaultMethodCallConv(bool isVariadic) const {
+ CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
if (!isVariadic &&
Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
return CC_X86ThisCall;
return CC_C;
}
- bool isNearlyEmpty(const CXXRecordDecl *RD) const {
+ bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
// FIXME: Audit the corners
if (!RD->isDynamicClass())
return false;
@@ -69,7 +69,7 @@ public:
Layout.getNonVirtualSize() == PointerSize * 2;
}
- MangleNumberingContext *createMangleNumberingContext() const {
+ MangleNumberingContext *createMangleNumberingContext() const override {
return new MicrosoftNumberingContext();
}
};
@@ -92,26 +92,27 @@ static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
return false;
}
-static MSInheritanceModel MSInheritanceAttrToModel(attr::Kind Kind) {
- switch (Kind) {
- default: llvm_unreachable("expected MS inheritance attribute");
- case attr::SingleInheritance: return MSIM_Single;
- case attr::MultipleInheritance: return MSIM_Multiple;
- case attr::VirtualInheritance: return MSIM_Virtual;
- case attr::UnspecifiedInheritance: return MSIM_Unspecified;
- }
+MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
+ if (!hasDefinition() || isParsingBaseSpecifiers())
+ return MSInheritanceAttr::Keyword_unspecified_inheritance;
+ if (getNumVBases() > 0)
+ return MSInheritanceAttr::Keyword_virtual_inheritance;
+ if (usesMultipleInheritanceModel(this))
+ return MSInheritanceAttr::Keyword_multiple_inheritance;
+ return MSInheritanceAttr::Keyword_single_inheritance;
}
-MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
- if (Attr *IA = this->getAttr<MSInheritanceAttr>())
- return MSInheritanceAttrToModel(IA->getKind());
- // If there was no explicit attribute, the record must be defined already, and
- // we can figure out the inheritance model from its other properties.
- if (this->getNumVBases() > 0)
- return MSIM_Virtual;
- if (usesMultipleInheritanceModel(this))
- return this->isPolymorphic() ? MSIM_MultiplePolymorphic : MSIM_Multiple;
- return this->isPolymorphic() ? MSIM_SinglePolymorphic : MSIM_Single;
+MSInheritanceAttr::Spelling
+CXXRecordDecl::getMSInheritanceModel() const {
+ MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
+ assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
+ return IA->getSemanticSpelling();
+}
+
+MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
+ if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
+ return VDA->getVtorDispMode();
+ return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
}
// Returns the number of pointer and integer slots used to represent a member
@@ -133,49 +134,32 @@ MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
// // offset.
// int NonVirtualBaseAdjustment;
//
+// // The offset of the vb-table pointer within the object. Only needed for
+// // incomplete types.
+// int VBPtrOffset;
+//
// // An offset within the vb-table that selects the virtual base containing
// // the member. Loading from this offset produces a new offset that is
// // added to the address of the vb-table pointer to produce the base.
// int VirtualBaseAdjustmentOffset;
-//
-// // The offset of the vb-table pointer within the object. Only needed for
-// // incomplete types.
-// int VBPtrOffset;
// };
static std::pair<unsigned, unsigned>
getMSMemberPointerSlots(const MemberPointerType *MPT) {
- const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
- MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
- unsigned Ptrs;
+ const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ unsigned Ptrs = 0;
unsigned Ints = 0;
- if (MPT->isMemberFunctionPointer()) {
- // Member function pointers are a struct of a function pointer followed by a
- // variable number of ints depending on the inheritance model used. The
- // function pointer is a real function if it is non-virtual and a vftable
- // slot thunk if it is virtual. The ints select the object base passed for
- // the 'this' pointer.
- Ptrs = 1; // First slot is always a function pointer.
- switch (Inheritance) {
- case MSIM_Unspecified: ++Ints; // VBTableOffset
- case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset
- case MSIM_MultiplePolymorphic:
- case MSIM_Multiple: ++Ints; // NonVirtualBaseAdjustment
- case MSIM_SinglePolymorphic:
- case MSIM_Single: break; // Nothing
- }
- } else {
- // Data pointers are an aggregate of ints. The first int is an offset
- // followed by vbtable-related offsets.
- Ptrs = 0;
- switch (Inheritance) {
- case MSIM_Unspecified: ++Ints; // VBTableOffset
- case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset
- case MSIM_MultiplePolymorphic:
- case MSIM_Multiple: // Nothing
- case MSIM_SinglePolymorphic:
- case MSIM_Single: ++Ints; // Field offset
- }
- }
+ if (MPT->isMemberFunctionPointer())
+ Ptrs = 1;
+ else
+ Ints = 1;
+ if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
+ Inheritance))
+ Ints++;
+ if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
+ Ints++;
+ if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
+ Ints++;
return std::make_pair(Ptrs, Ints);
}
@@ -185,14 +169,26 @@ std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
assert(Target.getTriple().getArch() == llvm::Triple::x86 ||
Target.getTriple().getArch() == llvm::Triple::x86_64);
unsigned Ptrs, Ints;
- llvm::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
+ std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
// The nominal struct is laid out with pointers followed by ints and aligned
// to a pointer width if any are present and an int width otherwise.
unsigned PtrSize = Target.getPointerWidth(0);
unsigned IntSize = Target.getIntWidth();
uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
- unsigned Align = Ptrs > 0 ? Target.getPointerAlign(0) : Target.getIntAlign();
- Width = llvm::RoundUpToAlignment(Width, Align);
+ unsigned Align;
+
+ // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
+ // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
+ // function memptrs.
+ if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86)
+ Align = 8 * 8;
+ else if (Ptrs)
+ Align = Target.getPointerAlign(0);
+ else
+ Align = Target.getIntAlign();
+
+ if (Target.getTriple().getArch() == llvm::Triple::x86_64)
+ Width = llvm::RoundUpToAlignment(Width, Align);
return std::make_pair(Width, Align);
}
diff --git a/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp b/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp
index 5256501..e6a6d09 100644
--- a/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp
@@ -14,17 +14,21 @@
#include "clang/AST/Mangle.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
-#include "clang/AST/CharUnits.h"
#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/CharUnits.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/ExprCXX.h"
+#include "clang/AST/VTableBuilder.h"
#include "clang/Basic/ABI.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MathExtras.h"
using namespace clang;
@@ -71,10 +75,114 @@ static const FunctionDecl *getStructor(const FunctionDecl *fn) {
return fn;
}
+static bool isLambda(const NamedDecl *ND) {
+ const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
+ if (!Record)
+ return false;
+
+ return Record->isLambda();
+}
+
+/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
+/// Microsoft Visual C++ ABI.
+class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
+ typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
+ llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
+ llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
+ llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
+
+public:
+ MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
+ : MicrosoftMangleContext(Context, Diags) {}
+ bool shouldMangleCXXName(const NamedDecl *D) override;
+ bool shouldMangleStringLiteral(const StringLiteral *SL) override;
+ void mangleCXXName(const NamedDecl *D, raw_ostream &Out) override;
+ void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
+ raw_ostream &) override;
+ void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
+ raw_ostream &) override;
+ void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
+ const ThisAdjustment &ThisAdjustment,
+ raw_ostream &) override;
+ void mangleCXXVFTable(const CXXRecordDecl *Derived,
+ ArrayRef<const CXXRecordDecl *> BasePath,
+ raw_ostream &Out) override;
+ void mangleCXXVBTable(const CXXRecordDecl *Derived,
+ ArrayRef<const CXXRecordDecl *> BasePath,
+ raw_ostream &Out) override;
+ void mangleCXXRTTI(QualType T, raw_ostream &Out) override;
+ void mangleCXXRTTIName(QualType T, raw_ostream &Out) override;
+ void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived,
+ uint32_t NVOffset, int32_t VBPtrOffset,
+ uint32_t VBTableOffset, uint32_t Flags,
+ raw_ostream &Out) override;
+ void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
+ raw_ostream &Out) override;
+ void mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
+ raw_ostream &Out) override;
+ void
+ mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
+ ArrayRef<const CXXRecordDecl *> BasePath,
+ raw_ostream &Out) override;
+ void mangleTypeName(QualType T, raw_ostream &) override;
+ void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
+ raw_ostream &) override;
+ void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
+ raw_ostream &) override;
+ void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber,
+ raw_ostream &) override;
+ void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override;
+ void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
+ void mangleDynamicAtExitDestructor(const VarDecl *D,
+ raw_ostream &Out) override;
+ void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override;
+ bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
+ // Lambda closure types are already numbered.
+ if (isLambda(ND))
+ return false;
+
+ const DeclContext *DC = getEffectiveDeclContext(ND);
+ if (!DC->isFunctionOrMethod())
+ return false;
+
+ // Use the canonical number for externally visible decls.
+ if (ND->isExternallyVisible()) {
+ disc = getASTContext().getManglingNumber(ND);
+ return true;
+ }
+
+ // Anonymous tags are already numbered.
+ if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
+ if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl())
+ return false;
+ }
+
+ // Make up a reasonable number for internal decls.
+ unsigned &discriminator = Uniquifier[ND];
+ if (!discriminator)
+ discriminator = ++Discriminator[std::make_pair(DC, ND->getIdentifier())];
+ disc = discriminator;
+ return true;
+ }
+
+ unsigned getLambdaId(const CXXRecordDecl *RD) {
+ assert(RD->isLambda() && "RD must be a lambda!");
+ assert(!RD->isExternallyVisible() && "RD must not be visible!");
+ assert(RD->getLambdaManglingNumber() == 0 &&
+ "RD must not have a mangling number!");
+ std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator, bool>
+ Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
+ return Result.first->second;
+ }
+
+private:
+ void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
+};
+
/// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
/// Microsoft Visual C++ ABI.
class MicrosoftCXXNameMangler {
- MangleContext &Context;
+ MicrosoftMangleContextImpl &Context;
raw_ostream &Out;
/// The "structor" is the top-level declaration being mangled, if
@@ -85,9 +193,8 @@ class MicrosoftCXXNameMangler {
typedef llvm::StringMap<unsigned> BackRefMap;
BackRefMap NameBackReferences;
- bool UseNameBackReferences;
- typedef llvm::DenseMap<void*, unsigned> ArgBackRefMap;
+ typedef llvm::DenseMap<void *, unsigned> ArgBackRefMap;
ArgBackRefMap TypeBackReferences;
ASTContext &getASTContext() const { return Context.getASTContext(); }
@@ -99,37 +206,38 @@ class MicrosoftCXXNameMangler {
public:
enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
- MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_)
- : Context(C), Out(Out_),
- Structor(0), StructorType(-1),
- UseNameBackReferences(true),
- PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
- 64) { }
+ MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
+ : Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
+ PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
+ 64) {}
- MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_,
+ MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
const CXXDestructorDecl *D, CXXDtorType Type)
- : Context(C), Out(Out_),
- Structor(getStructor(D)), StructorType(Type),
- UseNameBackReferences(true),
- PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
- 64) { }
+ : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
+ PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
+ 64) {}
raw_ostream &getStream() const { return Out; }
void mangle(const NamedDecl *D, StringRef Prefix = "\01?");
void mangleName(const NamedDecl *ND);
- void mangleDeclaration(const NamedDecl *ND);
void mangleFunctionEncoding(const FunctionDecl *FD);
void mangleVariableEncoding(const VarDecl *VD);
+ void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD);
+ void mangleMemberFunctionPointer(const CXXRecordDecl *RD,
+ const CXXMethodDecl *MD);
+ void mangleVirtualMemPtrThunk(
+ const CXXMethodDecl *MD,
+ const MicrosoftVTableContext::MethodVFTableLocation &ML);
void mangleNumber(int64_t Number);
void mangleType(QualType T, SourceRange Range,
QualifierMangleMode QMM = QMM_Mangle);
- void mangleFunctionType(const FunctionType *T, const FunctionDecl *D = 0,
+ void mangleFunctionType(const FunctionType *T,
+ const FunctionDecl *D = nullptr,
bool ForceInstMethod = false);
- void manglePostfix(const DeclContext *DC, bool NoFunction = false);
+ void mangleNestedName(const NamedDecl *ND);
private:
- void disableBackReferences() { UseNameBackReferences = false; }
void mangleUnqualifiedName(const NamedDecl *ND) {
mangleUnqualifiedName(ND, ND->getDeclName());
}
@@ -138,13 +246,15 @@ private:
void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);
void mangleCXXDtorType(CXXDtorType T);
void mangleQualifiers(Qualifiers Quals, bool IsMember);
- void manglePointerQualifiers(Qualifiers Quals);
+ void mangleRefQualifier(RefQualifierKind RefQualifier);
+ void manglePointerCVQualifiers(Qualifiers Quals);
+ void manglePointerExtQualifiers(Qualifiers Quals, const Type *PointeeType);
void mangleUnscopedTemplateName(const TemplateDecl *ND);
- void mangleTemplateInstantiationName(const TemplateDecl *TD,
- const TemplateArgumentList &TemplateArgs);
+ void
+ mangleTemplateInstantiationName(const TemplateDecl *TD,
+ const TemplateArgumentList &TemplateArgs);
void mangleObjCMethodName(const ObjCMethodDecl *MD);
- void mangleLocalName(const FunctionDecl *FD);
void mangleArgumentType(QualType T, SourceRange Range);
@@ -157,7 +267,7 @@ private:
#undef ABSTRACT_TYPE
#undef NON_CANONICAL_TYPE
#undef TYPE
-
+
void mangleType(const TagDecl *TD);
void mangleDecayedArrayType(const ArrayType *T);
void mangleArrayType(const ArrayType *T);
@@ -171,47 +281,6 @@ private:
const TemplateArgumentList &TemplateArgs);
void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA);
};
-
-/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
-/// Microsoft Visual C++ ABI.
-class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
-public:
- MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
- : MicrosoftMangleContext(Context, Diags) {}
- virtual bool shouldMangleCXXName(const NamedDecl *D);
- virtual void mangleCXXName(const NamedDecl *D, raw_ostream &Out);
- virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
- uint64_t OffsetInVFTable,
- raw_ostream &);
- virtual void mangleThunk(const CXXMethodDecl *MD,
- const ThunkInfo &Thunk,
- raw_ostream &);
- virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
- const ThisAdjustment &ThisAdjustment,
- raw_ostream &);
- virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out);
- virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out);
- virtual void mangleCXXRTTI(QualType T, raw_ostream &);
- virtual void mangleCXXRTTIName(QualType T, raw_ostream &);
- virtual void mangleTypeName(QualType T, raw_ostream &);
- virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
- raw_ostream &);
- virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
- raw_ostream &);
- virtual void mangleReferenceTemporary(const VarDecl *, raw_ostream &);
- virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out);
- virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
- virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
- raw_ostream &Out);
-
-private:
- void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
-};
-
}
bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
@@ -267,8 +336,14 @@ bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
return true;
}
-void MicrosoftCXXNameMangler::mangle(const NamedDecl *D,
- StringRef Prefix) {
+bool
+MicrosoftMangleContextImpl::shouldMangleStringLiteral(const StringLiteral *SL) {
+ return SL->isAscii() || SL->isWide();
+ // TODO: This needs to be updated when MSVC gains support for Unicode
+ // literals.
+}
+
+void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
// MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
// Therefore it's really important that we don't decorate the
// name with leading underscores or leading/trailing at signs. So, by
@@ -286,10 +361,9 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D,
// TODO: Fields? Can MSVC even mangle them?
// Issue a diagnostic for now.
DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle this declaration yet");
- Diags.Report(D->getLocation(), DiagID)
- << D->getSourceRange();
+ unsigned DiagID = Diags.getCustomDiagID(
+ DiagnosticsEngine::Error, "cannot mangle this declaration yet");
+ Diags.Report(D->getLocation(), DiagID) << D->getSourceRange();
}
}
@@ -324,7 +398,7 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
// ::= 2 # public static member
// ::= 3 # global
// ::= 4 # static local
-
+
// The first character in the encoding (after the name) is the storage class.
if (VD->isStaticDataMember()) {
// If it's a static member, it also encodes the access level.
@@ -344,13 +418,13 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
// ::= <type> <pointee-cvr-qualifiers> # pointers, references
// Pointers and references are odd. The type of 'int * const foo;' gets
// mangled as 'QAHA' instead of 'PAHB', for example.
- TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc();
- QualType Ty = TL.getType();
+ SourceRange SR = VD->getSourceRange();
+ QualType Ty = VD->getType();
if (Ty->isPointerType() || Ty->isReferenceType() ||
Ty->isMemberPointerType()) {
- mangleType(Ty, TL.getSourceRange(), QMM_Drop);
- if (PointersAre64Bit)
- Out << 'E';
+ mangleType(Ty, SR, QMM_Drop);
+ manglePointerExtQualifiers(
+ Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), nullptr);
if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()) {
mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);
// Member pointers are suffixed with a back reference to the member
@@ -366,25 +440,137 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
else
mangleQualifiers(Ty.getQualifiers(), false);
} else {
- mangleType(Ty, TL.getSourceRange(), QMM_Drop);
+ mangleType(Ty, SR, QMM_Drop);
mangleQualifiers(Ty.getLocalQualifiers(), false);
}
}
+void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD,
+ const ValueDecl *VD) {
+ // <member-data-pointer> ::= <integer-literal>
+ // ::= $F <number> <number>
+ // ::= $G <number> <number> <number>
+
+ int64_t FieldOffset;
+ int64_t VBTableOffset;
+ MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
+ if (VD) {
+ FieldOffset = getASTContext().getFieldOffset(VD);
+ assert(FieldOffset % getASTContext().getCharWidth() == 0 &&
+ "cannot take address of bitfield");
+ FieldOffset /= getASTContext().getCharWidth();
+
+ VBTableOffset = 0;
+ } else {
+ FieldOffset = RD->nullFieldOffsetIsZero() ? 0 : -1;
+
+ VBTableOffset = -1;
+ }
+
+ char Code = '\0';
+ switch (IM) {
+ case MSInheritanceAttr::Keyword_single_inheritance: Code = '0'; break;
+ case MSInheritanceAttr::Keyword_multiple_inheritance: Code = '0'; break;
+ case MSInheritanceAttr::Keyword_virtual_inheritance: Code = 'F'; break;
+ case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'G'; break;
+ }
+
+ Out << '$' << Code;
+
+ mangleNumber(FieldOffset);
+
+ // The C++ standard doesn't allow base-to-derived member pointer conversions
+ // in template parameter contexts, so the vbptr offset of data member pointers
+ // is always zero.
+ if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
+ mangleNumber(0);
+ if (MSInheritanceAttr::hasVBTableOffsetField(IM))
+ mangleNumber(VBTableOffset);
+}
+
+void
+MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
+ const CXXMethodDecl *MD) {
+ // <member-function-pointer> ::= $1? <name>
+ // ::= $H? <name> <number>
+ // ::= $I? <name> <number> <number>
+ // ::= $J? <name> <number> <number> <number>
+
+ MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
+
+ char Code = '\0';
+ switch (IM) {
+ case MSInheritanceAttr::Keyword_single_inheritance: Code = '1'; break;
+ case MSInheritanceAttr::Keyword_multiple_inheritance: Code = 'H'; break;
+ case MSInheritanceAttr::Keyword_virtual_inheritance: Code = 'I'; break;
+ case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'J'; break;
+ }
+
+ // If non-virtual, mangle the name. If virtual, mangle as a virtual memptr
+ // thunk.
+ uint64_t NVOffset = 0;
+ uint64_t VBTableOffset = 0;
+ uint64_t VBPtrOffset = 0;
+ if (MD) {
+ Out << '$' << Code << '?';
+ if (MD->isVirtual()) {
+ MicrosoftVTableContext *VTContext =
+ cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
+ const MicrosoftVTableContext::MethodVFTableLocation &ML =
+ VTContext->getMethodVFTableLocation(GlobalDecl(MD));
+ mangleVirtualMemPtrThunk(MD, ML);
+ NVOffset = ML.VFPtrOffset.getQuantity();
+ VBTableOffset = ML.VBTableIndex * 4;
+ if (ML.VBase) {
+ const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
+ VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
+ }
+ } else {
+ mangleName(MD);
+ mangleFunctionEncoding(MD);
+ }
+ } else {
+ // Null single inheritance member functions are encoded as a simple nullptr.
+ if (IM == MSInheritanceAttr::Keyword_single_inheritance) {
+ Out << "$0A@";
+ return;
+ }
+ if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance)
+ VBTableOffset = -1;
+ Out << '$' << Code;
+ }
+
+ if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM))
+ mangleNumber(NVOffset);
+ if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
+ mangleNumber(VBPtrOffset);
+ if (MSInheritanceAttr::hasVBTableOffsetField(IM))
+ mangleNumber(VBTableOffset);
+}
+
+void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
+ const CXXMethodDecl *MD,
+ const MicrosoftVTableContext::MethodVFTableLocation &ML) {
+ // Get the vftable offset.
+ CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
+ getASTContext().getTargetInfo().getPointerWidth(0));
+ uint64_t OffsetInVFTable = ML.Index * PointerWidth.getQuantity();
+
+ Out << "?_9";
+ mangleName(MD->getParent());
+ Out << "$B";
+ mangleNumber(OffsetInVFTable);
+ Out << 'A';
+ Out << (PointersAre64Bit ? 'A' : 'E');
+}
+
void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
// <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
- const DeclContext *DC = ND->getDeclContext();
// Always start with the unqualified name.
- mangleUnqualifiedName(ND);
-
- // If this is an extern variable declared locally, the relevant DeclContext
- // is that of the containing namespace, or the translation unit.
- if (isa<FunctionDecl>(DC) && ND->hasLinkage())
- while (!DC->isNamespace() && !DC->isTranslationUnit())
- DC = DC->getParent();
+ mangleUnqualifiedName(ND);
- manglePostfix(DC);
+ mangleNestedName(ND);
// Terminate the whole name with an '@'.
Out << '@';
@@ -412,8 +598,8 @@ void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
// in the range of ASCII characters 'A' to 'P'.
// The number 0x123450 would be encoded as 'BCDEFA'
char EncodedNumberBuffer[sizeof(uint64_t) * 2];
- llvm::MutableArrayRef<char> BufferRef(EncodedNumberBuffer);
- llvm::MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
+ MutableArrayRef<char> BufferRef(EncodedNumberBuffer);
+ MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
for (; Value != 0; Value >>= 4)
*I++ = 'A' + (Value & 0xf);
Out.write(I.base(), I - BufferRef.rbegin());
@@ -424,7 +610,7 @@ void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
static const TemplateDecl *
isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
// Check if we have a function template.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
TemplateArgs = FD->getTemplateSpecializationArgs();
return TD;
@@ -433,24 +619,30 @@ isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
// Check if we have a class template.
if (const ClassTemplateSpecializationDecl *Spec =
- dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
+ dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
+ TemplateArgs = &Spec->getTemplateArgs();
+ return Spec->getSpecializedTemplate();
+ }
+
+ // Check if we have a variable template.
+ if (const VarTemplateSpecializationDecl *Spec =
+ dyn_cast<VarTemplateSpecializationDecl>(ND)) {
TemplateArgs = &Spec->getTemplateArgs();
return Spec->getSpecializedTemplate();
}
- return 0;
+ return nullptr;
}
-void
-MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
- DeclarationName Name) {
+void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
+ DeclarationName Name) {
// <unqualified-name> ::= <operator-name>
// ::= <ctor-dtor-name>
// ::= <source-name>
// ::= <template-name>
// Check if we have a template.
- const TemplateArgumentList *TemplateArgs = 0;
+ const TemplateArgumentList *TemplateArgs = nullptr;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
// Function templates aren't considered for name back referencing. This
// makes sense since function templates aren't likely to occur multiple
@@ -458,10 +650,10 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// FIXME: Test alias template mangling with MSVC 2013.
if (!isa<ClassTemplateDecl>(TD)) {
mangleTemplateInstantiationName(TD, *TemplateArgs);
+ Out << '@';
return;
}
- // We have a class template.
// Here comes the tricky thing: if we need to mangle something like
// void foo(A::X<Y>, B::X<Y>),
// the X<Y> part is aliased. However, if you need to mangle
@@ -473,30 +665,17 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// type [ -> template-parameters]
// \-> namespace[s]
// What we do is we create a new mangler, mangle the same type (without
- // a namespace suffix) using the extra mangler with back references
- // disabled (to avoid infinite recursion) and then use the mangled type
- // name as a key to check the mangling of different types for aliasing.
-
- std::string BackReferenceKey;
- BackRefMap::iterator Found;
- if (UseNameBackReferences) {
- llvm::raw_string_ostream Stream(BackReferenceKey);
- MicrosoftCXXNameMangler Extra(Context, Stream);
- Extra.disableBackReferences();
- Extra.mangleUnqualifiedName(ND, Name);
- Stream.flush();
-
- Found = NameBackReferences.find(BackReferenceKey);
- }
- if (!UseNameBackReferences || Found == NameBackReferences.end()) {
- mangleTemplateInstantiationName(TD, *TemplateArgs);
- if (UseNameBackReferences && NameBackReferences.size() < 10) {
- size_t Size = NameBackReferences.size();
- NameBackReferences[BackReferenceKey] = Size;
- }
- } else {
- Out << Found->second;
- }
+ // a namespace suffix) to a string using the extra mangler and then use
+ // the mangled type name as a key to check the mangling of different types
+ // for aliasing.
+
+ llvm::SmallString<64> TemplateMangling;
+ llvm::raw_svector_ostream Stream(TemplateMangling);
+ MicrosoftCXXNameMangler Extra(Context, Stream);
+ Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
+ Stream.flush();
+
+ mangleSourceName(TemplateMangling);
return;
}
@@ -506,17 +685,31 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
mangleSourceName(II->getName());
break;
}
-
+
// Otherwise, an anonymous entity. We must have a declaration.
assert(ND && "mangling empty name without declaration");
-
+
if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
if (NS->isAnonymousNamespace()) {
Out << "?A@";
break;
}
}
-
+
+ if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+ // We must have an anonymous union or struct declaration.
+ const CXXRecordDecl *RD = VD->getType()->getAsCXXRecordDecl();
+ assert(RD && "expected variable decl to have a record type");
+ // Anonymous types with no tag or typedef get the name of their
+ // declarator mangled in. If they have no declarator, number them with
+ // a $S prefix.
+ llvm::SmallString<64> Name("$S");
+ // Get a unique id for the anonymous struct.
+ Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
+ mangleSourceName(Name.str());
+ break;
+ }
+
// We must have an anonymous struct.
const TagDecl *TD = cast<TagDecl>(ND);
if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
@@ -528,26 +721,43 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
break;
}
+ if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
+ if (Record->isLambda()) {
+ llvm::SmallString<10> Name("<lambda_");
+ unsigned LambdaId;
+ if (Record->getLambdaManglingNumber())
+ LambdaId = Record->getLambdaManglingNumber();
+ else
+ LambdaId = Context.getLambdaId(Record);
+
+ Name += llvm::utostr(LambdaId);
+ Name += ">";
+
+ mangleSourceName(Name);
+ break;
+ }
+ }
+
+ llvm::SmallString<64> Name("<unnamed-type-");
if (TD->hasDeclaratorForAnonDecl()) {
// Anonymous types with no tag or typedef get the name of their
- // declarator mangled in.
- llvm::SmallString<64> Name("<unnamed-type-");
+ // declarator mangled in if they have one.
Name += TD->getDeclaratorForAnonDecl()->getName();
- Name += ">";
- mangleSourceName(Name.str());
} else {
- // Anonymous types with no tag, no typedef, or declarator get
- // '<unnamed-tag>'.
- mangleSourceName("<unnamed-tag>");
+ // Otherwise, number the types using a $S prefix.
+ Name += "$S";
+ Name += llvm::utostr(Context.getAnonymousStructId(TD));
}
+ Name += ">";
+ mangleSourceName(Name.str());
break;
}
-
+
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
llvm_unreachable("Can't mangle Objective-C selector names here!");
-
+
case DeclarationName::CXXConstructorName:
if (ND == Structor) {
assert(StructorType == Ctor_Complete &&
@@ -555,7 +765,7 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
}
Out << "?0";
break;
-
+
case DeclarationName::CXXDestructorName:
if (ND == Structor)
// If the named decl is the C++ destructor we're mangling,
@@ -566,70 +776,69 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// class with a destructor is declared within a destructor.
mangleCXXDtorType(Dtor_Base);
break;
-
+
case DeclarationName::CXXConversionFunctionName:
// <operator-name> ::= ?B # (cast)
// The target type is encoded as the return type.
Out << "?B";
break;
-
+
case DeclarationName::CXXOperatorName:
mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation());
break;
-
+
case DeclarationName::CXXLiteralOperatorName: {
- // FIXME: Was this added in VS2010? Does MS even know how to mangle this?
- DiagnosticsEngine Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle this literal operator yet");
- Diags.Report(ND->getLocation(), DiagID);
+ Out << "?__K";
+ mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
break;
}
-
+
case DeclarationName::CXXUsingDirective:
llvm_unreachable("Can't mangle a using directive name!");
}
}
-void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC,
- bool NoFunction) {
+void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
// <postfix> ::= <unqualified-name> [<postfix>]
// ::= <substitution> [<postfix>]
-
- if (!DC) return;
-
- while (isa<LinkageSpecDecl>(DC))
- DC = DC->getParent();
-
- if (DC->isTranslationUnit())
+ if (isLambda(ND))
return;
- if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
- DiagnosticsEngine Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle a local inside this block yet");
- Diags.Report(BD->getLocation(), DiagID);
+ const DeclContext *DC = ND->getDeclContext();
- // FIXME: This is completely, utterly, wrong; see ItaniumMangle
- // for how this should be done.
- Out << "__block_invoke" << Context.getBlockId(BD, false);
- Out << '@';
- return manglePostfix(DC->getParent(), NoFunction);
- } else if (isa<CapturedDecl>(DC)) {
- // Skip CapturedDecl context.
- manglePostfix(DC->getParent(), NoFunction);
- return;
- }
+ while (!DC->isTranslationUnit()) {
+ if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
+ unsigned Disc;
+ if (Context.getNextDiscriminator(ND, Disc)) {
+ Out << '?';
+ mangleNumber(Disc);
+ Out << '?';
+ }
+ }
- if (NoFunction && (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)))
- return;
- else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
- mangleObjCMethodName(Method);
- else if (const FunctionDecl *Func = dyn_cast<FunctionDecl>(DC))
- mangleLocalName(Func);
- else {
- mangleUnqualifiedName(cast<NamedDecl>(DC));
- manglePostfix(DC->getParent(), NoFunction);
+ if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
+ DiagnosticsEngine &Diags = Context.getDiags();
+ unsigned DiagID =
+ Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "cannot mangle a local inside this block yet");
+ Diags.Report(BD->getLocation(), DiagID);
+
+ // FIXME: This is completely, utterly, wrong; see ItaniumMangle
+ // for how this should be done.
+ Out << "__block_invoke" << Context.getBlockId(BD, false);
+ Out << '@';
+ continue;
+ } else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
+ mangleObjCMethodName(Method);
+ } else if (isa<NamedDecl>(DC)) {
+ ND = cast<NamedDecl>(DC);
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+ mangle(FD, "?");
+ break;
+ } else
+ mangleUnqualifiedName(ND);
+ }
+ DC = DC->getParent();
}
}
@@ -768,7 +977,7 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
case OO_Array_New: Out << "?_U"; break;
// <operator-name> ::= ?_V # delete[]
case OO_Array_Delete: Out << "?_V"; break;
-
+
case OO_Conditional: {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
@@ -776,7 +985,7 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
Diags.Report(Loc, DiagID);
break;
}
-
+
case OO_None:
case NUM_OVERLOADED_OPERATORS:
llvm_unreachable("Not an overloaded operator");
@@ -786,14 +995,19 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
// <source name> ::= <identifier> @
BackRefMap::iterator Found;
- if (UseNameBackReferences)
+ if (NameBackReferences.size() < 10) {
+ size_t Size = NameBackReferences.size();
+ bool Inserted;
+ std::tie(Found, Inserted) =
+ NameBackReferences.insert(std::make_pair(Name, Size));
+ if (Inserted)
+ Found = NameBackReferences.end();
+ } else {
Found = NameBackReferences.find(Name);
- if (!UseNameBackReferences || Found == NameBackReferences.end()) {
+ }
+
+ if (Found == NameBackReferences.end()) {
Out << Name << '@';
- if (UseNameBackReferences && NameBackReferences.size() < 10) {
- size_t Size = NameBackReferences.size();
- NameBackReferences[Name] = Size;
- }
} else {
Out << Found->second;
}
@@ -803,47 +1017,8 @@ void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
Context.mangleObjCMethodName(MD, Out);
}
-// Find out how many function decls live above this one and return an integer
-// suitable for use as the number in a numbered anonymous scope.
-// TODO: Memoize.
-static unsigned getLocalNestingLevel(const FunctionDecl *FD) {
- const DeclContext *DC = FD->getParent();
- int level = 1;
-
- while (DC && !DC->isTranslationUnit()) {
- if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) level++;
- DC = DC->getParent();
- }
-
- return 2*level;
-}
-
-void MicrosoftCXXNameMangler::mangleLocalName(const FunctionDecl *FD) {
- // <nested-name> ::= <numbered-anonymous-scope> ? <mangled-name>
- // <numbered-anonymous-scope> ::= ? <number>
- // Even though the name is rendered in reverse order (e.g.
- // A::B::C is rendered as C@B@A), VC numbers the scopes from outermost to
- // innermost. So a method bar in class C local to function foo gets mangled
- // as something like:
- // ?bar@C@?1??foo@@YAXXZ@QAEXXZ
- // This is more apparent when you have a type nested inside a method of a
- // type nested inside a function. A method baz in class D local to method
- // bar of class C local to function foo gets mangled as:
- // ?baz@D@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ
- // This scheme is general enough to support GCC-style nested
- // functions. You could have a method baz of class C inside a function bar
- // inside a function foo, like so:
- // ?baz@C@?3??bar@?1??foo@@YAXXZ@YAXXZ@QAEXXZ
- unsigned NestLevel = getLocalNestingLevel(FD);
- Out << '?';
- mangleNumber(NestLevel);
- Out << '?';
- mangle(FD, "?");
-}
-
void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
- const TemplateDecl *TD,
- const TemplateArgumentList &TemplateArgs) {
+ const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
// <template-name> ::= <unscoped-template-name> <template-args>
// ::= <substitution>
// Always start with the unqualified name.
@@ -869,9 +1044,8 @@ MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) {
mangleUnqualifiedName(TD);
}
-void
-MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,
- bool IsBoolean) {
+void MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,
+ bool IsBoolean) {
// <integer-literal> ::= $0 <number>
Out << "$0";
// Make sure booleans are encoded as 0/1.
@@ -881,8 +1055,7 @@ MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,
mangleNumber(Value.getSExtValue());
}
-void
-MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
+void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
// See if this is a constant expression.
llvm::APSInt Value;
if (E->isIntegerConstantExpr(Value, Context.getASTContext())) {
@@ -890,7 +1063,10 @@ MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
return;
}
- const CXXUuidofExpr *UE = 0;
+ // Look through no-op casts like template parameter substitutions.
+ E = E->IgnoreParenNoopCasts(Context.getASTContext());
+
+ const CXXUuidofExpr *UE = nullptr;
if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
if (UO->getOpcode() == UO_AddrOf)
UE = dyn_cast<CXXUuidofExpr>(UO->getSubExpr());
@@ -919,26 +1095,30 @@ MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
// As bad as this diagnostic is, it's better than crashing.
DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot yet mangle expression type %0");
- Diags.Report(E->getExprLoc(), DiagID)
- << E->getStmtClassName() << E->getSourceRange();
+ unsigned DiagID = Diags.getCustomDiagID(
+ DiagnosticsEngine::Error, "cannot yet mangle expression type %0");
+ Diags.Report(E->getExprLoc(), DiagID) << E->getStmtClassName()
+ << E->getSourceRange();
}
-void
-MicrosoftCXXNameMangler::mangleTemplateArgs(const TemplateDecl *TD,
- const TemplateArgumentList &TemplateArgs) {
- // <template-args> ::= {<type> | <integer-literal>}+ @
- unsigned NumTemplateArgs = TemplateArgs.size();
- for (unsigned i = 0; i < NumTemplateArgs; ++i) {
- const TemplateArgument &TA = TemplateArgs[i];
+void MicrosoftCXXNameMangler::mangleTemplateArgs(
+ const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
+ // <template-args> ::= <template-arg>+
+ for (const TemplateArgument &TA : TemplateArgs.asArray())
mangleTemplateArg(TD, TA);
- }
- Out << '@';
}
void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
const TemplateArgument &TA) {
+ // <template-arg> ::= <type>
+ // ::= <integer-literal>
+ // ::= <member-data-pointer>
+ // ::= <member-function-pointer>
+ // ::= $E? <name> <type-encoding>
+ // ::= $1? <name> <type-encoding>
+ // ::= $0A@
+ // ::= <template-args>
+
switch (TA.getKind()) {
case TemplateArgument::Null:
llvm_unreachable("Can't mangle null template arguments!");
@@ -951,25 +1131,54 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
}
case TemplateArgument::Declaration: {
const NamedDecl *ND = cast<NamedDecl>(TA.getAsDecl());
- mangle(ND, TA.isDeclForReferenceParam() ? "$E?" : "$1?");
+ if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
+ mangleMemberDataPointer(
+ cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),
+ cast<ValueDecl>(ND));
+ } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+ const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
+ if (MD && MD->isInstance())
+ mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD);
+ else
+ mangle(FD, "$1?");
+ } else {
+ mangle(ND, TA.isDeclForReferenceParam() ? "$E?" : "$1?");
+ }
break;
}
case TemplateArgument::Integral:
mangleIntegerLiteral(TA.getAsIntegral(),
TA.getIntegralType()->isBooleanType());
break;
- case TemplateArgument::NullPtr:
+ case TemplateArgument::NullPtr: {
+ QualType T = TA.getNullPtrType();
+ if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
+ const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ if (MPT->isMemberFunctionPointerType() && isa<ClassTemplateDecl>(TD)) {
+ mangleMemberFunctionPointer(RD, nullptr);
+ return;
+ }
+ if (MPT->isMemberDataPointer()) {
+ mangleMemberDataPointer(RD, nullptr);
+ return;
+ }
+ }
Out << "$0A@";
break;
+ }
case TemplateArgument::Expression:
mangleExpression(TA.getAsExpr());
break;
- case TemplateArgument::Pack:
- // Unlike Itanium, there is no character code to indicate an argument pack.
- for (TemplateArgument::pack_iterator I = TA.pack_begin(), E = TA.pack_end();
- I != E; ++I)
- mangleTemplateArg(TD, *I);
+ case TemplateArgument::Pack: {
+ ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
+ if (TemplateArgs.empty()) {
+ Out << "$S";
+ } else {
+ for (const TemplateArgument &PA : TemplateArgs)
+ mangleTemplateArg(TD, PA);
+ }
break;
+ }
case TemplateArgument::Template:
mangleType(cast<TagDecl>(
TA.getAsTemplate().getAsTemplateDecl()->getTemplatedDecl()));
@@ -1059,13 +1268,43 @@ void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
// FIXME: For now, just drop all extension qualifiers on the floor.
}
-void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals) {
- // <pointer-cvr-qualifiers> ::= P # no qualifiers
- // ::= Q # const
- // ::= R # volatile
- // ::= S # const volatile
+void
+MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
+ // <ref-qualifier> ::= G # lvalue reference
+ // ::= H # rvalue-reference
+ switch (RefQualifier) {
+ case RQ_None:
+ break;
+
+ case RQ_LValue:
+ Out << 'G';
+ break;
+
+ case RQ_RValue:
+ Out << 'H';
+ break;
+ }
+}
+
+void
+MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
+ const Type *PointeeType) {
+ bool HasRestrict = Quals.hasRestrict();
+ if (PointersAre64Bit && (!PointeeType || !PointeeType->isFunctionType()))
+ Out << 'E';
+
+ if (HasRestrict)
+ Out << 'I';
+}
+
+void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
+ // <pointer-cv-qualifiers> ::= P # no qualifiers
+ // ::= Q # const
+ // ::= R # volatile
+ // ::= S # const volatile
bool HasConst = Quals.hasConst(),
HasVolatile = Quals.hasVolatile();
+
if (HasConst && HasVolatile) {
Out << 'S';
} else if (HasVolatile) {
@@ -1165,8 +1404,10 @@ void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
}
// We have to mangle these now, while we still have enough information.
- if (IsPointer)
- manglePointerQualifiers(Quals);
+ if (IsPointer) {
+ manglePointerCVQualifiers(Quals);
+ manglePointerExtQualifiers(Quals, T->getPointeeType().getTypePtr());
+ }
const Type *ty = T.getTypePtr();
switch (ty->getTypeClass()) {
@@ -1254,7 +1495,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T,
case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break;
case BuiltinType::OCLSampler: Out << "PAUocl_sampler@@"; break;
case BuiltinType::OCLEvent: Out << "PAUocl_event@@"; break;
-
+
case BuiltinType::NullPtr: Out << "$$T"; break;
case BuiltinType::Char16:
@@ -1306,9 +1547,10 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
// If this is a C++ instance method, mangle the CVR qualifiers for the
// this pointer.
if (IsInstMethod) {
- if (PointersAre64Bit)
- Out << 'E';
- mangleQualifiers(Qualifiers::fromCVRMask(Proto->getTypeQuals()), false);
+ Qualifiers Quals = Qualifiers::fromCVRMask(Proto->getTypeQuals());
+ manglePointerExtQualifiers(Quals, nullptr);
+ mangleRefQualifier(Proto->getRefQualifier());
+ mangleQualifiers(Quals, false);
}
mangleCallingConvention(T);
@@ -1327,23 +1569,30 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
}
Out << '@';
} else {
- QualType ResultType = Proto->getResultType();
- if (ResultType->isVoidType())
- ResultType = ResultType.getUnqualifiedType();
- mangleType(ResultType, Range, QMM_Result);
+ QualType ResultType = Proto->getReturnType();
+ if (const auto *AT =
+ dyn_cast_or_null<AutoType>(ResultType->getContainedAutoType())) {
+ Out << '?';
+ mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
+ Out << '?';
+ mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
+ Out << '@';
+ } else {
+ if (ResultType->isVoidType())
+ ResultType = ResultType.getUnqualifiedType();
+ mangleType(ResultType, Range, QMM_Result);
+ }
}
// <argument-list> ::= X # void
// ::= <type>+ @
// ::= <type>* Z # varargs
- if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
+ if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
Out << 'X';
} else {
// Happens for function pointer type arguments for example.
- for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
- ArgEnd = Proto->arg_type_end();
- Arg != ArgEnd; ++Arg)
- mangleArgumentType(*Arg, Range);
+ for (const QualType Arg : Proto->param_types())
+ mangleArgumentType(Arg, Range);
// <builtin-type> ::= Z # ellipsis
if (Proto->isVariadic())
Out << 'Z';
@@ -1465,7 +1714,7 @@ void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,
// <union-type> ::= T <name>
// <struct-type> ::= U <name>
// <class-type> ::= V <name>
-// <enum-type> ::= W <size> <name>
+// <enum-type> ::= W4 <name>
void MicrosoftCXXNameMangler::mangleType(const EnumType *T, SourceRange) {
mangleType(cast<TagType>(T)->getDecl());
}
@@ -1485,9 +1734,7 @@ void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
Out << 'V';
break;
case TTK_Enum:
- Out << 'W';
- Out << getASTContext().getTypeSizeInChars(
- cast<EnumDecl>(TD)->getIntegerType()).getQuantity();
+ Out << "W4";
break;
}
mangleName(TD);
@@ -1503,7 +1750,7 @@ void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {
// This isn't a recursive mangling, so now we have to do it all in this
// one call.
- manglePointerQualifiers(T->getElementType().getQualifiers());
+ manglePointerCVQualifiers(T->getElementType().getQualifiers());
mangleType(T->getElementType(), SourceRange());
}
void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,
@@ -1527,7 +1774,7 @@ void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {
SmallVector<llvm::APInt, 3> Dimensions;
for (;;) {
if (const ConstantArrayType *CAT =
- getASTContext().getAsConstantArrayType(ElementTy)) {
+ getASTContext().getAsConstantArrayType(ElementTy)) {
Dimensions.push_back(CAT->getSize());
ElementTy = CAT->getElementType();
} else if (ElementTy->isVariableArrayType()) {
@@ -1550,7 +1797,7 @@ void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {
<< DSAT->getBracketsRange();
return;
} else if (const IncompleteArrayType *IAT =
- getASTContext().getAsIncompleteArrayType(ElementTy)) {
+ getASTContext().getAsIncompleteArrayType(ElementTy)) {
Dimensions.push_back(llvm::APInt(32, 0));
ElementTy = IAT->getElementType();
}
@@ -1559,8 +1806,8 @@ void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {
Out << 'Y';
// <dimension-count> ::= <number> # number of extra dimensions
mangleNumber(Dimensions.size());
- for (unsigned Dim = 0; Dim < Dimensions.size(); ++Dim)
- mangleNumber(Dimensions[Dim].getLimitedValue());
+ for (const llvm::APInt &Dimension : Dimensions)
+ mangleNumber(Dimension.getLimitedValue());
mangleType(ElementTy, SourceRange(), QMM_Escape);
}
@@ -1573,10 +1820,8 @@ void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
Out << '8';
mangleName(T->getClass()->castAs<RecordType>()->getDecl());
- mangleFunctionType(FPT, 0, true);
+ mangleFunctionType(FPT, nullptr, true);
} else {
- if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
- Out << 'E';
mangleQualifiers(PointeeType.getQualifiers(), true);
mangleName(T->getClass()->castAs<RecordType>()->getDecl());
mangleType(PointeeType, Range, QMM_Drop);
@@ -1604,42 +1849,37 @@ void MicrosoftCXXNameMangler::mangleType(
// <type> ::= <pointer-type>
// <pointer-type> ::= E? <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
-// # the E is required for 64-bit non static pointers
+// # the E is required for 64-bit non-static pointers
void MicrosoftCXXNameMangler::mangleType(const PointerType *T,
SourceRange Range) {
QualType PointeeTy = T->getPointeeType();
- if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
- Out << 'E';
mangleType(PointeeTy, Range);
}
void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
SourceRange Range) {
// Object pointers never have qualifiers.
Out << 'A';
- if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
- Out << 'E';
+ manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr());
mangleType(T->getPointeeType(), Range);
}
// <type> ::= <reference-type>
// <reference-type> ::= A E? <cvr-qualifiers> <type>
-// # the E is required for 64-bit non static lvalue references
+// # the E is required for 64-bit non-static lvalue references
void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,
SourceRange Range) {
Out << 'A';
- if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
- Out << 'E';
+ manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr());
mangleType(T->getPointeeType(), Range);
}
// <type> ::= <r-value-reference-type>
// <r-value-reference-type> ::= $$Q E? <cvr-qualifiers> <type>
-// # the E is required for 64-bit non static rvalue references
+// # the E is required for 64-bit non-static rvalue references
void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,
SourceRange Range) {
Out << "$$Q";
- if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
- Out << 'E';
+ manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr());
mangleType(T->getPointeeType(), Range);
}
@@ -1804,6 +2044,8 @@ void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T,
}
void MicrosoftCXXNameMangler::mangleType(const AutoType *T, SourceRange Range) {
+ assert(T->getDeducedType().isNull() && "expecting a dependent type!");
+
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
"cannot mangle this 'auto' type yet");
@@ -1923,17 +2165,17 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD,
}
}
-void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
- const CXXMethodDecl *MD, uint64_t OffsetInVFTable, raw_ostream &Out) {
- bool Is64Bit = getASTContext().getTargetInfo().getPointerWidth(0) == 64;
+void
+MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
+ raw_ostream &Out) {
+ MicrosoftVTableContext *VTContext =
+ cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
+ const MicrosoftVTableContext::MethodVFTableLocation &ML =
+ VTContext->getMethodVFTableLocation(GlobalDecl(MD));
MicrosoftCXXNameMangler Mangler(*this, Out);
- Mangler.getStream() << "\01??_9";
- Mangler.mangleName(MD->getParent());
- Mangler.getStream() << "$B";
- Mangler.mangleNumber(OffsetInVFTable);
- Mangler.getStream() << "A";
- Mangler.getStream() << (Is64Bit ? "A" : "E");
+ Mangler.getStream() << "\01?";
+ Mangler.mangleVirtualMemPtrThunk(MD, ML);
}
void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
@@ -1944,7 +2186,8 @@ void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
Mangler.mangleName(MD);
mangleThunkThisAdjustment(MD, Thunk.This, Mangler, Out);
if (!Thunk.Return.isEmpty())
- assert(Thunk.Method != 0 && "Thunk info should hold the overridee decl");
+ assert(Thunk.Method != nullptr &&
+ "Thunk info should hold the overridee decl");
const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;
Mangler.mangleFunctionType(
@@ -1976,11 +2219,8 @@ void MicrosoftMangleContextImpl::mangleCXXVFTable(
Mangler.getStream() << "\01??_7";
Mangler.mangleName(Derived);
Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
- for (ArrayRef<const CXXRecordDecl *>::iterator I = BasePath.begin(),
- E = BasePath.end();
- I != E; ++I) {
- Mangler.mangleName(*I);
- }
+ for (const CXXRecordDecl *RD : BasePath)
+ Mangler.mangleName(RD);
Mangler.getStream() << '@';
}
@@ -1995,28 +2235,68 @@ void MicrosoftMangleContextImpl::mangleCXXVBTable(
Mangler.getStream() << "\01??_8";
Mangler.mangleName(Derived);
Mangler.getStream() << "7B"; // '7' for vbtable, 'B' for const.
- for (ArrayRef<const CXXRecordDecl *>::iterator I = BasePath.begin(),
- E = BasePath.end();
- I != E; ++I) {
- Mangler.mangleName(*I);
- }
+ for (const CXXRecordDecl *RD : BasePath)
+ Mangler.mangleName(RD);
Mangler.getStream() << '@';
}
-void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &) {
- // FIXME: Give a location...
- unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle RTTI descriptors for type %0 yet");
- getDiags().Report(DiagID)
- << T.getBaseTypeIdentifier();
+void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
+ MicrosoftCXXNameMangler Mangler(*this, Out);
+ Mangler.getStream() << "\01??_R0";
+ Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
+ Mangler.getStream() << "@8";
}
-void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, raw_ostream &) {
- // FIXME: Give a location...
- unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle the name of type %0 into RTTI descriptors yet");
- getDiags().Report(DiagID)
- << T.getBaseTypeIdentifier();
+void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T,
+ raw_ostream &Out) {
+ MicrosoftCXXNameMangler Mangler(*this, Out);
+ Mangler.getStream() << '.';
+ Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
+}
+
+void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
+ const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
+ uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
+ MicrosoftCXXNameMangler Mangler(*this, Out);
+ Mangler.getStream() << "\01??_R1";
+ Mangler.mangleNumber(NVOffset);
+ Mangler.mangleNumber(VBPtrOffset);
+ Mangler.mangleNumber(VBTableOffset);
+ Mangler.mangleNumber(Flags);
+ Mangler.mangleName(Derived);
+ Mangler.getStream() << "8";
+}
+
+void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
+ const CXXRecordDecl *Derived, raw_ostream &Out) {
+ MicrosoftCXXNameMangler Mangler(*this, Out);
+ Mangler.getStream() << "\01??_R2";
+ Mangler.mangleName(Derived);
+ Mangler.getStream() << "8";
+}
+
+void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
+ const CXXRecordDecl *Derived, raw_ostream &Out) {
+ MicrosoftCXXNameMangler Mangler(*this, Out);
+ Mangler.getStream() << "\01??_R3";
+ Mangler.mangleName(Derived);
+ Mangler.getStream() << "8";
+}
+
+void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
+ const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
+ raw_ostream &Out) {
+ // <mangled-name> ::= ?_R4 <class-name> <storage-class>
+ // <cvr-qualifiers> [<name>] @
+ // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
+ // is always '6' for vftables.
+ MicrosoftCXXNameMangler Mangler(*this, Out);
+ Mangler.getStream() << "\01??_R4";
+ Mangler.mangleName(Derived);
+ Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
+ for (const CXXRecordDecl *RD : BasePath)
+ Mangler.mangleName(RD);
+ Mangler.getStream() << '@';
}
void MicrosoftMangleContextImpl::mangleTypeName(QualType T, raw_ostream &Out) {
@@ -2042,6 +2322,7 @@ void MicrosoftMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D,
}
void MicrosoftMangleContextImpl::mangleReferenceTemporary(const VarDecl *VD,
+ unsigned,
raw_ostream &) {
unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
"cannot mangle this reference temporary yet");
@@ -2050,7 +2331,16 @@ void MicrosoftMangleContextImpl::mangleReferenceTemporary(const VarDecl *VD,
void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
raw_ostream &Out) {
- // <guard-name> ::= ?_B <postfix> @51
+ // TODO: This is not correct, especially with respect to MSVC2013. MSVC2013
+ // utilizes thread local variables to implement thread safe, re-entrant
+ // initialization for statics. They no longer differentiate between an
+ // externally visible and non-externally visible static with respect to
+ // mangling, they all get $TSS <number>.
+ //
+ // N.B. This means that they can get more than 32 static variable guards in a
+ // scope. It also means that they broke compatibility with their own ABI.
+
+ // <guard-name> ::= ?_B <postfix> @5 <scope-depth>
// ::= ?$S <guard-num> @ <postfix> @4IA
// The first mangling is what MSVC uses to guard static locals in inline
@@ -2064,8 +2354,17 @@ void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
bool Visible = VD->isExternallyVisible();
// <operator-name> ::= ?_B # local static guard
Mangler.getStream() << (Visible ? "\01??_B" : "\01?$S1@");
- Mangler.manglePostfix(VD->getDeclContext());
- Mangler.getStream() << (Visible ? "@51" : "@4IA");
+ unsigned ScopeDepth = 0;
+ if (Visible && !getNextDiscriminator(VD, ScopeDepth))
+ // If we do not have a discriminator and are emitting a guard variable for
+ // use at global scope, then mangling the nested name will not be enough to
+ // remove ambiguities.
+ Mangler.mangle(VD, "");
+ else
+ Mangler.mangleNestedName(VD);
+ Mangler.getStream() << (Visible ? "@5" : "@4IA");
+ if (ScopeDepth)
+ Mangler.mangleNumber(ScopeDepth);
}
void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,
@@ -2074,6 +2373,10 @@ void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,
MicrosoftCXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "\01??__" << CharCode;
Mangler.mangleName(D);
+ if (D->isStaticDataMember()) {
+ Mangler.mangleVariableEncoding(D);
+ Mangler.getStream() << '@';
+ }
// This is the function class mangling. These stubs are global, non-variadic,
// cdecl functions that return void and take no args.
Mangler.getStream() << "YAXXZ";
@@ -2092,6 +2395,172 @@ MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,
mangleInitFiniStub(D, Out, 'F');
}
+void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
+ raw_ostream &Out) {
+ // <char-type> ::= 0 # char
+ // ::= 1 # wchar_t
+ // ::= ??? # char16_t/char32_t will need a mangling too...
+ //
+ // <literal-length> ::= <non-negative integer> # the length of the literal
+ //
+ // <encoded-crc> ::= <hex digit>+ @ # crc of the literal including
+ // # null-terminator
+ //
+ // <encoded-string> ::= <simple character> # uninteresting character
+ // ::= '?$' <hex digit> <hex digit> # these two nibbles
+ // # encode the byte for the
+ // # character
+ // ::= '?' [a-z] # \xe1 - \xfa
+ // ::= '?' [A-Z] # \xc1 - \xda
+ // ::= '?' [0-9] # [,/\:. \n\t'-]
+ //
+ // <literal> ::= '??_C@_' <char-type> <literal-length> <encoded-crc>
+ // <encoded-string> '@'
+ MicrosoftCXXNameMangler Mangler(*this, Out);
+ Mangler.getStream() << "\01??_C@_";
+
+ // <char-type>: The "kind" of string literal is encoded into the mangled name.
+ // TODO: This needs to be updated when MSVC gains support for unicode
+ // literals.
+ if (SL->isAscii())
+ Mangler.getStream() << '0';
+ else if (SL->isWide())
+ Mangler.getStream() << '1';
+ else
+ llvm_unreachable("unexpected string literal kind!");
+
+ // <literal-length>: The next part of the mangled name consists of the length
+ // of the string.
+ // The StringLiteral does not consider the NUL terminator byte(s) but the
+ // mangling does.
+ // N.B. The length is in terms of bytes, not characters.
+ Mangler.mangleNumber(SL->getByteLength() + SL->getCharByteWidth());
+
+ // We will use the "Rocksoft^tm Model CRC Algorithm" to describe the
+ // properties of our CRC:
+ // Width : 32
+ // Poly : 04C11DB7
+ // Init : FFFFFFFF
+ // RefIn : True
+ // RefOut : True
+ // XorOut : 00000000
+ // Check : 340BC6D9
+ uint32_t CRC = 0xFFFFFFFFU;
+
+ auto UpdateCRC = [&CRC](char Byte) {
+ for (unsigned i = 0; i < 8; ++i) {
+ bool Bit = CRC & 0x80000000U;
+ if (Byte & (1U << i))
+ Bit = !Bit;
+ CRC <<= 1;
+ if (Bit)
+ CRC ^= 0x04C11DB7U;
+ }
+ };
+
+ auto GetLittleEndianByte = [&Mangler, &SL](unsigned Index) {
+ unsigned CharByteWidth = SL->getCharByteWidth();
+ uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
+ unsigned OffsetInCodeUnit = Index % CharByteWidth;
+ return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
+ };
+
+ auto GetBigEndianByte = [&Mangler, &SL](unsigned Index) {
+ unsigned CharByteWidth = SL->getCharByteWidth();
+ uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
+ unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
+ return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
+ };
+
+ // CRC all the bytes of the StringLiteral.
+ for (unsigned I = 0, E = SL->getByteLength(); I != E; ++I)
+ UpdateCRC(GetLittleEndianByte(I));
+
+ // The NUL terminator byte(s) were not present earlier,
+ // we need to manually process those bytes into the CRC.
+ for (unsigned NullTerminator = 0; NullTerminator < SL->getCharByteWidth();
+ ++NullTerminator)
+ UpdateCRC('\x00');
+
+ // The literature refers to the process of reversing the bits in the final CRC
+ // output as "reflection".
+ CRC = llvm::reverseBits(CRC);
+
+ // <encoded-crc>: The CRC is encoded utilizing the standard number mangling
+ // scheme.
+ Mangler.mangleNumber(CRC);
+
+ // <encoded-string>: The mangled name also contains the first 32 _characters_
+ // (including null-terminator bytes) of the StringLiteral.
+ // Each character is encoded by splitting them into bytes and then encoding
+ // the constituent bytes.
+ auto MangleByte = [&Mangler](char Byte) {
+ // There are five different manglings for characters:
+ // - [a-zA-Z0-9_$]: A one-to-one mapping.
+ // - ?[a-z]: The range from \xe1 to \xfa.
+ // - ?[A-Z]: The range from \xc1 to \xda.
+ // - ?[0-9]: The set of [,/\:. \n\t'-].
+ // - ?$XX: A fallback which maps nibbles.
+ if (isIdentifierBody(Byte, /*AllowDollar=*/true)) {
+ Mangler.getStream() << Byte;
+ } else if (isLetter(Byte & 0x7f)) {
+ Mangler.getStream() << '?' << static_cast<char>(Byte & 0x7f);
+ } else {
+ switch (Byte) {
+ case ',':
+ Mangler.getStream() << "?0";
+ break;
+ case '/':
+ Mangler.getStream() << "?1";
+ break;
+ case '\\':
+ Mangler.getStream() << "?2";
+ break;
+ case ':':
+ Mangler.getStream() << "?3";
+ break;
+ case '.':
+ Mangler.getStream() << "?4";
+ break;
+ case ' ':
+ Mangler.getStream() << "?5";
+ break;
+ case '\n':
+ Mangler.getStream() << "?6";
+ break;
+ case '\t':
+ Mangler.getStream() << "?7";
+ break;
+ case '\'':
+ Mangler.getStream() << "?8";
+ break;
+ case '-':
+ Mangler.getStream() << "?9";
+ break;
+ default:
+ Mangler.getStream() << "?$";
+ Mangler.getStream() << static_cast<char>('A' + ((Byte >> 4) & 0xf));
+ Mangler.getStream() << static_cast<char>('A' + (Byte & 0xf));
+ break;
+ }
+ }
+ };
+
+ // Enforce our 32 character max.
+ unsigned NumCharsToMangle = std::min(32U, SL->getLength());
+ for (unsigned I = 0, E = NumCharsToMangle * SL->getCharByteWidth(); I != E;
+ ++I)
+ MangleByte(GetBigEndianByte(I));
+
+ // Encode the NUL terminator if there is room.
+ if (NumCharsToMangle < 32)
+ for (unsigned NullTerminator = 0; NullTerminator < SL->getCharByteWidth();
+ ++NullTerminator)
+ MangleByte(0);
+
+ Mangler.getStream() << '@';
+}
+
MicrosoftMangleContext *
MicrosoftMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
return new MicrosoftMangleContextImpl(Context, Diags);
diff --git a/contrib/llvm/tools/clang/lib/AST/NSAPI.cpp b/contrib/llvm/tools/clang/lib/AST/NSAPI.cpp
index a862630..986b3b5 100644
--- a/contrib/llvm/tools/clang/lib/AST/NSAPI.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/NSAPI.cpp
@@ -14,9 +14,9 @@
using namespace clang;
NSAPI::NSAPI(ASTContext &ctx)
- : Ctx(ctx), ClassIds(), BOOLId(0), NSIntegerId(0), NSUIntegerId(0),
- NSASCIIStringEncodingId(0), NSUTF8StringEncodingId(0) {
-}
+ : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
+ NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
+ NSUTF8StringEncodingId(nullptr) {}
IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
static const char *ClassName[NumClassIds] = {
diff --git a/contrib/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp b/contrib/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp
index b03c4e0..1f041aa 100644
--- a/contrib/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/NestedNameSpecifier.cpp
@@ -30,7 +30,7 @@ NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
llvm::FoldingSetNodeID ID;
Mockup.Profile(ID);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
NestedNameSpecifier *NNS
= Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
if (!NNS) {
@@ -61,7 +61,8 @@ NestedNameSpecifier::Create(const ASTContext &Context,
const NamespaceDecl *NS) {
assert(NS && "Namespace cannot be NULL");
assert((!Prefix ||
- (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) &&
+ (Prefix->getAsType() == nullptr &&
+ Prefix->getAsIdentifier() == nullptr)) &&
"Broken nested name specifier");
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(Prefix);
@@ -76,7 +77,8 @@ NestedNameSpecifier::Create(const ASTContext &Context,
NamespaceAliasDecl *Alias) {
assert(Alias && "Namespace alias cannot be NULL");
assert((!Prefix ||
- (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) &&
+ (Prefix->getAsType() == nullptr &&
+ Prefix->getAsIdentifier() == nullptr)) &&
"Broken nested name specifier");
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(Prefix);
@@ -101,7 +103,7 @@ NestedNameSpecifier *
NestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) {
assert(II && "Identifier cannot be NULL");
NestedNameSpecifier Mockup;
- Mockup.Prefix.setPointer(0);
+ Mockup.Prefix.setPointer(nullptr);
Mockup.Prefix.setInt(StoredIdentifier);
Mockup.Specifier = II;
return FindOrInsert(Context, Mockup);
@@ -117,7 +119,7 @@ NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
}
NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
- if (Specifier == 0)
+ if (!Specifier)
return Global;
switch (Prefix.getInt()) {
@@ -144,7 +146,7 @@ NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
if (Prefix.getInt() == StoredNamespaceOrAlias)
return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
- return 0;
+ return nullptr;
}
/// \brief Retrieve the namespace alias stored in this nested name
@@ -153,7 +155,7 @@ NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
if (Prefix.getInt() == StoredNamespaceOrAlias)
return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
- return 0;
+ return nullptr;
}
@@ -437,7 +439,7 @@ namespace {
NestedNameSpecifierLocBuilder::
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
- : Representation(Other.Representation), Buffer(0),
+ : Representation(Other.Representation), Buffer(nullptr),
BufferSize(0), BufferCapacity(0)
{
if (!Other.Buffer)
@@ -451,10 +453,8 @@ NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
}
// Deep copy
- BufferSize = Other.BufferSize;
- BufferCapacity = Other.BufferSize;
- Buffer = static_cast<char *>(malloc(BufferCapacity));
- memcpy(Buffer, Other.Buffer, BufferSize);
+ Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
+ BufferCapacity);
}
NestedNameSpecifierLocBuilder &
@@ -477,7 +477,7 @@ operator=(const NestedNameSpecifierLocBuilder &Other) {
if (!Other.Buffer) {
// Empty.
- Buffer = 0;
+ Buffer = nullptr;
BufferSize = 0;
return *this;
}
@@ -490,10 +490,8 @@ operator=(const NestedNameSpecifierLocBuilder &Other) {
}
// Deep copy.
- BufferSize = Other.BufferSize;
- BufferCapacity = BufferSize;
- Buffer = static_cast<char *>(malloc(BufferSize));
- memcpy(Buffer, Other.Buffer, BufferSize);
+ Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
+ BufferCapacity);
return *this;
}
@@ -599,7 +597,7 @@ void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
free(Buffer);
if (!Other) {
- Representation = 0;
+ Representation = nullptr;
BufferSize = 0;
return;
}
diff --git a/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp b/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
index ff44d93..a991302 100644
--- a/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
@@ -37,7 +37,7 @@ static void BuildParentMap(MapTy& M, Stmt* S,
// If we are rebuilding the map, clear out any existing state.
if (M[POE->getSyntacticForm()])
for (Stmt::child_range I = S->children(); I; ++I)
- M[*I] = 0;
+ M[*I] = nullptr;
M[POE->getSyntacticForm()] = S;
BuildParentMap(M, POE->getSyntacticForm(), OV_Transparent);
@@ -92,7 +92,7 @@ static void BuildParentMap(MapTy& M, Stmt* S,
}
}
-ParentMap::ParentMap(Stmt* S) : Impl(0) {
+ParentMap::ParentMap(Stmt *S) : Impl(nullptr) {
if (S) {
MapTy *M = new MapTy();
BuildParentMap(*M, S);
@@ -120,7 +120,7 @@ void ParentMap::setParent(const Stmt *S, const Stmt *Parent) {
Stmt* ParentMap::getParent(Stmt* S) const {
MapTy* M = (MapTy*) Impl;
MapTy::iterator I = M->find(S);
- return I == M->end() ? 0 : I->second;
+ return I == M->end() ? nullptr : I->second;
}
Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const {
@@ -146,7 +146,7 @@ Stmt *ParentMap::getParentIgnoreParenImpCasts(Stmt *S) const {
}
Stmt *ParentMap::getOuterParenParent(Stmt *S) const {
- Stmt *Paren = 0;
+ Stmt *Paren = nullptr;
while (isa<ParenExpr>(S)) {
Paren = S;
S = getParent(S);
diff --git a/contrib/llvm/tools/clang/lib/AST/RawCommentList.cpp b/contrib/llvm/tools/clang/lib/AST/RawCommentList.cpp
index 1fa7cea..24b129a 100644
--- a/contrib/llvm/tools/clang/lib/AST/RawCommentList.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/RawCommentList.cpp
@@ -95,10 +95,9 @@ StringRef RawComment::getRawTextSlow(const SourceManager &SourceMgr) const {
unsigned BeginOffset;
unsigned EndOffset;
- llvm::tie(BeginFileID, BeginOffset) =
+ std::tie(BeginFileID, BeginOffset) =
SourceMgr.getDecomposedLoc(Range.getBegin());
- llvm::tie(EndFileID, EndOffset) =
- SourceMgr.getDecomposedLoc(Range.getEnd());
+ std::tie(EndFileID, EndOffset) = SourceMgr.getDecomposedLoc(Range.getEnd());
const unsigned Length = EndOffset - BeginOffset;
if (Length < 2)
@@ -252,3 +251,15 @@ void RawCommentList::addComment(const RawComment &RC,
Comments.push_back(new (Allocator) RawComment(RC));
}
}
+
+void RawCommentList::addDeserializedComments(ArrayRef<RawComment *> DeserializedComments) {
+ std::vector<RawComment *> MergedComments;
+ MergedComments.reserve(Comments.size() + DeserializedComments.size());
+
+ std::merge(Comments.begin(), Comments.end(),
+ DeserializedComments.begin(), DeserializedComments.end(),
+ std::back_inserter(MergedComments),
+ BeforeThanCompare<RawComment>(SourceMgr));
+ std::swap(Comments, MergedComments);
+}
+
diff --git a/contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp b/contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp
index 71e44ec..b2c244e 100644
--- a/contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/RecordLayout.cpp
@@ -21,19 +21,22 @@ void ASTRecordLayout::Destroy(ASTContext &Ctx) {
if (FieldOffsets)
Ctx.Deallocate(FieldOffsets);
if (CXXInfo) {
- Ctx.Deallocate(CXXInfo);
CXXInfo->~CXXRecordLayoutInfo();
+ Ctx.Deallocate(CXXInfo);
}
this->~ASTRecordLayout();
Ctx.Deallocate(this);
}
ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
- CharUnits alignment, CharUnits datasize,
+ CharUnits alignment,
+ CharUnits requiredAlignment,
+ CharUnits datasize,
const uint64_t *fieldoffsets,
unsigned fieldcount)
- : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
- FieldCount(fieldcount), CXXInfo(0) {
+ : Size(size), DataSize(datasize), Alignment(alignment),
+ RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
+ FieldCount(fieldcount), CXXInfo(nullptr) {
if (FieldCount > 0) {
FieldOffsets = new (Ctx) uint64_t[FieldCount];
memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
@@ -43,21 +46,24 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
// Constructor for C++ records.
ASTRecordLayout::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 nonvirtualalign,
+ CharUnits nonvirtualalignment,
CharUnits SizeOfLargestEmptySubobject,
const CXXRecordDecl *PrimaryBase,
bool IsPrimaryBaseVirtual,
const CXXRecordDecl *BaseSharingVBPtr,
- bool AlignAfterVBases,
+ bool HasZeroSizedSubObject,
+ bool LeadsWithZeroSizedBase,
const BaseOffsetsMapTy& BaseOffsets,
const VBaseOffsetsMapTy& VBaseOffsets)
- : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
+ : Size(size), DataSize(datasize), Alignment(alignment),
+ RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
{
if (FieldCount > 0) {
@@ -68,7 +74,7 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
CXXInfo->PrimaryBase.setPointer(PrimaryBase);
CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
CXXInfo->NonVirtualSize = nonvirtualsize;
- CXXInfo->NonVirtualAlign = nonvirtualalign;
+ CXXInfo->NonVirtualAlignment = nonvirtualalignment;
CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
CXXInfo->BaseOffsets = BaseOffsets;
CXXInfo->VBaseOffsets = VBaseOffsets;
@@ -76,7 +82,8 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
CXXInfo->VBPtrOffset = vbptroffset;
CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
- CXXInfo->AlignAfterVBases = AlignAfterVBases;
+ CXXInfo->HasZeroSizedSubObject = HasZeroSizedSubObject;
+ CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
#ifndef NDEBUG
diff --git a/contrib/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp b/contrib/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp
index 4390e66..b3deeba 100644
--- a/contrib/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -65,7 +65,7 @@ class EmptySubobjectMap {
const CXXRecordDecl *Class;
/// EmptyClassOffsets - A map from offsets to empty record decls.
- typedef SmallVector<const CXXRecordDecl *, 1> ClassVectorTy;
+ typedef llvm::TinyPtrVector<const CXXRecordDecl *> ClassVectorTy;
typedef llvm::DenseMap<CharUnits, ClassVectorTy> EmptyClassOffsetsMapTy;
EmptyClassOffsetsMapTy EmptyClassOffsets;
@@ -140,10 +140,8 @@ public:
void EmptySubobjectMap::ComputeEmptySubobjectSizes() {
// Check the bases.
- for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
- E = Class->bases_end(); I != E; ++I) {
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ for (const CXXBaseSpecifier &Base : Class->bases()) {
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
CharUnits EmptySize;
const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
@@ -160,18 +158,16 @@ void EmptySubobjectMap::ComputeEmptySubobjectSizes() {
}
// Check the fields.
- for (CXXRecordDecl::field_iterator I = Class->field_begin(),
- E = Class->field_end(); I != E; ++I) {
-
+ for (const FieldDecl *FD : Class->fields()) {
const RecordType *RT =
- Context.getBaseElementType(I->getType())->getAs<RecordType>();
+ Context.getBaseElementType(FD->getType())->getAs<RecordType>();
// We only care about record types.
if (!RT)
continue;
CharUnits EmptySize;
- const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl());
+ const CXXRecordDecl *MemberDecl = RT->getAsCXXRecordDecl();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
if (MemberDecl->isEmpty()) {
// If the class decl is empty, get its size.
@@ -196,8 +192,8 @@ EmptySubobjectMap::CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD,
EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset);
if (I == EmptyClassOffsets.end())
return true;
-
- const ClassVectorTy& Classes = I->second;
+
+ const ClassVectorTy &Classes = I->second;
if (std::find(Classes.begin(), Classes.end(), RD) == Classes.end())
return true;
@@ -213,7 +209,7 @@ void EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD,
// If we have empty structures inside a union, we can assign both
// the same offset. Just avoid pushing them twice in the list.
- ClassVectorTy& Classes = EmptyClassOffsets[Offset];
+ ClassVectorTy &Classes = EmptyClassOffsets[Offset];
if (std::find(Classes.begin(), Classes.end(), RD) != Classes.end())
return;
@@ -237,8 +233,7 @@ EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info,
// Traverse all non-virtual bases.
const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
- for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
- BaseSubobjectInfo* Base = Info->Bases[I];
+ for (const BaseSubobjectInfo *Base : Info->Bases) {
if (Base->IsVirtual)
continue;
@@ -263,12 +258,12 @@ EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info,
E = Info->Class->field_end(); I != E; ++I, ++FieldNo) {
if (I->isBitField())
continue;
-
+
CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo);
if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset))
return false;
}
-
+
return true;
}
@@ -288,8 +283,7 @@ void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info,
// Traverse all non-virtual bases.
const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
- for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
- BaseSubobjectInfo* Base = Info->Bases[I];
+ for (const BaseSubobjectInfo *Base : Info->Bases) {
if (Base->IsVirtual)
continue;
@@ -348,13 +342,11 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD,
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
// Traverse all non-virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- if (I->isVirtual())
+ for (const CXXBaseSpecifier &Base : RD->bases()) {
+ if (Base.isVirtual())
continue;
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl);
if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset))
@@ -363,11 +355,9 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD,
if (RD == Class) {
// This is the most derived class, traverse virtual bases as well.
- for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
- E = RD->vbases_end(); I != E; ++I) {
- const CXXRecordDecl *VBaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
+ for (const CXXBaseSpecifier &Base : RD->vbases()) {
+ const CXXRecordDecl *VBaseDecl = Base.getType()->getAsCXXRecordDecl();
+
CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl);
if (!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset))
return false;
@@ -399,10 +389,8 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD,
return true;
QualType T = FD->getType();
- if (const RecordType *RT = T->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset);
- }
// If we have an array type we need to look at every element.
if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) {
@@ -410,8 +398,8 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD,
const RecordType *RT = ElemTy->getAs<RecordType>();
if (!RT)
return true;
-
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+ const CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
uint64_t NumElements = Context.getConstantArrayElementCount(AT);
@@ -460,13 +448,11 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD,
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
// Traverse all non-virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- if (I->isVirtual())
+ for (const CXXBaseSpecifier &Base : RD->bases()) {
+ if (Base.isVirtual())
continue;
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl);
UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset);
@@ -474,11 +460,9 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD,
if (RD == Class) {
// This is the most derived class, traverse virtual bases as well.
- for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
- E = RD->vbases_end(); I != E; ++I) {
- const CXXRecordDecl *VBaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
+ for (const CXXBaseSpecifier &Base : RD->vbases()) {
+ const CXXRecordDecl *VBaseDecl = Base.getType()->getAsCXXRecordDecl();
+
CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl);
UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset);
}
@@ -500,8 +484,7 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD,
void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD,
CharUnits Offset) {
QualType T = FD->getType();
- if (const RecordType *RT = T->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
UpdateEmptyFieldSubobjects(RD, RD, Offset);
return;
}
@@ -512,8 +495,8 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD,
const RecordType *RT = ElemTy->getAs<RecordType>();
if (!RT)
return;
-
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+ const CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
uint64_t NumElements = Context.getConstantArrayElementCount(AT);
@@ -649,9 +632,9 @@ protected:
MaxFieldAlignment(CharUnits::Zero()),
DataSize(0), NonVirtualSize(CharUnits::Zero()),
NonVirtualAlignment(CharUnits::One()),
- PrimaryBase(0), PrimaryBaseIsVirtual(false),
+ PrimaryBase(nullptr), PrimaryBaseIsVirtual(false),
HasOwnVFPtr(false),
- FirstNearlyEmptyVBase(0) { }
+ FirstNearlyEmptyVBase(nullptr) {}
/// Reset this RecordLayoutBuilder to a fresh state, using the given
/// alignment as the initial alignment. This is used for the
@@ -783,16 +766,14 @@ protected:
void
RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- assert(!I->getType()->isDependentType() &&
+ for (const auto &I : RD->bases()) {
+ assert(!I.getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
- const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ const CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl();
// Check if this is a nearly empty virtual base.
- if (I->isVirtual() && Context.isNearlyEmpty(Base)) {
+ if (I.isVirtual() && Context.isNearlyEmpty(Base)) {
// If it's not an indirect primary base, then we've found our primary
// base.
if (!IndirectPrimaryBases.count(Base)) {
@@ -825,14 +806,12 @@ void RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
// If the record has a dynamic base class, attempt to choose a primary base
// class. It is the first (in direct base class order) non-virtual dynamic
// base class, if one exists.
- for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
- e = RD->bases_end(); i != e; ++i) {
+ for (const auto &I : RD->bases()) {
// Ignore virtual bases.
- if (i->isVirtual())
+ if (I.isVirtual())
continue;
- const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+ const CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl();
if (Base->isDynamicClass()) {
// We found it.
@@ -885,11 +864,11 @@ RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD,
Info->Class = RD;
Info->IsVirtual = IsVirtual;
- Info->Derived = 0;
- Info->PrimaryVirtualBaseInfo = 0;
-
- const CXXRecordDecl *PrimaryVirtualBase = 0;
- BaseSubobjectInfo *PrimaryVirtualBaseInfo = 0;
+ Info->Derived = nullptr;
+ Info->PrimaryVirtualBaseInfo = nullptr;
+
+ const CXXRecordDecl *PrimaryVirtualBase = nullptr;
+ BaseSubobjectInfo *PrimaryVirtualBaseInfo = nullptr;
// Check if this base has a primary virtual base.
if (RD->getNumVBases()) {
@@ -906,8 +885,8 @@ RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD,
if (PrimaryVirtualBaseInfo->Derived) {
// We did have info about this primary base, and it turns out that it
// has already been claimed as a primary virtual base for another
- // base.
- PrimaryVirtualBase = 0;
+ // base.
+ PrimaryVirtualBase = nullptr;
} else {
// We can claim this base as our primary base.
Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;
@@ -918,13 +897,11 @@ RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD,
}
// Now go through all direct bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- bool IsVirtual = I->isVirtual();
-
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
+ for (const auto &I : RD->bases()) {
+ bool IsVirtual = I.isVirtual();
+
+ const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
+
Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info));
}
@@ -944,15 +921,14 @@ RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD,
}
void RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) {
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- bool IsVirtual = I->isVirtual();
+ for (const auto &I : RD->bases()) {
+ bool IsVirtual = I.isVirtual();
+
+ const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
// Compute the base subobject info for this base.
- BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, 0);
+ BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual,
+ nullptr);
if (IsVirtual) {
// ComputeBaseInfo has already added this base for us.
@@ -999,8 +975,8 @@ RecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
// If the primary virtual base was a primary virtual base of some other
// base class we'll have to steal it.
BaseSubobjectInfo *PrimaryBaseInfo = VirtualBaseInfo.lookup(PrimaryBase);
- PrimaryBaseInfo->Derived = 0;
-
+ PrimaryBaseInfo->Derived = nullptr;
+
// We have a virtual primary base, insert it as an indirect primary base.
IndirectPrimaryBases.insert(PrimaryBase);
@@ -1033,15 +1009,13 @@ RecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
}
// Now lay out the non-virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
+ for (const auto &I : RD->bases()) {
// Ignore virtual bases.
- if (I->isVirtual())
+ if (I.isVirtual())
continue;
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+ const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
// Skip the primary base, because we've already laid it out. The
// !PrimaryBaseIsVirtual check is required because we might have a
@@ -1093,8 +1067,7 @@ RecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info,
// Now go through all direct non-virtual bases.
const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
- for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
- const BaseSubobjectInfo *Base = Info->Bases[I];
+ for (const BaseSubobjectInfo *Base : Info->Bases) {
if (Base->IsVirtual)
continue;
@@ -1118,15 +1091,13 @@ RecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual();
}
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- assert(!I->getType()->isDependentType() &&
+ for (const CXXBaseSpecifier &Base : RD->bases()) {
+ assert(!Base.getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
- if (I->isVirtual()) {
+ if (Base.isVirtual()) {
if (PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) {
bool IndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl);
@@ -1191,7 +1162,7 @@ CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
}
}
- CharUnits UnpackedBaseAlign = Layout.getNonVirtualAlign();
+ CharUnits UnpackedBaseAlign = Layout.getNonVirtualAlignment();
CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign;
// If we have an empty base class, try to place it at offset 0.
@@ -1326,22 +1297,18 @@ void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
#ifndef NDEBUG
// Check that we have base offsets for all bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- if (I->isVirtual())
+ for (const CXXBaseSpecifier &Base : RD->bases()) {
+ if (Base.isVirtual())
continue;
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
assert(Bases.count(BaseDecl) && "Did not find base offset!");
}
// And all virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
- E = RD->vbases_end(); I != E; ++I) {
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ for (const CXXBaseSpecifier &Base : RD->vbases()) {
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
assert(VBases.count(BaseDecl) && "Did not find base offset!");
}
@@ -1374,9 +1341,8 @@ void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
// Layout each field, for now, just sequentially, respecting alignment. In
// the future, this will need to be tweakable by targets.
- for (RecordDecl::field_iterator Field = D->field_begin(),
- FieldEnd = D->field_end(); Field != FieldEnd; ++Field)
- LayoutField(*Field);
+ for (const auto *Field : D->fields())
+ LayoutField(Field);
}
void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
@@ -1396,14 +1362,13 @@ void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
};
QualType Type;
- for (unsigned I = 0, E = llvm::array_lengthof(IntegralPODTypes);
- I != E; ++I) {
- uint64_t Size = Context.getTypeSize(IntegralPODTypes[I]);
+ for (const QualType &QT : IntegralPODTypes) {
+ uint64_t Size = Context.getTypeSize(QT);
if (Size > FieldSize)
break;
- Type = IntegralPODTypes[I];
+ Type = QT;
}
assert(!Type.isNull() && "Did not find a type!");
@@ -1452,127 +1417,224 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
uint64_t TypeSize = FieldInfo.first;
unsigned FieldAlign = FieldInfo.second;
+ // UnfilledBitsInLastUnit is the difference between the end of the
+ // last allocated bitfield (i.e. the first bit offset available for
+ // bitfields) and the end of the current data size in bits (i.e. the
+ // first bit offset available for non-bitfields). The current data
+ // size in bits is always a multiple of the char size; additionally,
+ // for ms_struct records it's also a multiple of the
+ // LastBitfieldTypeSize (if set).
+
+ // The struct-layout algorithm is dictated by the platform ABI,
+ // which in principle could use almost any rules it likes. In
+ // practice, UNIXy targets tend to inherit the algorithm described
+ // in the System V generic ABI. The basic bitfield layout rule in
+ // System V is to place bitfields at the next available bit offset
+ // where the entire bitfield would fit in an aligned storage unit of
+ // the declared type; it's okay if an earlier or later non-bitfield
+ // is allocated in the same storage unit. However, some targets
+ // (those that !useBitFieldTypeAlignment(), e.g. ARM APCS) don't
+ // require this storage unit to be aligned, and therefore always put
+ // the bitfield at the next available bit offset.
+
+ // ms_struct basically requests a complete replacement of the
+ // platform ABI's struct-layout algorithm, with the high-level goal
+ // of duplicating MSVC's layout. For non-bitfields, this follows
+ // the the standard algorithm. The basic bitfield layout rule is to
+ // allocate an entire unit of the bitfield's declared type
+ // (e.g. 'unsigned long'), then parcel it up among successive
+ // bitfields whose declared types have the same size, making a new
+ // unit as soon as the last can no longer store the whole value.
+ // Since it completely replaces the platform ABI's algorithm,
+ // settings like !useBitFieldTypeAlignment() do not apply.
+
+ // A zero-width bitfield forces the use of a new storage unit for
+ // later bitfields. In general, this occurs by rounding up the
+ // current size of the struct as if the algorithm were about to
+ // place a non-bitfield of the field's formal type. Usually this
+ // does not change the alignment of the struct itself, but it does
+ // on some targets (those that useZeroLengthBitfieldAlignment(),
+ // e.g. ARM). In ms_struct layout, zero-width bitfields are
+ // ignored unless they follow a non-zero-width bitfield.
+
+ // A field alignment restriction (e.g. from #pragma pack) or
+ // specification (e.g. from __attribute__((aligned))) changes the
+ // formal alignment of the field. For System V, this alters the
+ // required alignment of the notional storage unit that must contain
+ // the bitfield. For ms_struct, this only affects the placement of
+ // new storage units. In both cases, the effect of #pragma pack is
+ // ignored on zero-width bitfields.
+
+ // On System V, a packed field (e.g. from #pragma pack or
+ // __attribute__((packed))) always uses the next available bit
+ // offset.
+
+ // In an ms_struct struct, the alignment of a fundamental type is
+ // always equal to its size. This is necessary in order to mimic
+ // the i386 alignment rules on targets which might not fully align
+ // all types (e.g. Darwin PPC32, where alignof(long long) == 4).
+
+ // First, some simple bookkeeping to perform for ms_struct structs.
if (IsMsStruct) {
- // The field alignment for integer types in ms_struct structs is
- // always the size.
+ // The field alignment for integer types is always the size.
FieldAlign = TypeSize;
- // Ignore zero-length bitfields after non-bitfields in ms_struct structs.
- if (!FieldSize && !LastBitfieldTypeSize)
- FieldAlign = 1;
- // If a bitfield is followed by a bitfield of a different size, don't
- // pack the bits together in ms_struct structs.
+
+ // If the previous field was not a bitfield, or was a bitfield
+ // with a different storage unit size, we're done with that
+ // storage unit.
if (LastBitfieldTypeSize != TypeSize) {
+ // Also, ignore zero-length bitfields after non-bitfields.
+ if (!LastBitfieldTypeSize && !FieldSize)
+ FieldAlign = 1;
+
UnfilledBitsInLastUnit = 0;
LastBitfieldTypeSize = 0;
}
}
- uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit;
- uint64_t FieldOffset = IsUnion ? 0 : UnpaddedFieldOffset;
-
- bool ZeroLengthBitfield = false;
- if (!Context.getTargetInfo().useBitFieldTypeAlignment() &&
- Context.getTargetInfo().useZeroLengthBitfieldAlignment() &&
- FieldSize == 0) {
- // The alignment of a zero-length bitfield affects the alignment
- // of the next member. The alignment is the max of the zero
- // length bitfield's alignment and a target specific fixed value.
- ZeroLengthBitfield = true;
- unsigned ZeroLengthBitfieldBoundary =
- Context.getTargetInfo().getZeroLengthBitfieldBoundary();
- if (ZeroLengthBitfieldBoundary > FieldAlign)
- FieldAlign = ZeroLengthBitfieldBoundary;
- }
-
+ // If the field is wider than its declared type, it follows
+ // different rules in all cases.
if (FieldSize > TypeSize) {
LayoutWideBitField(FieldSize, TypeSize, FieldPacked, D);
return;
}
- // The align if the field is not packed. This is to check if the attribute
- // was unnecessary (-Wpacked).
+ // Compute the next available bit offset.
+ uint64_t FieldOffset =
+ IsUnion ? 0 : (getDataSizeInBits() - UnfilledBitsInLastUnit);
+
+ // Handle targets that don't honor bitfield type alignment.
+ if (!IsMsStruct && !Context.getTargetInfo().useBitFieldTypeAlignment()) {
+ // Some such targets do honor it on zero-width bitfields.
+ if (FieldSize == 0 &&
+ Context.getTargetInfo().useZeroLengthBitfieldAlignment()) {
+ // The alignment to round up to is the max of the field's natural
+ // alignment and a target-specific fixed value (sometimes zero).
+ unsigned ZeroLengthBitfieldBoundary =
+ Context.getTargetInfo().getZeroLengthBitfieldBoundary();
+ FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary);
+
+ // If that doesn't apply, just ignore the field alignment.
+ } else {
+ FieldAlign = 1;
+ }
+ }
+
+ // Remember the alignment we would have used if the field were not packed.
unsigned UnpackedFieldAlign = FieldAlign;
- uint64_t UnpackedFieldOffset = FieldOffset;
- if (!Context.getTargetInfo().useBitFieldTypeAlignment() && !ZeroLengthBitfield)
- UnpackedFieldAlign = 1;
- if (FieldPacked ||
- (!Context.getTargetInfo().useBitFieldTypeAlignment() && !ZeroLengthBitfield))
+ // Ignore the field alignment if the field is packed unless it has zero-size.
+ if (!IsMsStruct && FieldPacked && FieldSize != 0)
FieldAlign = 1;
- FieldAlign = std::max(FieldAlign, D->getMaxAlignment());
- UnpackedFieldAlign = std::max(UnpackedFieldAlign, D->getMaxAlignment());
- // The maximum field alignment overrides the aligned attribute.
- if (!MaxFieldAlignment.isZero() && FieldSize != 0) {
+ // But, if there's an 'aligned' attribute on the field, honor that.
+ if (unsigned ExplicitFieldAlign = D->getMaxAlignment()) {
+ FieldAlign = std::max(FieldAlign, ExplicitFieldAlign);
+ UnpackedFieldAlign = std::max(UnpackedFieldAlign, ExplicitFieldAlign);
+ }
+
+ // But, if there's a #pragma pack in play, that takes precedent over
+ // even the 'aligned' attribute, for non-zero-width bitfields.
+ if (!MaxFieldAlignment.isZero() && FieldSize) {
unsigned MaxFieldAlignmentInBits = Context.toBits(MaxFieldAlignment);
FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits);
UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits);
}
- // ms_struct bitfields always have to start at a round alignment.
- if (IsMsStruct && !LastBitfieldTypeSize) {
- FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
- UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset,
- UnpackedFieldAlign);
- }
+ // For purposes of diagnostics, we're going to simultaneously
+ // compute the field offsets that we would have used if we weren't
+ // adding any alignment padding or if the field weren't packed.
+ uint64_t UnpaddedFieldOffset = FieldOffset;
+ uint64_t UnpackedFieldOffset = FieldOffset;
- // Check if we need to add padding to give the field the correct alignment.
- if (FieldSize == 0 ||
- (MaxFieldAlignment.isZero() &&
- (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize))
- FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
+ // Check if we need to add padding to fit the bitfield within an
+ // allocation unit with the right size and alignment. The rules are
+ // somewhat different here for ms_struct structs.
+ if (IsMsStruct) {
+ // If it's not a zero-width bitfield, and we can fit the bitfield
+ // into the active storage unit (and we haven't already decided to
+ // start a new storage unit), just do so, regardless of any other
+ // other consideration. Otherwise, round up to the right alignment.
+ if (FieldSize == 0 || FieldSize > UnfilledBitsInLastUnit) {
+ FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
+ UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset,
+ UnpackedFieldAlign);
+ UnfilledBitsInLastUnit = 0;
+ }
- if (FieldSize == 0 ||
- (MaxFieldAlignment.isZero() &&
- (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize))
- UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset,
- UnpackedFieldAlign);
+ } else {
+ // #pragma pack, with any value, suppresses the insertion of padding.
+ bool AllowPadding = MaxFieldAlignment.isZero();
+
+ // Compute the real offset.
+ if (FieldSize == 0 ||
+ (AllowPadding &&
+ (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)) {
+ FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
+ }
- // Padding members don't affect overall alignment, unless zero length bitfield
- // alignment is enabled.
- if (!D->getIdentifier() &&
- !Context.getTargetInfo().useZeroLengthBitfieldAlignment() &&
- !IsMsStruct)
- FieldAlign = UnpackedFieldAlign = 1;
+ // Repeat the computation for diagnostic purposes.
+ if (FieldSize == 0 ||
+ (AllowPadding &&
+ (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize))
+ UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset,
+ UnpackedFieldAlign);
+ }
+ // If we're using external layout, give the external layout a chance
+ // to override this information.
if (ExternalLayout)
FieldOffset = updateExternalFieldOffset(D, FieldOffset);
- // Place this field at the current location.
+ // Okay, place the bitfield at the calculated offset.
FieldOffsets.push_back(FieldOffset);
+ // Bookkeeping:
+
+ // Anonymous members don't affect the overall record alignment,
+ // except on targets where they do.
+ if (!IsMsStruct &&
+ !Context.getTargetInfo().useZeroLengthBitfieldAlignment() &&
+ !D->getIdentifier())
+ FieldAlign = UnpackedFieldAlign = 1;
+
+ // Diagnose differences in layout due to padding or packing.
if (!ExternalLayout)
CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset,
UnpackedFieldAlign, FieldPacked, D);
// Update DataSize to include the last byte containing (part of) the bitfield.
+
+ // For unions, this is just a max operation, as usual.
if (IsUnion) {
// FIXME: I think FieldSize should be TypeSize here.
setDataSize(std::max(getDataSizeInBits(), FieldSize));
- } else {
- if (IsMsStruct && FieldSize) {
- // Under ms_struct, a bitfield always takes up space equal to the size
- // of the type. We can't just change the alignment computation on the
- // other codepath because of the way this interacts with #pragma pack:
- // in a packed struct, we need to allocate misaligned space in the
- // struct to hold the bitfield.
- if (!UnfilledBitsInLastUnit) {
- setDataSize(FieldOffset + TypeSize);
- UnfilledBitsInLastUnit = TypeSize - FieldSize;
- } else if (UnfilledBitsInLastUnit < FieldSize) {
- setDataSize(getDataSizeInBits() + TypeSize);
- UnfilledBitsInLastUnit = TypeSize - FieldSize;
- } else {
- UnfilledBitsInLastUnit -= FieldSize;
- }
- LastBitfieldTypeSize = TypeSize;
- } else {
- uint64_t NewSizeInBits = FieldOffset + FieldSize;
- uint64_t BitfieldAlignment = Context.getTargetInfo().getCharAlign();
- setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, BitfieldAlignment));
- UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;
- LastBitfieldTypeSize = 0;
+
+ // For non-zero-width bitfields in ms_struct structs, allocate a new
+ // storage unit if necessary.
+ } else if (IsMsStruct && FieldSize) {
+ // We should have cleared UnfilledBitsInLastUnit in every case
+ // where we changed storage units.
+ if (!UnfilledBitsInLastUnit) {
+ setDataSize(FieldOffset + TypeSize);
+ UnfilledBitsInLastUnit = TypeSize;
}
+ UnfilledBitsInLastUnit -= FieldSize;
+ LastBitfieldTypeSize = TypeSize;
+
+ // Otherwise, bump the data size up to include the bitfield,
+ // including padding up to char alignment, and then remember how
+ // bits we didn't use.
+ } else {
+ uint64_t NewSizeInBits = FieldOffset + FieldSize;
+ uint64_t CharAlignment = Context.getTargetInfo().getCharAlign();
+ setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, CharAlignment));
+ UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;
+
+ // The only time we can get here for an ms_struct is if this is a
+ // zero-width bitfield, which doesn't count as anything for the
+ // purposes of unfilled bits.
+ LastBitfieldTypeSize = 0;
}
// Update the size.
@@ -1870,28 +1932,26 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
const CXXRecordDecl *RD) {
// If a class isn't polymorphic it doesn't have a key function.
if (!RD->isPolymorphic())
- return 0;
+ return nullptr;
// A class that is not externally visible doesn't have a key function. (Or
// at least, there's no point to assigning a key function to such a class;
// this doesn't affect the ABI.)
if (!RD->isExternallyVisible())
- return 0;
+ return nullptr;
- // Template instantiations don't have key functions,see Itanium C++ ABI 5.2.6.
+ // Template instantiations don't have key functions per Itanium C++ ABI 5.2.6.
// Same behavior as GCC.
TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
if (TSK == TSK_ImplicitInstantiation ||
+ TSK == TSK_ExplicitInstantiationDeclaration ||
TSK == TSK_ExplicitInstantiationDefinition)
- return 0;
+ return nullptr;
bool allowInlineFunctions =
Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline();
- for (CXXRecordDecl::method_iterator I = RD->method_begin(),
- E = RD->method_end(); I != E; ++I) {
- const CXXMethodDecl *MD = *I;
-
+ for (const CXXMethodDecl *MD : RD->methods()) {
if (!MD->isVirtual())
continue;
@@ -1924,7 +1984,7 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
return MD;
}
- return 0;
+ return nullptr;
}
DiagnosticBuilder
@@ -1979,50 +2039,101 @@ static bool isMsLayout(const RecordDecl* D) {
}
// This section contains an implementation of struct layout that is, up to the
-// included tests, compatible with cl.exe (2012). The layout produced is
+// included tests, compatible with cl.exe (2013). The layout produced is
// significantly different than those produced by the Itanium ABI. Here we note
// the most important differences.
//
// * The alignment of bitfields in unions is ignored when computing the
// alignment of the union.
-// * The existance of zero-width bitfield that occurs after anything other than
+// * The existence of zero-width bitfield that occurs after anything other than
// a non-zero length bitfield is ignored.
+// * There is no explicit primary base for the purposes of layout. All bases
+// with vfptrs are laid out first, followed by all bases without vfptrs.
// * The Itanium equivalent vtable pointers are split into a vfptr (virtual
// function pointer) and a vbptr (virtual base pointer). They can each be
// shared with a, non-virtual bases. These bases need not be the same. vfptrs
-// always occur at offset 0. vbptrs can occur at an
-// arbitrary offset and are placed after non-virtual bases but before fields.
+// always occur at offset 0. vbptrs can occur at an arbitrary offset and are
+// placed after the lexiographically last non-virtual base. This placement
+// is always before fields but can be in the middle of the non-virtual bases
+// due to the two-pass layout scheme for non-virtual-bases.
// * Virtual bases sometimes require a 'vtordisp' field that is laid out before
// the virtual base and is used in conjunction with virtual overrides during
-// construction and destruction.
-// * vfptrs are allocated in a block of memory equal to the alignment of the
-// fields and non-virtual bases at offset 0 in 32 bit mode and in a pointer
-// sized block of memory in 64 bit mode.
-// * vbptrs are allocated in a block of memory equal to the alignment of the
-// fields and non-virtual bases. This block is at a potentially unaligned
-// offset. If the allocation slot is unaligned and the alignment is less than
-// or equal to the pointer size, additional space is allocated so that the
-// pointer can be aligned properly. This causes very strange effects on the
-// placement of objects after the allocated block. (see the code).
+// construction and destruction. This is always a 4 byte value and is used as
+// an alternative to constructor vtables.
// * vtordisps are allocated in a block of memory with size and alignment equal
// to the alignment of the completed structure (before applying __declspec(
// align())). The vtordisp always occur at the end of the allocation block,
// immediately prior to the virtual base.
-// * The last zero sized non-virtual base is allocated after the placement of
-// vbptr if one exists and can be placed at the end of the struct, potentially
-// aliasing either the first member or another struct allocated after this
-// one.
-// * The last zero size virtual base may be placed at the end of the struct.
-// and can potentially alias a zero sized type in the next struct.
-// * If the last field is a non-zero length bitfield and we have any virtual
-// bases then some extra padding is added before the virtual bases for no
-// obvious reason.
-// * When laying out empty non-virtual bases, an extra byte of padding is added
-// if the non-virtual base before the empty non-virtual base has a vbptr.
-
+// * vfptrs are injected after all bases and fields have been laid out. In
+// order to guarantee proper alignment of all fields, the vfptr injection
+// pushes all bases and fields back by the alignment imposed by those bases
+// and fields. This can potentially add a significant amount of padding.
+// vfptrs are always injected at offset 0.
+// * vbptrs are injected after all bases and fields have been laid out. In
+// order to guarantee proper alignment of all fields, the vfptr injection
+// pushes all bases and fields back by the alignment imposed by those bases
+// and fields. This can potentially add a significant amount of padding.
+// vbptrs are injected immediately after the last non-virtual base as
+// lexiographically ordered in the code. If this site isn't pointer aligned
+// the vbptr is placed at the next properly aligned location. Enough padding
+// is added to guarantee a fit.
+// * The last zero sized non-virtual base can be placed at the end of the
+// struct (potentially aliasing another object), or may alias with the first
+// field, even if they are of the same type.
+// * The last zero size virtual base may be placed at the end of the struct
+// potentially aliasing another object.
+// * The ABI attempts to avoid aliasing of zero sized bases by adding padding
+// between bases or vbases with specific properties. The criteria for
+// additional padding between two bases is that the first base is zero sized
+// or ends with a zero sized subobject and the second base is zero sized or
+// trails with a zero sized base or field (sharing of vfptrs can reorder the
+// layout of the so the leading base is not always the first one declared).
+// This rule does take into account fields that are not records, so padding
+// will occur even if the last field is, e.g. an int. The padding added for
+// bases is 1 byte. The padding added between vbases depends on the alignment
+// of the object but is at least 4 bytes (in both 32 and 64 bit modes).
+// * There is no concept of non-virtual alignment, non-virtual alignment and
+// alignment are always identical.
+// * There is a distinction between alignment and required alignment.
+// __declspec(align) changes the required alignment of a struct. This
+// alignment is _always_ obeyed, even in the presence of #pragma pack. A
+// record inherites required alignment from all of its fields an bases.
+// * __declspec(align) on bitfields has the effect of changing the bitfield's
+// alignment instead of its required alignment. This is the only known way
+// to make the alignment of a struct bigger than 8. Interestingly enough
+// this alignment is also immune to the effects of #pragma pack and can be
+// used to create structures with large alignment under #pragma pack.
+// However, because it does not impact required alignment, such a structure,
+// when used as a field or base, will not be aligned if #pragma pack is
+// still active at the time of use.
+//
+// Known incompatibilities:
+// * all: #pragma pack between fields in a record
+// * 2010 and back: If the last field in a record is a bitfield, every object
+// laid out after the record will have extra padding inserted before it. The
+// extra padding will have size equal to the size of the storage class of the
+// bitfield. 0 sized bitfields don't exhibit this behavior and the extra
+// padding can be avoided by adding a 0 sized bitfield after the non-zero-
+// sized bitfield.
+// * 2012 and back: In 64-bit mode, if the alignment of a record is 16 or
+// greater due to __declspec(align()) then a second layout phase occurs after
+// The locations of the vf and vb pointers are known. This layout phase
+// suffers from the "last field is a bitfield" bug in 2010 and results in
+// _every_ field getting padding put in front of it, potentially including the
+// vfptr, leaving the vfprt at a non-zero location which results in a fault if
+// anything tries to read the vftbl. The second layout phase also treats
+// bitfields as separate entities and gives them each storage rather than
+// packing them. Additionally, because this phase appears to perform a
+// (an unstable) sort on the members before laying them out and because merged
+// bitfields have the same address, the bitfields end up in whatever order
+// the sort left them in, a behavior we could never hope to replicate.
namespace {
struct MicrosoftRecordLayoutBuilder {
+ struct ElementInfo {
+ CharUnits Size;
+ CharUnits Alignment;
+ };
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
MicrosoftRecordLayoutBuilder(const ASTContext &Context) : Context(Context) {}
private:
@@ -2030,19 +2141,20 @@ private:
LLVM_DELETED_FUNCTION;
void operator=(const MicrosoftRecordLayoutBuilder &) LLVM_DELETED_FUNCTION;
public:
-
void layout(const RecordDecl *RD);
void cxxLayout(const CXXRecordDecl *RD);
/// \brief Initializes size and alignment and honors some flags.
void initializeLayout(const RecordDecl *RD);
/// \brief Initialized C++ layout, compute alignment and virtual alignment and
- /// existance of vfptrs and vbptrs. Alignment is needed before the vfptr is
+ /// existence of vfptrs and vbptrs. Alignment is needed before the vfptr is
/// laid out.
void initializeCXXLayout(const CXXRecordDecl *RD);
- void layoutVFPtr(const CXXRecordDecl *RD);
void layoutNonVirtualBases(const CXXRecordDecl *RD);
- void layoutNonVirtualBase(const CXXRecordDecl *RD);
- void layoutVBPtr(const CXXRecordDecl *RD);
+ void layoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
+ const ASTRecordLayout &BaseLayout,
+ const ASTRecordLayout *&PreviousBaseLayout);
+ void injectVFPtr(const CXXRecordDecl *RD);
+ void injectVBPtr(const CXXRecordDecl *RD);
/// \brief Lays out the fields of the record. Also rounds size up to
/// alignment.
void layoutFields(const RecordDecl *RD);
@@ -2052,22 +2164,14 @@ public:
/// special cases associated with zero-width bit-fields.
void layoutZeroWidthBitField(const FieldDecl *FD);
void layoutVirtualBases(const CXXRecordDecl *RD);
- void layoutVirtualBase(const CXXRecordDecl *RD, bool HasVtordisp);
- /// \brief Flushes the lazy virtual base and conditionally rounds up to
- /// alignment.
- void finalizeCXXLayout(const CXXRecordDecl *RD);
- void honorDeclspecAlign(const RecordDecl *RD);
-
- /// \brief Updates the alignment of the type. This function doesn't take any
- /// properties (such as packedness) into account. getAdjustedFieldInfo()
- /// adjustes for packedness.
- void updateAlignment(CharUnits NewAlignment) {
- Alignment = std::max(Alignment, NewAlignment);
- }
- /// \brief Gets the size and alignment taking attributes into account.
- std::pair<CharUnits, CharUnits> getAdjustedFieldInfo(const FieldDecl *FD);
- /// \brief Places a field at offset 0.
- void placeFieldAtZero() { FieldOffsets.push_back(0); }
+ void finalizeLayout(const RecordDecl *RD);
+ /// \brief Gets the size and alignment of a base taking pragma pack and
+ /// __declspec(align) into account.
+ ElementInfo getAdjustedElementInfo(const ASTRecordLayout &Layout);
+ /// \brief Gets the size and alignment of a field taking pragma pack and
+ /// __declspec(align) into account. It also updates RequiredAlignment as a
+ /// side effect because it is most convenient to do so here.
+ ElementInfo getAdjustedElementInfo(const FieldDecl *FD);
/// \brief Places a field at an offset in CharUnits.
void placeFieldAtOffset(CharUnits FieldOffset) {
FieldOffsets.push_back(Context.toBits(FieldOffset));
@@ -2079,334 +2183,280 @@ public:
/// \brief Compute the set of virtual bases for which vtordisps are required.
llvm::SmallPtrSet<const CXXRecordDecl *, 2>
computeVtorDispSet(const CXXRecordDecl *RD);
-
const ASTContext &Context;
/// \brief The size of the record being laid out.
CharUnits Size;
+ /// \brief The non-virtual size of the record layout.
+ CharUnits NonVirtualSize;
+ /// \brief The data size of the record layout.
+ CharUnits DataSize;
/// \brief The current alignment of the record layout.
CharUnits Alignment;
- /// \brief The collection of field offsets.
- SmallVector<uint64_t, 16> FieldOffsets;
/// \brief The maximum allowed field alignment. This is set by #pragma pack.
CharUnits MaxFieldAlignment;
- /// \brief Alignment does not occur for virtual bases unless something
- /// forces it to by explicitly using __declspec(align())
- bool AlignAfterVBases : 1;
- bool IsUnion : 1;
- /// \brief True if the last field laid out was a bitfield and was not 0
- /// width.
- bool LastFieldIsNonZeroWidthBitfield : 1;
+ /// \brief The alignment that this record must obey. This is imposed by
+ /// __declspec(align()) on the record itself or one of its fields or bases.
+ CharUnits RequiredAlignment;
/// \brief The size of the allocation of the currently active bitfield.
/// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield
/// is true.
CharUnits CurrentBitfieldSize;
- /// \brief The number of remaining bits in our last bitfield allocation.
- /// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield is
- /// true.
- unsigned RemainingBitsInField;
-
- /// \brief The data alignment of the record layout.
- CharUnits DataSize;
- /// \brief The alignment of the non-virtual portion of the record layout
- /// without the impact of the virtual pointers.
- /// Only used for C++ layouts.
- CharUnits BasesAndFieldsAlignment;
- /// \brief The alignment of the non-virtual portion of the record layout
- /// Only used for C++ layouts.
- CharUnits NonVirtualAlignment;
- /// \brief The additional alignment imposed by the virtual bases.
- CharUnits VirtualAlignment;
+ /// \brief Offset to the virtual base table pointer (if one exists).
+ CharUnits VBPtrOffset;
+ /// \brief The size and alignment info of a pointer.
+ ElementInfo PointerInfo;
/// \brief The primary base class (if one exists).
const CXXRecordDecl *PrimaryBase;
/// \brief The class we share our vb-pointer with.
const CXXRecordDecl *SharedVBPtrBase;
- /// \brief True if the class has a vftable pointer that can be extended
- /// by this class or classes derived from it. Such a vfptr will always occur
- /// at offset 0.
- bool HasExtendableVFPtr : 1;
- /// \brief True if the class has a (not necessarily its own) vbtable pointer.
- bool HasVBPtr : 1;
- /// \brief Offset to the virtual base table pointer (if one exists).
- CharUnits VBPtrOffset;
+ /// \brief The collection of field offsets.
+ SmallVector<uint64_t, 16> FieldOffsets;
/// \brief Base classes and their offsets in the record.
BaseOffsetsMapTy Bases;
/// \brief virtual base classes and their offsets in the record.
ASTRecordLayout::VBaseOffsetsMapTy VBases;
- /// \brief The size of a pointer.
- CharUnits PointerSize;
- /// \brief The alignment of a pointer.
- CharUnits PointerAlignment;
- /// \brief Holds an empty base we haven't yet laid out.
- const CXXRecordDecl *LazyEmptyBase;
- /// \brief Lets us know if the last base we laid out was empty. Only used
- /// when adjusting the placement of a last zero-sized base in 64 bit mode.
- bool LastBaseWasEmpty;
- /// \brief Lets us know if we're in 64-bit mode
- bool Is64BitMode;
- /// \brief True if the last non-virtual base has a vbptr.
- bool LastNonVirtualBaseHasVBPtr;
+ /// \brief The number of remaining bits in our last bitfield allocation.
+ /// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield is
+ /// true.
+ unsigned RemainingBitsInField;
+ bool IsUnion : 1;
+ /// \brief True if the last field laid out was a bitfield and was not 0
+ /// width.
+ bool LastFieldIsNonZeroWidthBitfield : 1;
+ /// \brief True if the class has its own vftable pointer.
+ bool HasOwnVFPtr : 1;
+ /// \brief True if the class has a vbtable pointer.
+ bool HasVBPtr : 1;
+ /// \brief True if the last sub-object within the type is zero sized or the
+ /// object itself is zero sized. This *does not* count members that are not
+ /// records. Only used for MS-ABI.
+ bool EndsWithZeroSizedObject : 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;
};
} // namespace
-std::pair<CharUnits, CharUnits>
-MicrosoftRecordLayoutBuilder::getAdjustedFieldInfo(const FieldDecl *FD) {
- std::pair<CharUnits, CharUnits> FieldInfo =
- Context.getTypeInfoInChars(FD->getType());
+MicrosoftRecordLayoutBuilder::ElementInfo
+MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
+ const ASTRecordLayout &Layout) {
+ ElementInfo Info;
+ Info.Alignment = Layout.getAlignment();
+ // Respect pragma pack.
+ if (!MaxFieldAlignment.isZero())
+ Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);
+ // Track zero-sized subobjects here where it's already available.
+ EndsWithZeroSizedObject = Layout.hasZeroSizedSubObject();
+ // Respect required alignment, this is necessary because we may have adjusted
+ // the alignment in the case of pragam pack. Note that the required alignment
+ // doesn't actually apply to the struct alignment at this point.
+ Alignment = std::max(Alignment, Info.Alignment);
+ RequiredAlignment = std::max(RequiredAlignment, Layout.getRequiredAlignment());
+ Info.Alignment = std::max(Info.Alignment, Layout.getRequiredAlignment());
+ Info.Size = Layout.getNonVirtualSize();
+ return Info;
+}
- // If we're not on win32 and using ms_struct the field alignment will be wrong
- // for 64 bit types, so we fix that here.
- if (FD->getASTContext().getTargetInfo().getTriple().getOS() !=
- llvm::Triple::Win32) {
- QualType T = Context.getBaseElementType(FD->getType());
- if (const BuiltinType *BTy = T->getAs<BuiltinType>()) {
- CharUnits TypeSize = Context.getTypeSizeInChars(BTy);
- if (TypeSize > FieldInfo.second)
- FieldInfo.second = TypeSize;
+MicrosoftRecordLayoutBuilder::ElementInfo
+MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
+ const FieldDecl *FD) {
+ ElementInfo Info;
+ std::tie(Info.Size, Info.Alignment) =
+ Context.getTypeInfoInChars(FD->getType());
+ // Respect align attributes.
+ CharUnits FieldRequiredAlignment =
+ Context.toCharUnitsFromBits(FD->getMaxAlignment());
+ // Respect attributes applied to subobjects of the field.
+ if (FD->isBitField())
+ // For some reason __declspec align impacts alignment rather than required
+ // alignment when it is applied to bitfields.
+ Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);
+ else {
+ if (auto RT =
+ FD->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
+ auto const &Layout = Context.getASTRecordLayout(RT->getDecl());
+ EndsWithZeroSizedObject = Layout.hasZeroSizedSubObject();
+ FieldRequiredAlignment = std::max(FieldRequiredAlignment,
+ Layout.getRequiredAlignment());
}
+ // Capture required alignment as a side-effect.
+ RequiredAlignment = std::max(RequiredAlignment, FieldRequiredAlignment);
}
-
- // Respect packed attribute.
+ // Respect pragma pack, attribute pack and declspec align
+ if (!MaxFieldAlignment.isZero())
+ Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);
if (FD->hasAttr<PackedAttr>())
- FieldInfo.second = CharUnits::One();
- // Respect pack pragma.
- else if (!MaxFieldAlignment.isZero())
- FieldInfo.second = std::min(FieldInfo.second, MaxFieldAlignment);
- // Respect alignment attributes.
- if (unsigned fieldAlign = FD->getMaxAlignment()) {
- CharUnits FieldAlign = Context.toCharUnitsFromBits(fieldAlign);
- AlignAfterVBases = true;
- FieldInfo.second = std::max(FieldInfo.second, FieldAlign);
- }
- return FieldInfo;
-}
-
-void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) {
- IsUnion = RD->isUnion();
- Is64BitMode = Context.getTargetInfo().getPointerWidth(0) == 64;
-
- Size = CharUnits::Zero();
- Alignment = CharUnits::One();
- AlignAfterVBases = false;
-
- // Compute the maximum field alignment.
- MaxFieldAlignment = CharUnits::Zero();
- // Honor the default struct packing maximum alignment flag.
- if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct)
- MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment);
- // Honor the packing attribute.
- if (const MaxFieldAlignmentAttr *MFAA = RD->getAttr<MaxFieldAlignmentAttr>())
- MaxFieldAlignment = Context.toCharUnitsFromBits(MFAA->getAlignment());
- // Packed attribute forces max field alignment to be 1.
- if (RD->hasAttr<PackedAttr>())
- MaxFieldAlignment = CharUnits::One();
+ Info.Alignment = CharUnits::One();
+ Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);
+ return Info;
}
void MicrosoftRecordLayoutBuilder::layout(const RecordDecl *RD) {
initializeLayout(RD);
layoutFields(RD);
- honorDeclspecAlign(RD);
+ DataSize = Size = Size.RoundUpToAlignment(Alignment);
+ RequiredAlignment = std::max(
+ RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment()));
+ finalizeLayout(RD);
}
void MicrosoftRecordLayoutBuilder::cxxLayout(const CXXRecordDecl *RD) {
initializeLayout(RD);
initializeCXXLayout(RD);
- layoutVFPtr(RD);
layoutNonVirtualBases(RD);
- layoutVBPtr(RD);
layoutFields(RD);
- DataSize = Size;
- NonVirtualAlignment = Alignment;
+ injectVBPtr(RD);
+ injectVFPtr(RD);
+ if (HasOwnVFPtr || (HasVBPtr && !SharedVBPtrBase))
+ Alignment = std::max(Alignment, PointerInfo.Alignment);
+ auto RoundingAlignment = Alignment;
+ if (!MaxFieldAlignment.isZero())
+ RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment);
+ NonVirtualSize = Size = Size.RoundUpToAlignment(RoundingAlignment);
+ RequiredAlignment = std::max(
+ RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment()));
layoutVirtualBases(RD);
- finalizeCXXLayout(RD);
- honorDeclspecAlign(RD);
+ finalizeLayout(RD);
+}
+
+void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) {
+ IsUnion = RD->isUnion();
+ Size = CharUnits::Zero();
+ Alignment = CharUnits::One();
+ // In 64-bit mode we always perform an alignment step after laying out vbases.
+ // In 32-bit mode we do not. The check to see if we need to perform alignment
+ // checks the RequiredAlignment field and performs alignment if it isn't 0.
+ RequiredAlignment = Context.getTargetInfo().getPointerWidth(0) == 64 ?
+ CharUnits::One() : CharUnits::Zero();
+ // Compute the maximum field alignment.
+ MaxFieldAlignment = CharUnits::Zero();
+ // Honor the default struct packing maximum alignment flag.
+ if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct)
+ MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment);
+ // Honor the packing attribute. The MS-ABI ignores pragma pack if its larger
+ // than the pointer size.
+ if (const MaxFieldAlignmentAttr *MFAA = RD->getAttr<MaxFieldAlignmentAttr>()){
+ unsigned PackedAlignment = MFAA->getAlignment();
+ if (PackedAlignment <= Context.getTargetInfo().getPointerWidth(0))
+ MaxFieldAlignment = Context.toCharUnitsFromBits(PackedAlignment);
+ }
+ // Packed attribute forces max field alignment to be 1.
+ if (RD->hasAttr<PackedAttr>())
+ MaxFieldAlignment = CharUnits::One();
}
void
MicrosoftRecordLayoutBuilder::initializeCXXLayout(const CXXRecordDecl *RD) {
- // Calculate pointer size and alignment.
- PointerSize =
+ EndsWithZeroSizedObject = false;
+ LeadsWithZeroSizedBase = false;
+ HasOwnVFPtr = false;
+ HasVBPtr = false;
+ PrimaryBase = nullptr;
+ SharedVBPtrBase = nullptr;
+ // Calculate pointer size and alignment. These are used for vfptr and vbprt
+ // injection.
+ PointerInfo.Size =
Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
- PointerAlignment = PointerSize;
+ PointerInfo.Alignment = PointerInfo.Size;
+ // Respect pragma pack.
if (!MaxFieldAlignment.isZero())
- PointerAlignment = std::min(PointerAlignment, MaxFieldAlignment);
-
- // Initialize information about the bases.
- HasVBPtr = false;
- HasExtendableVFPtr = false;
- SharedVBPtrBase = 0;
- PrimaryBase = 0;
- VirtualAlignment = CharUnits::One();
- AlignAfterVBases = Is64BitMode;
+ PointerInfo.Alignment = std::min(PointerInfo.Alignment, MaxFieldAlignment);
+}
- // If the record has a dynamic base class, attempt to choose a primary base
- // class. It is the first (in direct base class order) non-virtual dynamic
- // base class, if one exists.
- for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
- e = RD->bases_end();
- i != e; ++i) {
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
- const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
- // Handle forced alignment.
- if (Layout.getAlignAfterVBases())
- AlignAfterVBases = true;
- // Handle virtual bases.
- if (i->isVirtual()) {
- VirtualAlignment = std::max(VirtualAlignment, Layout.getAlignment());
+void
+MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) {
+ // The MS-ABI lays out all bases that contain leading vfptrs before it lays
+ // out any bases that do not contain vfptrs. We implement this as two passes
+ // over the bases. This approach guarantees that the primary base is laid out
+ // first. We use these passes to calculate some additional aggregated
+ // information about the bases, such as reqruied alignment and the presence of
+ // zero sized members.
+ const ASTRecordLayout *PreviousBaseLayout = nullptr;
+ // Iterate through the bases and lay out the non-virtual ones.
+ for (const CXXBaseSpecifier &Base : RD->bases()) {
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+ const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+ // Mark and skip virtual bases.
+ if (Base.isVirtual()) {
HasVBPtr = true;
continue;
}
- // We located a primary base class!
- if (!PrimaryBase && Layout.hasExtendableVFPtr()) {
- PrimaryBase = BaseDecl;
- HasExtendableVFPtr = true;
- }
- // We located a base to share a VBPtr with!
- if (!SharedVBPtrBase && Layout.hasVBPtr()) {
+ // Check fo a base to share a VBPtr with.
+ if (!SharedVBPtrBase && BaseLayout.hasVBPtr()) {
SharedVBPtrBase = BaseDecl;
HasVBPtr = true;
}
- updateAlignment(Layout.getAlignment());
+ // Only lay out bases with extendable VFPtrs on the first pass.
+ if (!BaseLayout.hasExtendableVFPtr())
+ continue;
+ // If we don't have a primary base, this one qualifies.
+ if (!PrimaryBase) {
+ PrimaryBase = BaseDecl;
+ LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase();
+ }
+ // Lay out the base.
+ layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout);
}
-
- // Use LayoutFields to compute the alignment of the fields. The layout
- // is discarded. This is the simplest way to get all of the bit-field
- // behavior correct and is not actually very expensive.
- layoutFields(RD);
- Size = CharUnits::Zero();
- BasesAndFieldsAlignment = Alignment;
- FieldOffsets.clear();
-}
-
-void MicrosoftRecordLayoutBuilder::layoutVFPtr(const CXXRecordDecl *RD) {
- // If we have a primary base then our VFPtr was already laid out
- if (PrimaryBase)
- return;
-
- // Look at all of our methods to determine if we need a VFPtr. We need a
- // vfptr if we define a new virtual function.
- if (!HasExtendableVFPtr && RD->isDynamicClass())
+ // Figure out if we need a fresh VFPtr for this class.
+ if (!PrimaryBase && RD->isDynamicClass())
for (CXXRecordDecl::method_iterator i = RD->method_begin(),
e = RD->method_end();
- !HasExtendableVFPtr && i != e; ++i)
- HasExtendableVFPtr = i->isVirtual() && i->size_overridden_methods() == 0;
- if (!HasExtendableVFPtr)
- return;
-
- // MSVC 32 (but not 64) potentially over-aligns the vf-table pointer by giving
- // it the max alignment of all the non-virtual data in the class. The
- // resulting layout is essentially { vftbl, { nvdata } }. This is completely
- // unnecessary, but we're not here to pass judgment.
- updateAlignment(PointerAlignment);
- if (Is64BitMode)
- Size = Size.RoundUpToAlignment(PointerAlignment) + PointerSize;
- else
- Size = Size.RoundUpToAlignment(PointerAlignment) + Alignment;
-}
-
-void
-MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) {
- LazyEmptyBase = 0;
- LastBaseWasEmpty = false;
- LastNonVirtualBaseHasVBPtr = false;
-
- // Lay out the primary base first.
- if (PrimaryBase)
- layoutNonVirtualBase(PrimaryBase);
-
+ !HasOwnVFPtr && i != e; ++i)
+ HasOwnVFPtr = i->isVirtual() && i->size_overridden_methods() == 0;
+ // If we don't have a primary base then we have a leading object that could
+ // itself lead with a zero-sized object, something we track.
+ bool CheckLeadingLayout = !PrimaryBase;
// Iterate through the bases and lay out the non-virtual ones.
- for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
- e = RD->bases_end();
- i != e; ++i) {
- if (i->isVirtual())
+ for (const CXXBaseSpecifier &Base : RD->bases()) {
+ if (Base.isVirtual())
+ continue;
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+ const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+ // Only lay out bases without extendable VFPtrs on the second pass.
+ if (BaseLayout.hasExtendableVFPtr()) {
+ VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize();
continue;
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(i->getType()->castAs<RecordType>()->getDecl());
- if (BaseDecl != PrimaryBase)
- layoutNonVirtualBase(BaseDecl);
- }
-}
-
-void
-MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(const CXXRecordDecl *RD) {
- const ASTRecordLayout *Layout = RD ? &Context.getASTRecordLayout(RD) : 0;
-
- // If we have a lazy empty base we haven't laid out yet, do that now.
- if (LazyEmptyBase) {
- const ASTRecordLayout &LazyLayout =
- Context.getASTRecordLayout(LazyEmptyBase);
- Size = Size.RoundUpToAlignment(LazyLayout.getAlignment());
- // If the last non-virtual base has a vbptr we add a byte of padding for no
- // obvious reason.
- if (LastNonVirtualBaseHasVBPtr)
- Size++;
- Bases.insert(std::make_pair(LazyEmptyBase, Size));
- // Empty bases only consume space when followed by another empty base.
- if (RD && Layout->getNonVirtualSize().isZero()) {
- LastBaseWasEmpty = true;
- Size++;
}
- LazyEmptyBase = 0;
- LastNonVirtualBaseHasVBPtr = false;
- }
-
- // RD is null when flushing the final lazy base.
- if (!RD)
- return;
-
- if (Layout->getNonVirtualSize().isZero()) {
- LazyEmptyBase = RD;
- return;
+ // If this is the first layout, check to see if it leads with a zero sized
+ // object. If it does, so do we.
+ if (CheckLeadingLayout) {
+ CheckLeadingLayout = false;
+ LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase();
+ }
+ // Lay out the base.
+ layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout);
+ VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize();
}
-
- // Insert the base here.
- CharUnits BaseOffset = Size.RoundUpToAlignment(Layout->getAlignment());
- Bases.insert(std::make_pair(RD, BaseOffset));
- Size = BaseOffset + Layout->getDataSize();
- // Note: we don't update alignment here because it was accounted
- // for during initalization.
- LastBaseWasEmpty = false;
- LastNonVirtualBaseHasVBPtr = Layout->hasVBPtr();
-}
-
-void MicrosoftRecordLayoutBuilder::layoutVBPtr(const CXXRecordDecl *RD) {
+ // Set our VBPtroffset if we know it at this point.
if (!HasVBPtr)
VBPtrOffset = CharUnits::fromQuantity(-1);
else if (SharedVBPtrBase) {
const ASTRecordLayout &Layout = Context.getASTRecordLayout(SharedVBPtrBase);
VBPtrOffset = Bases[SharedVBPtrBase] + Layout.getVBPtrOffset();
- } else {
- VBPtrOffset = Size.RoundUpToAlignment(PointerAlignment);
- CharUnits OldSize = Size;
- Size = VBPtrOffset + PointerSize;
- if (BasesAndFieldsAlignment <= PointerAlignment) {
- // Handle strange padding rules for the lazily placed base. I have no
- // explanation for why the last virtual base is padded in such an odd way.
- // Two things to note about this padding are that the rules are different
- // if the alignment of the bases+fields is <= to the alignemnt of a
- // pointer and that the rule in 64-bit mode behaves differently depending
- // on if the second to last base was also zero sized.
- Size += OldSize % BasesAndFieldsAlignment.getQuantity();
- } else {
- if (Is64BitMode)
- Size += LastBaseWasEmpty ? CharUnits::One() : CharUnits::Zero();
- else
- Size = OldSize + BasesAndFieldsAlignment;
- }
- updateAlignment(PointerAlignment);
}
+}
- // Flush the lazy empty base.
- layoutNonVirtualBase(0);
+void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
+ const CXXRecordDecl *BaseDecl,
+ const ASTRecordLayout &BaseLayout,
+ const ASTRecordLayout *&PreviousBaseLayout) {
+ // Insert padding between two bases if the left first one is zero sized or
+ // contains a zero sized subobject and the right is zero sized or one leads
+ // with a zero sized base.
+ if (PreviousBaseLayout && PreviousBaseLayout->hasZeroSizedSubObject() &&
+ BaseLayout.leadsWithZeroSizedBase())
+ Size++;
+ ElementInfo Info = getAdjustedElementInfo(BaseLayout);
+ CharUnits BaseOffset = Size.RoundUpToAlignment(Info.Alignment);
+ Bases.insert(std::make_pair(BaseDecl, BaseOffset));
+ Size = BaseOffset + BaseLayout.getNonVirtualSize();
+ PreviousBaseLayout = &BaseLayout;
}
void MicrosoftRecordLayoutBuilder::layoutFields(const RecordDecl *RD) {
LastFieldIsNonZeroWidthBitfield = false;
- for (RecordDecl::field_iterator Field = RD->field_begin(),
- FieldEnd = RD->field_end();
- Field != FieldEnd; ++Field)
- layoutField(*Field);
- Size = Size.RoundUpToAlignment(Alignment);
+ for (const FieldDecl *Field : RD->fields())
+ layoutField(Field);
}
void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) {
@@ -2415,20 +2465,15 @@ void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) {
return;
}
LastFieldIsNonZeroWidthBitfield = false;
-
- std::pair<CharUnits, CharUnits> FieldInfo = getAdjustedFieldInfo(FD);
- CharUnits FieldSize = FieldInfo.first;
- CharUnits FieldAlign = FieldInfo.second;
-
- updateAlignment(FieldAlign);
+ ElementInfo Info = getAdjustedElementInfo(FD);
+ Alignment = std::max(Alignment, Info.Alignment);
if (IsUnion) {
- placeFieldAtZero();
- Size = std::max(Size, FieldSize);
+ placeFieldAtOffset(CharUnits::Zero());
+ Size = std::max(Size, Info.Size);
} else {
- // Round up the current record size to the field's alignment boundary.
- CharUnits FieldOffset = Size.RoundUpToAlignment(FieldAlign);
+ CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
placeFieldAtOffset(FieldOffset);
- Size = FieldOffset + FieldSize;
+ Size = FieldOffset + Info.Size;
}
}
@@ -2438,39 +2483,33 @@ void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) {
layoutZeroWidthBitField(FD);
return;
}
-
- std::pair<CharUnits, CharUnits> FieldInfo = getAdjustedFieldInfo(FD);
- CharUnits FieldSize = FieldInfo.first;
- CharUnits FieldAlign = FieldInfo.second;
-
+ ElementInfo Info = getAdjustedElementInfo(FD);
// Clamp the bitfield to a containable size for the sake of being able
// to lay them out. Sema will throw an error.
- if (Width > Context.toBits(FieldSize))
- Width = Context.toBits(FieldSize);
-
+ if (Width > Context.toBits(Info.Size))
+ Width = Context.toBits(Info.Size);
// Check to see if this bitfield fits into an existing allocation. Note:
// MSVC refuses to pack bitfields of formal types with different sizes
// into the same allocation.
if (!IsUnion && LastFieldIsNonZeroWidthBitfield &&
- CurrentBitfieldSize == FieldSize && Width <= RemainingBitsInField) {
+ CurrentBitfieldSize == Info.Size && Width <= RemainingBitsInField) {
placeFieldAtBitOffset(Context.toBits(Size) - RemainingBitsInField);
RemainingBitsInField -= Width;
return;
}
-
LastFieldIsNonZeroWidthBitfield = true;
- CurrentBitfieldSize = FieldSize;
+ CurrentBitfieldSize = Info.Size;
if (IsUnion) {
- placeFieldAtZero();
- Size = std::max(Size, FieldSize);
+ placeFieldAtOffset(CharUnits::Zero());
+ Size = std::max(Size, Info.Size);
// TODO: Add a Sema warning that MS ignores bitfield alignment in unions.
} else {
// Allocate a new block of memory and place the bitfield in it.
- CharUnits FieldOffset = Size.RoundUpToAlignment(FieldAlign);
+ CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
placeFieldAtOffset(FieldOffset);
- Size = FieldOffset + FieldSize;
- updateAlignment(FieldAlign);
- RemainingBitsInField = Context.toBits(FieldSize) - Width;
+ Size = FieldOffset + Info.Size;
+ Alignment = std::max(Alignment, Info.Alignment);
+ RemainingBitsInField = Context.toBits(Info.Size) - Width;
}
}
@@ -2478,201 +2517,220 @@ void
MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(const FieldDecl *FD) {
// Zero-width bitfields are ignored unless they follow a non-zero-width
// bitfield.
- std::pair<CharUnits, CharUnits> FieldInfo = getAdjustedFieldInfo(FD);
- CharUnits FieldSize = FieldInfo.first;
- CharUnits FieldAlign = FieldInfo.second;
-
if (!LastFieldIsNonZeroWidthBitfield) {
placeFieldAtOffset(IsUnion ? CharUnits::Zero() : Size);
// TODO: Add a Sema warning that MS ignores alignment for zero
- // sized bitfields that occur after zero-size bitfields or non bitfields.
+ // sized bitfields that occur after zero-size bitfields or non-bitfields.
return;
}
-
LastFieldIsNonZeroWidthBitfield = false;
+ ElementInfo Info = getAdjustedElementInfo(FD);
if (IsUnion) {
- placeFieldAtZero();
- Size = std::max(Size, FieldSize);
+ placeFieldAtOffset(CharUnits::Zero());
+ Size = std::max(Size, Info.Size);
+ // TODO: Add a Sema warning that MS ignores bitfield alignment in unions.
} else {
// Round up the current record size to the field's alignment boundary.
- CharUnits FieldOffset = Size.RoundUpToAlignment(FieldAlign);
+ CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
placeFieldAtOffset(FieldOffset);
Size = FieldOffset;
- updateAlignment(FieldAlign);
+ Alignment = std::max(Alignment, Info.Alignment);
}
}
+void MicrosoftRecordLayoutBuilder::injectVBPtr(const CXXRecordDecl *RD) {
+ if (!HasVBPtr || SharedVBPtrBase)
+ return;
+ // Inject the VBPointer at the injection site.
+ CharUnits InjectionSite = VBPtrOffset;
+ // But before we do, make sure it's properly aligned.
+ VBPtrOffset = VBPtrOffset.RoundUpToAlignment(PointerInfo.Alignment);
+ // Determine where the first field should be laid out after the vbptr.
+ CharUnits FieldStart = VBPtrOffset + PointerInfo.Size;
+ // Make sure that the amount we push the fields back by is a multiple of the
+ // alignment.
+ CharUnits Offset = (FieldStart - InjectionSite).RoundUpToAlignment(
+ std::max(RequiredAlignment, Alignment));
+ // Increase the size of the object and push back all fields by the offset
+ // amount.
+ Size += Offset;
+ for (uint64_t &FieldOffset : FieldOffsets)
+ FieldOffset += Context.toBits(Offset);
+ for (BaseOffsetsMapTy::value_type &Base : Bases)
+ if (Base.second >= InjectionSite)
+ Base.second += Offset;
+}
+
+void MicrosoftRecordLayoutBuilder::injectVFPtr(const CXXRecordDecl *RD) {
+ if (!HasOwnVFPtr)
+ return;
+ // Make sure that the amount we push the struct back by is a multiple of the
+ // alignment.
+ CharUnits Offset = PointerInfo.Size.RoundUpToAlignment(
+ std::max(RequiredAlignment, Alignment));
+ // Increase the size of the object and push back all fields, the vbptr and all
+ // bases by the offset amount.
+ Size += Offset;
+ for (uint64_t &FieldOffset : FieldOffsets)
+ FieldOffset += Context.toBits(Offset);
+ if (HasVBPtr)
+ VBPtrOffset += Offset;
+ for (BaseOffsetsMapTy::value_type &Base : Bases)
+ Base.second += Offset;
+}
+
void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) {
if (!HasVBPtr)
return;
-
- updateAlignment(VirtualAlignment);
-
- // Zero-sized v-bases obey the alignment attribute so apply it here. The
- // alignment attribute is normally accounted for in FinalizeLayout.
- if (unsigned MaxAlign = RD->getMaxAlignment())
- updateAlignment(Context.toCharUnitsFromBits(MaxAlign));
-
- llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordisp =
+ // Vtordisps are always 4 bytes (even in 64-bit mode)
+ CharUnits VtorDispSize = CharUnits::fromQuantity(4);
+ CharUnits VtorDispAlignment = VtorDispSize;
+ // vtordisps respect pragma pack.
+ if (!MaxFieldAlignment.isZero())
+ VtorDispAlignment = std::min(VtorDispAlignment, MaxFieldAlignment);
+ // The alignment of the vtordisp is at least the required alignment of the
+ // entire record. This requirement may be present to support vtordisp
+ // injection.
+ for (const CXXBaseSpecifier &VBase : RD->vbases()) {
+ const CXXRecordDecl *BaseDecl = VBase.getType()->getAsCXXRecordDecl();
+ const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+ RequiredAlignment =
+ std::max(RequiredAlignment, BaseLayout.getRequiredAlignment());
+ }
+ VtorDispAlignment = std::max(VtorDispAlignment, RequiredAlignment);
+ // Compute the vtordisp set.
+ llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordispSet =
computeVtorDispSet(RD);
-
- // If the last field we laid out was a non-zero length bitfield then add some
- // extra padding for no obvious reason.
- if (LastFieldIsNonZeroWidthBitfield)
- Size += CurrentBitfieldSize;
-
// Iterate through the virtual bases and lay them out.
- for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
- e = RD->vbases_end();
- i != e; ++i) {
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(i->getType()->castAs<RecordType>()->getDecl());
- layoutVirtualBase(BaseDecl, HasVtordisp.count(BaseDecl));
- }
-}
-
-void MicrosoftRecordLayoutBuilder::layoutVirtualBase(const CXXRecordDecl *RD,
- bool HasVtordisp) {
- if (LazyEmptyBase) {
- const ASTRecordLayout &LazyLayout =
- Context.getASTRecordLayout(LazyEmptyBase);
- Size = Size.RoundUpToAlignment(LazyLayout.getAlignment());
- VBases.insert(
- std::make_pair(LazyEmptyBase, ASTRecordLayout::VBaseInfo(Size, false)));
- // Empty bases only consume space when followed by another empty base.
- // The space consumed is in an Alignment sized/aligned block and the v-base
- // is placed at its alignment offset into the chunk, unless its alignment
- // is less than 4 bytes, at which it is placed at 4 byte offset in the
- // chunk. We have no idea why.
- if (RD && Context.getASTRecordLayout(RD).getNonVirtualSize().isZero())
- Size = Size.RoundUpToAlignment(Alignment) + CharUnits::fromQuantity(4);
- LazyEmptyBase = 0;
- }
-
- // RD is null when flushing the final lazy virtual base.
- if (!RD)
- return;
-
- const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- if (Layout.getNonVirtualSize().isZero() && !HasVtordisp) {
- LazyEmptyBase = RD;
- return;
+ const ASTRecordLayout *PreviousBaseLayout = nullptr;
+ for (const CXXBaseSpecifier &VBase : RD->vbases()) {
+ const CXXRecordDecl *BaseDecl = VBase.getType()->getAsCXXRecordDecl();
+ const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+ bool HasVtordisp = HasVtordispSet.count(BaseDecl);
+ // Insert padding between two bases if the left first one is zero sized or
+ // contains a zero sized subobject and the right is zero sized or one leads
+ // with a zero sized base. The padding between virtual bases is 4
+ // bytes (in both 32 and 64 bits modes) and always involves rounding up to
+ // the required alignment, we don't know why.
+ if ((PreviousBaseLayout && PreviousBaseLayout->hasZeroSizedSubObject() &&
+ BaseLayout.leadsWithZeroSizedBase()) || HasVtordisp) {
+ Size = Size.RoundUpToAlignment(VtorDispAlignment) + VtorDispSize;
+ Alignment = std::max(VtorDispAlignment, Alignment);
+ }
+ // Insert the virtual base.
+ ElementInfo Info = getAdjustedElementInfo(BaseLayout);
+ CharUnits BaseOffset = Size.RoundUpToAlignment(Info.Alignment);
+ VBases.insert(std::make_pair(BaseDecl,
+ ASTRecordLayout::VBaseInfo(BaseOffset, HasVtordisp)));
+ Size = BaseOffset + BaseLayout.getNonVirtualSize();
+ PreviousBaseLayout = &BaseLayout;
}
-
- CharUnits BaseNVSize = Layout.getNonVirtualSize();
- CharUnits BaseAlign = Layout.getAlignment();
-
- // vtordisps are always 4 bytes (even in 64-bit mode)
- if (HasVtordisp)
- Size = Size.RoundUpToAlignment(Alignment) + CharUnits::fromQuantity(4);
- Size = Size.RoundUpToAlignment(BaseAlign);
-
- // Insert the base here.
- CharUnits BaseOffset = Size.RoundUpToAlignment(BaseAlign);
- VBases.insert(
- std::make_pair(RD, ASTRecordLayout::VBaseInfo(BaseOffset, HasVtordisp)));
- Size = BaseOffset + BaseNVSize;
- // Note: we don't update alignment here because it was accounted for in
- // InitializeLayout.
}
-void MicrosoftRecordLayoutBuilder::finalizeCXXLayout(const CXXRecordDecl *RD) {
- // Flush the lazy virtual base.
- layoutVirtualBase(0, false);
-
- if (RD->vbases_begin() == RD->vbases_end() || AlignAfterVBases)
- Size = Size.RoundUpToAlignment(Alignment);
-
- if (Size.isZero())
+void MicrosoftRecordLayoutBuilder::finalizeLayout(const RecordDecl *RD) {
+ // Respect required alignment. Note that in 32-bit mode Required alignment
+ // may be 0 nad cause size not to be updated.
+ DataSize = Size;
+ if (!RequiredAlignment.isZero()) {
+ Alignment = std::max(Alignment, RequiredAlignment);
+ auto RoundingAlignment = Alignment;
+ if (!MaxFieldAlignment.isZero())
+ RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment);
+ RoundingAlignment = std::max(RoundingAlignment, RequiredAlignment);
+ Size = Size.RoundUpToAlignment(RoundingAlignment);
+ }
+ // Zero-sized structures have size equal to their alignment.
+ if (Size.isZero()) {
+ EndsWithZeroSizedObject = true;
+ LeadsWithZeroSizedBase = true;
Size = Alignment;
-}
-
-void MicrosoftRecordLayoutBuilder::honorDeclspecAlign(const RecordDecl *RD) {
- if (unsigned MaxAlign = RD->getMaxAlignment()) {
- AlignAfterVBases = true;
- updateAlignment(Context.toCharUnitsFromBits(MaxAlign));
- Size = Size.RoundUpToAlignment(Alignment);
}
}
+// Recursively walks the non-virtual bases of a class and determines if any of
+// them are in the bases with overridden methods set.
static bool
-RequiresVtordisp(const llvm::SmallPtrSet<const CXXRecordDecl *, 2> &HasVtordisp,
+RequiresVtordisp(const llvm::SmallPtrSetImpl<const CXXRecordDecl *> &
+ BasesWithOverriddenMethods,
const CXXRecordDecl *RD) {
- if (HasVtordisp.count(RD))
+ if (BasesWithOverriddenMethods.count(RD))
return true;
// If any of a virtual bases non-virtual bases (recursively) requires a
// vtordisp than so does this virtual base.
- for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
- e = RD->bases_end();
- i != e; ++i)
- if (!i->isVirtual() &&
- RequiresVtordisp(
- HasVtordisp,
- cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl())))
+ for (const CXXBaseSpecifier &Base : RD->bases())
+ if (!Base.isVirtual() &&
+ RequiresVtordisp(BasesWithOverriddenMethods,
+ Base.getType()->getAsCXXRecordDecl()))
return true;
return false;
}
llvm::SmallPtrSet<const CXXRecordDecl *, 2>
MicrosoftRecordLayoutBuilder::computeVtorDispSet(const CXXRecordDecl *RD) {
- llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordisp;
+ llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordispSet;
+
+ // /vd2 or #pragma vtordisp(2): Always use vtordisps for virtual bases with
+ // vftables.
+ if (RD->getMSVtorDispMode() == MSVtorDispAttr::ForVFTable) {
+ for (const CXXBaseSpecifier &Base : RD->vbases()) {
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
+ if (Layout.hasExtendableVFPtr())
+ HasVtordispSet.insert(BaseDecl);
+ }
+ return HasVtordispSet;
+ }
// If any of our bases need a vtordisp for this type, so do we. Check our
// direct bases for vtordisp requirements.
- for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
- e = RD->bases_end();
- i != e; ++i) {
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+ for (const CXXBaseSpecifier &Base : RD->bases()) {
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
- for (ASTRecordLayout::VBaseOffsetsMapTy::const_iterator
- bi = Layout.getVBaseOffsetsMap().begin(),
- be = Layout.getVBaseOffsetsMap().end();
- bi != be; ++bi)
- if (bi->second.hasVtorDisp())
- HasVtordisp.insert(bi->first);
- }
-
- // If we define a constructor or destructor and override a function that is
- // defined in a virtual base's vtable, that virtual bases need a vtordisp.
- // Here we collect a list of classes with vtables for which our virtual bases
- // actually live. The virtual bases with this property will require
- // vtordisps. In addition, virtual bases that contain non-virtual bases that
- // define functions we override also require vtordisps, this case is checked
- // explicitly below.
- if (RD->hasUserDeclaredConstructor() || RD->hasUserDeclaredDestructor()) {
- llvm::SmallPtrSet<const CXXMethodDecl *, 8> Work;
- // Seed the working set with our non-destructor virtual methods.
- for (CXXRecordDecl::method_iterator i = RD->method_begin(),
- e = RD->method_end();
- i != e; ++i)
- if ((*i)->isVirtual() && !isa<CXXDestructorDecl>(*i))
- Work.insert(*i);
- while (!Work.empty()) {
- const CXXMethodDecl *MD = *Work.begin();
- CXXMethodDecl::method_iterator i = MD->begin_overridden_methods(),
- e = MD->end_overridden_methods();
- if (i == e)
- // If a virtual method has no-overrides it lives in its parent's vtable.
- HasVtordisp.insert(MD->getParent());
- else
- Work.insert(i, e);
- // We've finished processing this element, remove it from the working set.
- Work.erase(MD);
- }
+ for (const auto &bi : Layout.getVBaseOffsetsMap())
+ if (bi.second.hasVtorDisp())
+ HasVtordispSet.insert(bi.first);
+ }
+ // We don't introduce any additional vtordisps if either:
+ // * A user declared constructor or destructor aren't declared.
+ // * #pragma vtordisp(0) or the /vd0 flag are in use.
+ if ((!RD->hasUserDeclaredConstructor() && !RD->hasUserDeclaredDestructor()) ||
+ RD->getMSVtorDispMode() == MSVtorDispAttr::Never)
+ return HasVtordispSet;
+ // /vd1 or #pragma vtordisp(1): Try to guess based on whether we think it's
+ // possible for a partially constructed object with virtual base overrides to
+ // escape a non-trivial constructor.
+ assert(RD->getMSVtorDispMode() == MSVtorDispAttr::ForVBaseOverride);
+ // Compute a set of base classes which define methods we override. A virtual
+ // base in this set will require a vtordisp. A virtual base that transitively
+ // contains one of these bases as a non-virtual base will also require a
+ // vtordisp.
+ llvm::SmallPtrSet<const CXXMethodDecl *, 8> Work;
+ llvm::SmallPtrSet<const CXXRecordDecl *, 2> BasesWithOverriddenMethods;
+ // Seed the working set with our non-destructor virtual methods.
+ for (const CXXMethodDecl *MD : RD->methods())
+ if (MD->isVirtual() && !isa<CXXDestructorDecl>(MD))
+ Work.insert(MD);
+ while (!Work.empty()) {
+ const CXXMethodDecl *MD = *Work.begin();
+ CXXMethodDecl::method_iterator i = MD->begin_overridden_methods(),
+ e = MD->end_overridden_methods();
+ // If a virtual method has no-overrides it lives in its parent's vtable.
+ if (i == e)
+ BasesWithOverriddenMethods.insert(MD->getParent());
+ else
+ Work.insert(i, e);
+ // We've finished processing this element, remove it from the working set.
+ Work.erase(MD);
}
-
- // Re-check all of our vbases for vtordisp requirements (in case their
- // non-virtual bases have vtordisp requirements).
- for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
- e = RD->vbases_end();
- i != e; ++i) {
- const CXXRecordDecl *BaseDecl = i->getType()->getAsCXXRecordDecl();
- if (!HasVtordisp.count(BaseDecl) && RequiresVtordisp(HasVtordisp, BaseDecl))
- HasVtordisp.insert(BaseDecl);
+ // For each of our virtual bases, check if it is in the set of overridden
+ // bases or if it transitively contains a non-virtual base that is.
+ for (const CXXBaseSpecifier &Base : RD->vbases()) {
+ const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+ if (!HasVtordispSet.count(BaseDecl) &&
+ RequiresVtordisp(BasesWithOverriddenMethods, BaseDecl))
+ HasVtordispSet.insert(BaseDecl);
}
-
- return HasVtordisp;
+ return HasVtordispSet;
}
/// \brief Get or compute information about the layout of the specified record
@@ -2684,19 +2742,20 @@ ASTContext::BuildMicrosoftASTRecordLayout(const RecordDecl *D) const {
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
Builder.cxxLayout(RD);
return new (*this) ASTRecordLayout(
- *this, Builder.Size, Builder.Alignment,
- Builder.HasExtendableVFPtr && !Builder.PrimaryBase,
- Builder.HasExtendableVFPtr,
- Builder.VBPtrOffset, Builder.DataSize, Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size(), Builder.DataSize,
- Builder.NonVirtualAlignment, CharUnits::Zero(), Builder.PrimaryBase,
- false, Builder.SharedVBPtrBase, Builder.AlignAfterVBases, Builder.Bases,
- Builder.VBases);
+ *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
+ Builder.HasOwnVFPtr,
+ Builder.HasOwnVFPtr || Builder.PrimaryBase,
+ Builder.VBPtrOffset, Builder.NonVirtualSize, Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size(), Builder.NonVirtualSize,
+ Builder.Alignment, CharUnits::Zero(), Builder.PrimaryBase,
+ false, Builder.SharedVBPtrBase,
+ Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
+ Builder.Bases, Builder.VBases);
} else {
Builder.layout(D);
return new (*this) ASTRecordLayout(
- *this, Builder.Size, Builder.Alignment, Builder.Size,
- Builder.FieldOffsets.data(), Builder.FieldOffsets.size());
+ *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
+ Builder.Size, Builder.FieldOffsets.data(), Builder.FieldOffsets.size());
}
}
@@ -2724,7 +2783,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
const ASTRecordLayout *Entry = ASTRecordLayouts[D];
if (Entry) return *Entry;
- const ASTRecordLayout *NewEntry = 0;
+ const ASTRecordLayout *NewEntry = nullptr;
if (isMsLayout(D) && !D->getASTContext().getExternalSource()) {
NewEntry = BuildMicrosoftASTRecordLayout(D);
@@ -2747,6 +2806,8 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
NewEntry =
new (*this) ASTRecordLayout(*this, Builder.getSize(),
Builder.Alignment,
+ /*RequiredAlignment : used by MS-ABI)*/
+ Builder.Alignment,
Builder.HasOwnVFPtr,
RD->isDynamicClass(),
CharUnits::fromQuantity(-1),
@@ -2758,15 +2819,17 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
EmptySubobjects.SizeOfLargestEmptySubobject,
Builder.PrimaryBase,
Builder.PrimaryBaseIsVirtual,
- 0, true,
+ nullptr, false, false,
Builder.Bases, Builder.VBases);
} else {
- RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
+ RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
Builder.Layout(D);
NewEntry =
new (*this) ASTRecordLayout(*this, Builder.getSize(),
Builder.Alignment,
+ /*RequiredAlignment : used by MS-ABI)*/
+ Builder.Alignment,
Builder.getSize(),
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
@@ -2784,16 +2847,25 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
const CXXMethodDecl *ASTContext::getCurrentKeyFunction(const CXXRecordDecl *RD) {
if (!getTargetInfo().getCXXABI().hasKeyFunctions())
- return 0;
+ return nullptr;
assert(RD->getDefinition() && "Cannot get key function for forward decl!");
RD = cast<CXXRecordDecl>(RD->getDefinition());
- LazyDeclPtr &Entry = KeyFunctions[RD];
- if (!Entry)
- Entry = const_cast<CXXMethodDecl*>(computeKeyFunction(*this, RD));
+ // Beware:
+ // 1) computing the key function might trigger deserialization, which might
+ // invalidate iterators into KeyFunctions
+ // 2) 'get' on the LazyDeclPtr might also trigger deserialization and
+ // invalidate the LazyDeclPtr within the map itself
+ LazyDeclPtr Entry = KeyFunctions[RD];
+ const Decl *Result =
+ Entry ? Entry.get(getExternalSource()) : computeKeyFunction(*this, RD);
+
+ // Store it back if it changed.
+ if (Entry.isOffset() || Entry.isValid() != bool(Result))
+ KeyFunctions[RD] = const_cast<Decl*>(Result);
- return cast_or_null<CXXMethodDecl>(Entry.get(getExternalSource()));
+ return cast_or_null<CXXMethodDecl>(Result);
}
void ASTContext::setNonKeyFunction(const CXXMethodDecl *Method) {
@@ -2810,10 +2882,12 @@ void ASTContext::setNonKeyFunction(const CXXMethodDecl *Method) {
if (I == KeyFunctions.end()) return;
// If it is cached, check whether it's the target method, and if so,
- // remove it from the cache.
- if (I->second.get(getExternalSource()) == Method) {
+ // remove it from the cache. Note, the call to 'get' might invalidate
+ // the iterator and the LazyDeclPtr object within the map.
+ LazyDeclPtr Ptr = I->second;
+ if (Ptr.get(getExternalSource()) == Method) {
// FIXME: remember that we did this for module / chained PCH state?
- KeyFunctions.erase(I);
+ KeyFunctions.erase(Method->getParent());
}
}
@@ -2830,10 +2904,8 @@ uint64_t ASTContext::getFieldOffset(const ValueDecl *VD) const {
const IndirectFieldDecl *IFD = cast<IndirectFieldDecl>(VD);
OffsetInBits = 0;
- for (IndirectFieldDecl::chain_iterator CI = IFD->chain_begin(),
- CE = IFD->chain_end();
- CI != CE; ++CI)
- OffsetInBits += ::getFieldOffset(*this, cast<FieldDecl>(*CI));
+ for (const NamedDecl *ND : IFD->chain())
+ OffsetInBits += ::getFieldOffset(*this, cast<FieldDecl>(ND));
}
return OffsetInBits;
@@ -2867,15 +2939,17 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
// entries later; however we shouldn't look up implementations
// frequently.
if (SynthCount == 0)
- return getObjCLayout(D, 0);
+ return getObjCLayout(D, nullptr);
}
- RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
+ RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
Builder.Layout(D);
const ASTRecordLayout *NewEntry =
new (*this) ASTRecordLayout(*this, Builder.getSize(),
Builder.Alignment,
+ /*RequiredAlignment : used by MS-ABI)*/
+ Builder.Alignment,
Builder.getDataSize(),
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
@@ -2928,19 +3002,24 @@ static void DumpCXXRecordLayout(raw_ostream &OS,
OS << '(' << *RD << " vftable pointer)\n";
}
- // Dump (non-virtual) bases
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- assert(!I->getType()->isDependentType() &&
+ // Collect nvbases.
+ SmallVector<const CXXRecordDecl *, 4> Bases;
+ for (const CXXBaseSpecifier &Base : RD->bases()) {
+ assert(!Base.getType()->isDependentType() &&
"Cannot layout class with dependent bases.");
- if (I->isVirtual())
- continue;
+ if (!Base.isVirtual())
+ Bases.push_back(Base.getType()->getAsCXXRecordDecl());
+ }
- const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ // Sort nvbases by offset.
+ std::stable_sort(Bases.begin(), Bases.end(),
+ [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {
+ return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);
+ });
+ // Dump (non-virtual) bases
+ for (const CXXRecordDecl *Base : Bases) {
CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base);
-
DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
Base == PrimaryBase ? "(primary base)" : "(base)",
/*IncludeVirtualBases=*/false);
@@ -2960,13 +3039,11 @@ static void DumpCXXRecordLayout(raw_ostream &OS,
CharUnits FieldOffset = Offset +
C.toCharUnitsFromBits(Layout.getFieldOffset(FieldNo));
- if (const RecordType *RT = Field.getType()->getAs<RecordType>()) {
- if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel,
- Field.getName().data(),
- /*IncludeVirtualBases=*/true);
- continue;
- }
+ if (const CXXRecordDecl *D = Field.getType()->getAsCXXRecordDecl()) {
+ DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel,
+ Field.getName().data(),
+ /*IncludeVirtualBases=*/true);
+ continue;
}
PrintOffset(OS, FieldOffset, IndentLevel);
@@ -2979,11 +3056,9 @@ static void DumpCXXRecordLayout(raw_ostream &OS,
// Dump virtual bases.
const ASTRecordLayout::VBaseOffsetsMapTy &vtordisps =
Layout.getVBaseOffsetsMap();
- for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
- E = RD->vbases_end(); I != E; ++I) {
- assert(I->isVirtual() && "Found non-virtual class!");
- const CXXRecordDecl *VBase =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ for (const CXXBaseSpecifier &Base : RD->vbases()) {
+ assert(Base.isVirtual() && "Found non-virtual class!");
+ const CXXRecordDecl *VBase = Base.getType()->getAsCXXRecordDecl();
CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase);
@@ -3006,8 +3081,7 @@ static void DumpCXXRecordLayout(raw_ostream &OS,
PrintIndentNoOffset(OS, IndentLevel - 1);
OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity();
- OS << ", nvalign=" << Layout.getNonVirtualAlign().getQuantity() << "]\n";
- OS << '\n';
+ OS << ", nvalign=" << Layout.getNonVirtualAlignment().getQuantity() << "]\n";
}
void ASTContext::DumpRecordLayout(const RecordDecl *RD,
@@ -3017,7 +3091,7 @@ void ASTContext::DumpRecordLayout(const RecordDecl *RD,
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
if (!Simple)
- return DumpCXXRecordLayout(OS, CXXRD, *this, CharUnits(), 0, 0,
+ return DumpCXXRecordLayout(OS, CXXRD, *this, CharUnits(), 0, nullptr,
/*IncludeVirtualBases=*/true);
OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n";
diff --git a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp
index de85161..a8483dc 100644
--- a/contrib/llvm/tools/clang/lib/AST/Stmt.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/Stmt.cpp
@@ -65,13 +65,13 @@ void Stmt::PrintStats() {
unsigned sum = 0;
llvm::errs() << "\n*** Stmt/Expr Stats:\n";
for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
- if (StmtClassInfo[i].Name == 0) continue;
+ if (StmtClassInfo[i].Name == nullptr) continue;
sum += StmtClassInfo[i].Counter;
}
llvm::errs() << " " << sum << " stmts/exprs total.\n";
sum = 0;
for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
- if (StmtClassInfo[i].Name == 0) continue;
+ if (StmtClassInfo[i].Name == nullptr) continue;
if (StmtClassInfo[i].Counter == 0) continue;
llvm::errs() << " " << StmtClassInfo[i].Counter << " "
<< StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size
@@ -260,7 +260,7 @@ CompoundStmt::CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
"NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
if (Stmts.size() == 0) {
- Body = 0;
+ Body = nullptr;
return;
}
@@ -285,8 +285,8 @@ const char *LabelStmt::getName() const {
AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc,
ArrayRef<const Attr*> Attrs,
Stmt *SubStmt) {
- void *Mem = C.Allocate(sizeof(AttributedStmt) +
- sizeof(Attr*) * (Attrs.size() - 1),
+ assert(!Attrs.empty() && "Attrs should not be empty");
+ void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * Attrs.size(),
llvm::alignOf<AttributedStmt>());
return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);
}
@@ -294,8 +294,7 @@ AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc,
AttributedStmt *AttributedStmt::CreateEmpty(const ASTContext &C,
unsigned NumAttrs) {
assert(NumAttrs > 0 && "NumAttrs should be greater than zero");
- void *Mem = C.Allocate(sizeof(AttributedStmt) +
- sizeof(Attr*) * (NumAttrs - 1),
+ void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * NumAttrs,
llvm::alignOf<AttributedStmt>());
return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);
}
@@ -554,7 +553,7 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
// Find the ']'.
const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
- if (NameEnd == 0)
+ if (NameEnd == nullptr)
return diag::err_asm_unterminated_symbolic_operand_name;
if (NameEnd == CurPtr)
return diag::err_asm_empty_symbolic_operand_name;
@@ -720,8 +719,7 @@ ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
Stmt **CatchStmts, unsigned NumCatchStmts,
Stmt *atFinallyStmt)
: Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc),
- NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0)
-{
+ NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != nullptr) {
Stmt **Stmts = getStmts();
Stmts[0] = atTryStmt;
for (unsigned I = 0; I != NumCatchStmts; ++I)
@@ -738,7 +736,7 @@ ObjCAtTryStmt *ObjCAtTryStmt::Create(const ASTContext &Context,
unsigned NumCatchStmts,
Stmt *atFinallyStmt) {
unsigned Size = sizeof(ObjCAtTryStmt) +
- (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *);
+ (1 + NumCatchStmts + (atFinallyStmt != nullptr)) * sizeof(Stmt *);
void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
atFinallyStmt);
@@ -803,7 +801,7 @@ CXXForRangeStmt::CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEndStmt,
Expr *CXXForRangeStmt::getRangeInit() {
DeclStmt *RangeStmt = getRangeStmt();
VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
- assert(RangeDecl &&& "for-range should have a single var decl");
+ assert(RangeDecl && "for-range should have a single var decl");
return RangeDecl->getInit();
}
@@ -833,7 +831,7 @@ IfStmt::IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
VarDecl *IfStmt::getConditionVariable() const {
if (!SubExprs[VAR])
- return 0;
+ return nullptr;
DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
return cast<VarDecl>(DS->getSingleDecl());
@@ -841,7 +839,7 @@ VarDecl *IfStmt::getConditionVariable() const {
void IfStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
if (!V) {
- SubExprs[VAR] = 0;
+ SubExprs[VAR] = nullptr;
return;
}
@@ -864,7 +862,7 @@ ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
VarDecl *ForStmt::getConditionVariable() const {
if (!SubExprs[CONDVAR])
- return 0;
+ return nullptr;
DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
return cast<VarDecl>(DS->getSingleDecl());
@@ -872,7 +870,7 @@ VarDecl *ForStmt::getConditionVariable() const {
void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
if (!V) {
- SubExprs[CONDVAR] = 0;
+ SubExprs[CONDVAR] = nullptr;
return;
}
@@ -882,16 +880,16 @@ void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
}
SwitchStmt::SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond)
- : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0)
+ : Stmt(SwitchStmtClass), FirstCase(nullptr), AllEnumCasesCovered(0)
{
setConditionVariable(C, Var);
SubExprs[COND] = cond;
- SubExprs[BODY] = NULL;
+ SubExprs[BODY] = nullptr;
}
VarDecl *SwitchStmt::getConditionVariable() const {
if (!SubExprs[VAR])
- return 0;
+ return nullptr;
DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
return cast<VarDecl>(DS->getSingleDecl());
@@ -899,7 +897,7 @@ VarDecl *SwitchStmt::getConditionVariable() const {
void SwitchStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
if (!V) {
- SubExprs[VAR] = 0;
+ SubExprs[VAR] = nullptr;
return;
}
@@ -925,7 +923,7 @@ WhileStmt::WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
VarDecl *WhileStmt::getConditionVariable() const {
if (!SubExprs[VAR])
- return 0;
+ return nullptr;
DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
return cast<VarDecl>(DS->getSingleDecl());
@@ -933,7 +931,7 @@ VarDecl *WhileStmt::getConditionVariable() const {
void WhileStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
if (!V) {
- SubExprs[VAR] = 0;
+ SubExprs[VAR] = nullptr;
return;
}
@@ -947,7 +945,7 @@ LabelDecl *IndirectGotoStmt::getConstantTarget() {
if (AddrLabelExpr *E =
dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
return E->getLabel();
- return 0;
+ return nullptr;
}
// ReturnStmt
@@ -958,22 +956,20 @@ Expr* ReturnStmt::getRetValue() {
return cast_or_null<Expr>(RetExpr);
}
-SEHTryStmt::SEHTryStmt(bool IsCXXTry,
- SourceLocation TryLoc,
- Stmt *TryBlock,
- Stmt *Handler)
- : Stmt(SEHTryStmtClass),
- IsCXXTry(IsCXXTry),
- TryLoc(TryLoc)
-{
- Children[TRY] = TryBlock;
+SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
+ Stmt *Handler, int HandlerIndex, int HandlerParentIndex)
+ : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc),
+ HandlerIndex(HandlerIndex), HandlerParentIndex(HandlerParentIndex) {
+ Children[TRY] = TryBlock;
Children[HANDLER] = Handler;
}
-SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
+SEHTryStmt *SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
SourceLocation TryLoc, Stmt *TryBlock,
- Stmt *Handler) {
- return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
+ Stmt *Handler, int HandlerIndex,
+ int HandlerParentIndex) {
+ return new (C) SEHTryStmt(IsCXXTry, TryLoc, TryBlock, Handler, HandlerIndex,
+ HandlerParentIndex);
}
SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
@@ -1049,8 +1045,8 @@ CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
: Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
- CapDeclAndKind(0, CR_Default), TheRecordDecl(0) {
- getStoredStmts()[NumCaptures] = 0;
+ CapDeclAndKind(nullptr, CR_Default), TheRecordDecl(nullptr) {
+ getStoredStmts()[NumCaptures] = nullptr;
}
CapturedStmt *CapturedStmt::Create(const ASTContext &Context, Stmt *S,
@@ -1100,15 +1096,14 @@ Stmt::child_range CapturedStmt::children() {
}
bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
- for (const_capture_iterator I = capture_begin(),
- E = capture_end(); I != E; ++I) {
- if (!I->capturesVariable())
+ for (const auto &I : captures()) {
+ if (!I.capturesVariable())
continue;
// This does not handle variable redeclarations. This should be
// extended to capture variables with redeclarations, for example
// a thread-private variable in OpenMP.
- if (I->getCapturedVar() == Var)
+ if (I.getCapturedVar() == Var)
return true;
}
@@ -1130,8 +1125,9 @@ OMPPrivateClause *OMPPrivateClause::Create(const ASTContext &C,
SourceLocation LParenLoc,
SourceLocation EndLoc,
ArrayRef<Expr *> VL) {
- void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * VL.size(),
- llvm::alignOf<OMPPrivateClause>());
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
OMPPrivateClause *Clause = new (Mem) OMPPrivateClause(StartLoc, LParenLoc,
EndLoc, VL.size());
Clause->setVarRefs(VL);
@@ -1140,8 +1136,9 @@ OMPPrivateClause *OMPPrivateClause::Create(const ASTContext &C,
OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
unsigned N) {
- void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * N,
- llvm::alignOf<OMPPrivateClause>());
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
return new (Mem) OMPPrivateClause(N);
}
@@ -1150,9 +1147,9 @@ OMPFirstprivateClause *OMPFirstprivateClause::Create(const ASTContext &C,
SourceLocation LParenLoc,
SourceLocation EndLoc,
ArrayRef<Expr *> VL) {
- void *Mem = C.Allocate(sizeof(OMPFirstprivateClause) +
- sizeof(Expr *) * VL.size(),
- llvm::alignOf<OMPFirstprivateClause>());
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
OMPFirstprivateClause *Clause = new (Mem) OMPFirstprivateClause(StartLoc,
LParenLoc,
EndLoc,
@@ -1163,18 +1160,42 @@ OMPFirstprivateClause *OMPFirstprivateClause::Create(const ASTContext &C,
OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
unsigned N) {
- void *Mem = C.Allocate(sizeof(OMPFirstprivateClause) + sizeof(Expr *) * N,
- llvm::alignOf<OMPFirstprivateClause>());
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
return new (Mem) OMPFirstprivateClause(N);
}
+OMPLastprivateClause *OMPLastprivateClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPLastprivateClause *Clause =
+ new (Mem) OMPLastprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPLastprivateClause(N);
+}
+
OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc,
ArrayRef<Expr *> VL) {
- void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *) * VL.size(),
- llvm::alignOf<OMPSharedClause>());
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
OMPSharedClause *Clause = new (Mem) OMPSharedClause(StartLoc, LParenLoc,
EndLoc, VL.size());
Clause->setVarRefs(VL);
@@ -1183,15 +1204,148 @@ OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C,
unsigned N) {
- void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *) * N,
- llvm::alignOf<OMPSharedClause>());
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
return new (Mem) OMPSharedClause(N);
}
+OMPLinearClause *OMPLinearClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL, Expr *Step) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * (VL.size() + 1));
+ OMPLinearClause *Clause = new (Mem)
+ OMPLinearClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setStep(Step);
+ return Clause;
+}
+
+OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
+ unsigned NumVars) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * (NumVars + 1));
+ return new (Mem) OMPLinearClause(NumVars);
+}
+
+OMPAlignedClause *
+OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation ColonLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * (VL.size() + 1));
+ OMPAlignedClause *Clause = new (Mem)
+ OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ Clause->setAlignment(A);
+ return Clause;
+}
+
+OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
+ unsigned NumVars) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * (NumVars + 1));
+ return new (Mem) OMPAlignedClause(NumVars);
+}
+
+OMPCopyinClause *OMPCopyinClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPCopyinClause *Clause = new (Mem) OMPCopyinClause(StartLoc, LParenLoc,
+ EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPCopyinClause(N);
+}
+
+OMPCopyprivateClause *OMPCopyprivateClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPCopyprivateClause *Clause =
+ new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPCopyprivateClause(N);
+}
+
void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) {
- assert(Clauses.size() == this->Clauses.size() &&
+ assert(Clauses.size() == getNumClauses() &&
"Number of clauses is not the same as the preallocated buffer");
- std::copy(Clauses.begin(), Clauses.end(), this->Clauses.begin());
+ std::copy(Clauses.begin(), Clauses.end(), getClauses().begin());
+}
+
+OMPReductionClause *OMPReductionClause::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
+ NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPReductionClause *Clause = new (Mem) OMPReductionClause(
+ StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPReductionClause(N);
+}
+
+OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * VL.size());
+ OMPFlushClause *Clause =
+ new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
+ void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
+ llvm::alignOf<Expr *>()) +
+ sizeof(Expr *) * N);
+ return new (Mem) OMPFlushClause(N);
}
OMPParallelDirective *OMPParallelDirective::Create(
@@ -1200,9 +1354,10 @@ OMPParallelDirective *OMPParallelDirective::Create(
SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt) {
- void *Mem = C.Allocate(sizeof(OMPParallelDirective) +
- sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *),
- llvm::alignOf<OMPParallelDirective>());
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
+ sizeof(Stmt *));
OMPParallelDirective *Dir = new (Mem) OMPParallelDirective(StartLoc, EndLoc,
Clauses.size());
Dir->setClauses(Clauses);
@@ -1211,10 +1366,315 @@ OMPParallelDirective *OMPParallelDirective::Create(
}
OMPParallelDirective *OMPParallelDirective::CreateEmpty(const ASTContext &C,
- unsigned N,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
+ sizeof(Stmt *));
+ return new (Mem) OMPParallelDirective(NumClauses);
+}
+
+OMPSimdDirective *
+OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPSimdDirective *Dir = new (Mem)
+ OMPSimdDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPSimdDirective *OMPSimdDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPSimdDirective(CollapsedNum, NumClauses);
+}
+
+OMPForDirective *
+OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPForDirective *Dir =
+ new (Mem) OMPForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPForDirective *OMPForDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPForDirective(CollapsedNum, NumClauses);
+}
+
+OMPSectionsDirective *OMPSectionsDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPSectionsDirective *Dir =
+ new (Mem) OMPSectionsDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPSectionsDirective *OMPSectionsDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPSectionsDirective(NumClauses);
+}
+
+OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPSectionDirective *OMPSectionDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ return new (Mem) OMPSectionDirective();
+}
+
+OMPSingleDirective *OMPSingleDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPSingleDirective *Dir =
+ new (Mem) OMPSingleDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPSingleDirective *OMPSingleDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPSingleDirective(NumClauses);
+}
+
+OMPMasterDirective *OMPMasterDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ OMPMasterDirective *Dir = new (Mem) OMPMasterDirective(StartLoc, EndLoc);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPMasterDirective *OMPMasterDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ return new (Mem) OMPMasterDirective();
+}
+
+OMPCriticalDirective *OMPCriticalDirective::Create(
+ const ASTContext &C, const DeclarationNameInfo &Name,
+ SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ OMPCriticalDirective *Dir =
+ new (Mem) OMPCriticalDirective(Name, StartLoc, EndLoc);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPCriticalDirective *OMPCriticalDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
+ llvm::alignOf<Stmt *>());
+ void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ return new (Mem) OMPCriticalDirective();
+}
+
+OMPParallelForDirective *
+OMPParallelForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPParallelForDirective *Dir = new (Mem)
+ OMPParallelForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPParallelForDirective *
+OMPParallelForDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
+ unsigned CollapsedNum, EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPParallelForDirective(CollapsedNum, NumClauses);
+}
+
+OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPParallelSectionsDirective *Dir =
+ new (Mem) OMPParallelSectionsDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPParallelSectionsDirective *
+OMPParallelSectionsDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPParallelSectionsDirective(NumClauses);
+}
+
+OMPTaskDirective *OMPTaskDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+ OMPTaskDirective *Dir =
+ new (Mem) OMPTaskDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
+ return Dir;
+}
+
+OMPTaskDirective *OMPTaskDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+ return new (Mem) OMPTaskDirective(NumClauses);
+}
+
+OMPTaskyieldDirective *OMPTaskyieldDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ void *Mem = C.Allocate(sizeof(OMPTaskyieldDirective));
+ OMPTaskyieldDirective *Dir =
+ new (Mem) OMPTaskyieldDirective(StartLoc, EndLoc);
+ return Dir;
+}
+
+OMPTaskyieldDirective *OMPTaskyieldDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ void *Mem = C.Allocate(sizeof(OMPTaskyieldDirective));
+ return new (Mem) OMPTaskyieldDirective();
+}
+
+OMPBarrierDirective *OMPBarrierDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ void *Mem = C.Allocate(sizeof(OMPBarrierDirective));
+ OMPBarrierDirective *Dir = new (Mem) OMPBarrierDirective(StartLoc, EndLoc);
+ return Dir;
+}
+
+OMPBarrierDirective *OMPBarrierDirective::CreateEmpty(const ASTContext &C,
+ EmptyShell) {
+ void *Mem = C.Allocate(sizeof(OMPBarrierDirective));
+ return new (Mem) OMPBarrierDirective();
+}
+
+OMPTaskwaitDirective *OMPTaskwaitDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ void *Mem = C.Allocate(sizeof(OMPTaskwaitDirective));
+ OMPTaskwaitDirective *Dir = new (Mem) OMPTaskwaitDirective(StartLoc, EndLoc);
+ return Dir;
+}
+
+OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C,
EmptyShell) {
- void *Mem = C.Allocate(sizeof(OMPParallelDirective) +
- sizeof(OMPClause *) * N + sizeof(Stmt *),
- llvm::alignOf<OMPParallelDirective>());
- return new (Mem) OMPParallelDirective(N);
+ void *Mem = C.Allocate(sizeof(OMPTaskwaitDirective));
+ return new (Mem) OMPTaskwaitDirective();
+}
+
+OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size());
+ OMPFlushDirective *Dir =
+ new (Mem) OMPFlushDirective(StartLoc, EndLoc, Clauses.size());
+ Dir->setClauses(Clauses);
+ return Dir;
+}
+
+OMPFlushDirective *OMPFlushDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ EmptyShell) {
+ unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
+ llvm::alignOf<OMPClause *>());
+ void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses);
+ return new (Mem) OMPFlushDirective(NumClauses);
}
+
diff --git a/contrib/llvm/tools/clang/lib/AST/StmtIterator.cpp b/contrib/llvm/tools/clang/lib/AST/StmtIterator.cpp
index 6e85375..1ccba04 100644
--- a/contrib/llvm/tools/clang/lib/AST/StmtIterator.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/StmtIterator.cpp
@@ -27,7 +27,7 @@ static inline const VariableArrayType *FindVA(const Type* t) {
t = vt->getElementType().getTypePtr();
}
- return NULL;
+ return nullptr;
}
void StmtIteratorBase::NextVA() {
@@ -54,7 +54,7 @@ void StmtIteratorBase::NextVA() {
}
void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
- assert (getVAPtr() == NULL);
+ assert(getVAPtr() == nullptr);
assert(inDeclGroup());
if (ImmediateAdvance)
@@ -93,12 +93,12 @@ bool StmtIteratorBase::HandleDecl(Decl* D) {
}
StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
- : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
+ : stmt(nullptr), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
NextDecl(false);
}
StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t)
- : stmt(0), DGI(0), RawVAPtr(SizeOfTypeVAMode) {
+ : stmt(nullptr), DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) {
RawVAPtr |= reinterpret_cast<uintptr_t>(t);
}
diff --git a/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp b/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp
index ae2cdf7..1fdad9f 100644
--- a/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/StmtPrinter.cpp
@@ -70,6 +70,7 @@ namespace {
void PrintCallArgs(CallExpr *E);
void PrintRawSEHExceptHandler(SEHExceptStmt *S);
void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
+ void PrintOMPExecutableDirective(OMPExecutableDirective *S);
void PrintExpr(Expr *E) {
if (E)
@@ -89,7 +90,7 @@ namespace {
return;
else StmtVisitor<StmtPrinter>::Visit(S);
}
-
+
void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
Indent() << "<<unknown stmt type>>\n";
}
@@ -113,9 +114,8 @@ namespace {
/// with no newline after the }.
void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
OS << "{\n";
- for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
- I != E; ++I)
- PrintStmt(*I);
+ for (auto *I : Node->body())
+ PrintStmt(I);
Indent() << "}";
}
@@ -125,11 +125,7 @@ void StmtPrinter::PrintRawDecl(Decl *D) {
}
void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {
- DeclStmt::const_decl_iterator Begin = S->decl_begin(), End = S->decl_end();
- SmallVector<Decl*, 2> Decls;
- for ( ; Begin != End; ++Begin)
- Decls.push_back(*Begin);
-
+ SmallVector<Decl*, 2> Decls(S->decls());
Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
}
@@ -172,19 +168,10 @@ void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
}
void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
- OS << "[[";
- bool first = true;
- for (ArrayRef<const Attr*>::iterator it = Node->getAttrs().begin(),
- end = Node->getAttrs().end();
- it != end; ++it) {
- if (!first) {
- OS << ", ";
- first = false;
- }
- // TODO: check this
- (*it)->printPretty(OS, Policy);
+ for (const auto *Attr : Node->getAttrs()) {
+ Attr->printPretty(OS, Policy);
}
- OS << "]] ";
+
PrintStmt(Node->getSubStmt(), 0);
}
@@ -330,7 +317,8 @@ void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
PrintExpr(Node->getRangeInit());
OS << ") {\n";
PrintStmt(Node->getBody());
- Indent() << "}\n";
+ Indent() << "}";
+ if (Policy.IncludeNewlines) OS << "\n";
}
void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
@@ -350,21 +338,25 @@ void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
}
void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
- Indent() << "goto " << Node->getLabel()->getName() << ";\n";
+ Indent() << "goto " << Node->getLabel()->getName() << ";";
+ if (Policy.IncludeNewlines) OS << "\n";
}
void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
Indent() << "goto *";
PrintExpr(Node->getTarget());
- OS << ";\n";
+ OS << ";";
+ if (Policy.IncludeNewlines) OS << "\n";
}
void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
- Indent() << "continue;\n";
+ Indent() << "continue;";
+ if (Policy.IncludeNewlines) OS << "\n";
}
void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
- Indent() << "break;\n";
+ Indent() << "break;";
+ if (Policy.IncludeNewlines) OS << "\n";
}
@@ -374,7 +366,8 @@ void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
OS << " ";
PrintExpr(Node->getRetValue());
}
- OS << ";\n";
+ OS << ";";
+ if (Policy.IncludeNewlines) OS << "\n";
}
@@ -437,7 +430,8 @@ void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
VisitStringLiteral(Node->getClobberStringLiteral(i));
}
- OS << ");\n";
+ OS << ");";
+ if (Policy.IncludeNewlines) OS << "\n";
}
void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
@@ -579,6 +573,11 @@ void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
OS << "\n";
}
+void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
+ Indent() << "__leave;";
+ if (Policy.IncludeNewlines) OS << "\n";
+}
+
//===----------------------------------------------------------------------===//
// OpenMP clauses printing methods
//===----------------------------------------------------------------------===//
@@ -586,29 +585,100 @@ void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
namespace {
class OMPClausePrinter : public OMPClauseVisitor<OMPClausePrinter> {
raw_ostream &OS;
+ const PrintingPolicy &Policy;
/// \brief Process clauses with list of variables.
template <typename T>
void VisitOMPClauseList(T *Node, char StartSym);
public:
- OMPClausePrinter(raw_ostream &OS) : OS(OS) { }
+ OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
+ : OS(OS), Policy(Policy) { }
#define OPENMP_CLAUSE(Name, Class) \
void Visit##Class(Class *S);
#include "clang/Basic/OpenMPKinds.def"
};
+void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
+ OS << "if(";
+ Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
+ OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
+ OS << "final(";
+ Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
+ OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
+ OS << "num_threads(";
+ Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
+ OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
+ OS << "safelen(";
+ Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
+ OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
+ OS << "collapse(";
+ Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
+ OS << ")";
+}
+
void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
OS << "default("
<< getOpenMPSimpleClauseTypeName(OMPC_default, Node->getDefaultKind())
<< ")";
}
+void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
+ OS << "proc_bind("
+ << getOpenMPSimpleClauseTypeName(OMPC_proc_bind, Node->getProcBindKind())
+ << ")";
+}
+
+void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
+ OS << "schedule("
+ << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
+ if (Node->getChunkSize()) {
+ OS << ", ";
+ Node->getChunkSize()->printPretty(OS, nullptr, Policy);
+ }
+ OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *) {
+ OS << "ordered";
+}
+
+void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
+ OS << "nowait";
+}
+
+void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
+ OS << "untied";
+}
+
+void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
+ OS << "mergeable";
+}
+
template<typename T>
void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
for (typename T::varlist_iterator I = Node->varlist_begin(),
E = Node->varlist_end();
- I != E; ++I)
- OS << (I == Node->varlist_begin() ? StartSym : ',')
- << *cast<NamedDecl>(cast<DeclRefExpr>(*I)->getDecl());
+ I != E; ++I) {
+ assert(*I && "Expected non-null Stmt");
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*I)) {
+ OS << (I == Node->varlist_begin() ? StartSym : ',');
+ cast<NamedDecl>(DRE->getDecl())->printQualifiedName(OS);
+ } else {
+ OS << (I == Node->varlist_begin() ? StartSym : ',');
+ (*I)->printPretty(OS, nullptr, Policy, 0);
+ }
+ }
}
void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
@@ -627,6 +697,14 @@ void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
}
}
+void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "lastprivate";
+ VisitOMPClauseList(Node, '(');
+ OS << ")";
+ }
+}
+
void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
if (!Node->varlist_empty()) {
OS << "shared";
@@ -635,17 +713,83 @@ void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
}
}
+void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "reduction(";
+ NestedNameSpecifier *QualifierLoc =
+ Node->getQualifierLoc().getNestedNameSpecifier();
+ OverloadedOperatorKind OOK =
+ Node->getNameInfo().getName().getCXXOverloadedOperator();
+ if (QualifierLoc == nullptr && OOK != OO_None) {
+ // Print reduction identifier in C format
+ OS << getOperatorSpelling(OOK);
+ } else {
+ // Use C++ format
+ if (QualifierLoc != nullptr)
+ QualifierLoc->print(OS, Policy);
+ OS << Node->getNameInfo();
+ }
+ OS << ":";
+ VisitOMPClauseList(Node, ' ');
+ OS << ")";
+ }
+}
+
+void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "linear";
+ VisitOMPClauseList(Node, '(');
+ if (Node->getStep() != nullptr) {
+ OS << ": ";
+ Node->getStep()->printPretty(OS, nullptr, Policy, 0);
+ }
+ OS << ")";
+ }
+}
+
+void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "aligned";
+ VisitOMPClauseList(Node, '(');
+ if (Node->getAlignment() != nullptr) {
+ OS << ": ";
+ Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
+ }
+ OS << ")";
+ }
+}
+
+void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "copyin";
+ VisitOMPClauseList(Node, '(');
+ OS << ")";
+ }
+}
+
+void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "copyprivate";
+ VisitOMPClauseList(Node, '(');
+ OS << ")";
+ }
+}
+
+void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
+ if (!Node->varlist_empty()) {
+ VisitOMPClauseList(Node, '(');
+ OS << ")";
+ }
+}
}
//===----------------------------------------------------------------------===//
// OpenMP directives printing methods
//===----------------------------------------------------------------------===//
-void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
- Indent() << "#pragma omp parallel ";
-
- OMPClausePrinter Printer(OS);
- ArrayRef<OMPClause *> Clauses = Node->clauses();
+void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S) {
+ OMPClausePrinter Printer(OS, Policy);
+ ArrayRef<OMPClause *> Clauses = S->clauses();
for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
I != E; ++I)
if (*I && !(*I)->isImplicit()) {
@@ -653,13 +797,95 @@ void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
OS << ' ';
}
OS << "\n";
- if (Node->getAssociatedStmt()) {
- assert(isa<CapturedStmt>(Node->getAssociatedStmt()) &&
+ if (S->hasAssociatedStmt() && S->getAssociatedStmt()) {
+ assert(isa<CapturedStmt>(S->getAssociatedStmt()) &&
"Expected captured statement!");
- Stmt *CS = cast<CapturedStmt>(Node->getAssociatedStmt())->getCapturedStmt();
+ Stmt *CS = cast<CapturedStmt>(S->getAssociatedStmt())->getCapturedStmt();
PrintStmt(CS);
}
}
+
+void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
+ Indent() << "#pragma omp parallel ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
+ Indent() << "#pragma omp simd ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
+ Indent() << "#pragma omp for ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
+ Indent() << "#pragma omp sections ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
+ Indent() << "#pragma omp section";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
+ Indent() << "#pragma omp single ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
+ Indent() << "#pragma omp master";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
+ Indent() << "#pragma omp critical";
+ if (Node->getDirectiveName().getName()) {
+ OS << " (";
+ Node->getDirectiveName().printName(OS);
+ OS << ")";
+ }
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
+ Indent() << "#pragma omp parallel for ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPParallelSectionsDirective(
+ OMPParallelSectionsDirective *Node) {
+ Indent() << "#pragma omp parallel sections ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
+ Indent() << "#pragma omp task ";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
+ Indent() << "#pragma omp taskyield";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
+ Indent() << "#pragma omp barrier";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
+ Indent() << "#pragma omp taskwait";
+ PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
+ Indent() << "#pragma omp flush ";
+ PrintOMPExecutableDirective(Node);
+}
+
//===----------------------------------------------------------------------===//
// Expr printing methods.
//===----------------------------------------------------------------------===//
@@ -717,7 +943,7 @@ void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
}
if (Node->isImplicitProperty())
- OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
+ Node->getImplicitPropertyGetter()->getSelector().print(OS);
else
OS << Node->getExplicitProperty()->getName();
}
@@ -743,6 +969,9 @@ void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
case PredefinedExpr::FuncDName:
OS << "__FUNCDNAME__";
break;
+ case PredefinedExpr::FuncSig:
+ OS << "__FUNCSIG__";
+ break;
case PredefinedExpr::LFunction:
OS << "L__FUNCTION__";
break;
@@ -814,11 +1043,10 @@ void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
// Emit suffixes. Integer literals are always a builtin integer type.
switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
default: llvm_unreachable("Unexpected type for integer literal!");
- // FIXME: The Short and UShort cases are to handle cases where a short
- // integeral literal is formed during template instantiation. They should
- // be removed when template instantiation no longer needs integer literals.
- case BuiltinType::Short:
- case BuiltinType::UShort:
+ case BuiltinType::SChar: OS << "i8"; break;
+ case BuiltinType::UChar: OS << "Ui8"; break;
+ case BuiltinType::Short: OS << "i16"; break;
+ case BuiltinType::UShort: OS << "Ui16"; break;
case BuiltinType::Int: break; // no suffix.
case BuiltinType::UInt: OS << 'U'; break;
case BuiltinType::Long: OS << 'L'; break;
@@ -1002,7 +1230,7 @@ void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
MemberExpr *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
FieldDecl *ParentDecl = ParentMember
- ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) : NULL;
+ ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) : nullptr;
if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
OS << (Node->isArrow() ? "->" : ".");
@@ -1043,7 +1271,7 @@ void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
PrintExpr(Node->getInitializer());
}
void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
- // No need to print anything, simply forward to the sub expression.
+ // No need to print anything, simply forward to the subexpression.
PrintExpr(Node->getSubExpr());
}
void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
@@ -1144,10 +1372,12 @@ void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
DEnd = Node->designators_end();
D != DEnd; ++D) {
if (D->isFieldDesignator()) {
- if (D->getDotLoc().isInvalid())
- OS << D->getFieldName()->getName() << ":";
- else
+ if (D->getDotLoc().isInvalid()) {
+ if (IdentifierInfo *II = D->getFieldName())
+ OS << II->getName() << ":";
+ } else {
OS << "." << D->getFieldName()->getName();
+ }
} else {
OS << "[";
if (D->isArrayDesignator()) {
@@ -1194,7 +1424,7 @@ void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
}
void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
- const char *Name = 0;
+ const char *Name = nullptr;
switch (Node->getOp()) {
#define BUILTIN(ID, TYPE, ATTRS)
#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
@@ -1281,6 +1511,12 @@ void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
}
void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
+ // If we have a conversion operator call only print the argument.
+ CXXMethodDecl *MD = Node->getMethodDecl();
+ if (MD && isa<CXXConversionDecl>(MD)) {
+ PrintExpr(Node->getImplicitObjectArgument());
+ return;
+ }
VisitCallExpr(cast<CallExpr>(Node));
}
@@ -1360,9 +1596,8 @@ void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
assert(Args);
const TemplateArgument &Pack = Args->get(0);
- for (TemplateArgument::pack_iterator I = Pack.pack_begin(),
- E = Pack.pack_end(); I != E; ++I) {
- char C = (char)I->getAsIntegral().getZExtValue();
+ for (const auto &P : Pack.pack_elements()) {
+ char C = (char)P.getAsIntegral().getZExtValue();
OS << C;
}
break;
@@ -1400,7 +1635,7 @@ void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
}
void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
- if (Node->getSubExpr() == 0)
+ if (!Node->getSubExpr())
OS << "throw";
else {
OS << "throw ";
@@ -1492,16 +1727,14 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
OS << " (";
CXXMethodDecl *Method = Node->getCallOperator();
NeedComma = false;
- for (CXXMethodDecl::param_iterator P = Method->param_begin(),
- PEnd = Method->param_end();
- P != PEnd; ++P) {
+ for (auto P : Method->params()) {
if (NeedComma) {
OS << ", ";
} else {
NeedComma = true;
}
- std::string ParamStr = (*P)->getNameAsString();
- (*P)->getOriginalType().print(OS, Policy, ParamStr);
+ std::string ParamStr = P->getNameAsString();
+ P->getOriginalType().print(OS, Policy, ParamStr);
}
if (Method->isVariadic()) {
if (NeedComma)
@@ -1522,7 +1755,7 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
// Print the trailing return type if it was specified in the source.
if (Node->hasExplicitResultType()) {
OS << " -> ";
- Proto->getResultType().print(OS, Policy);
+ Proto->getReturnType().print(OS, Policy);
}
}
@@ -1627,7 +1860,7 @@ void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
}
void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
- // Just forward to the sub expression.
+ // Just forward to the subexpression.
PrintExpr(E->getSubExpr());
}
@@ -1677,74 +1910,15 @@ void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
OS, Node->getTemplateArgs(), Node->getNumTemplateArgs(), Policy);
}
-static const char *getTypeTraitName(UnaryTypeTrait UTT) {
- switch (UTT) {
- case UTT_HasNothrowAssign: return "__has_nothrow_assign";
- case UTT_HasNothrowMoveAssign: return "__has_nothrow_move_assign";
- case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
- case UTT_HasNothrowCopy: return "__has_nothrow_copy";
- case UTT_HasTrivialAssign: return "__has_trivial_assign";
- case UTT_HasTrivialMoveAssign: return "__has_trivial_move_assign";
- case UTT_HasTrivialMoveConstructor: return "__has_trivial_move_constructor";
- case UTT_HasTrivialDefaultConstructor: return "__has_trivial_constructor";
- case UTT_HasTrivialCopy: return "__has_trivial_copy";
- case UTT_HasTrivialDestructor: return "__has_trivial_destructor";
- case UTT_HasVirtualDestructor: return "__has_virtual_destructor";
- case UTT_IsAbstract: return "__is_abstract";
- case UTT_IsArithmetic: return "__is_arithmetic";
- case UTT_IsArray: return "__is_array";
- case UTT_IsClass: return "__is_class";
- case UTT_IsCompleteType: return "__is_complete_type";
- case UTT_IsCompound: return "__is_compound";
- case UTT_IsConst: return "__is_const";
- case UTT_IsEmpty: return "__is_empty";
- case UTT_IsEnum: return "__is_enum";
- case UTT_IsFinal: return "__is_final";
- case UTT_IsFloatingPoint: return "__is_floating_point";
- case UTT_IsFunction: return "__is_function";
- case UTT_IsFundamental: return "__is_fundamental";
- case UTT_IsIntegral: return "__is_integral";
- case UTT_IsInterfaceClass: return "__is_interface_class";
- case UTT_IsLiteral: return "__is_literal";
- case UTT_IsLvalueReference: return "__is_lvalue_reference";
- case UTT_IsMemberFunctionPointer: return "__is_member_function_pointer";
- case UTT_IsMemberObjectPointer: return "__is_member_object_pointer";
- case UTT_IsMemberPointer: return "__is_member_pointer";
- case UTT_IsObject: return "__is_object";
- case UTT_IsPOD: return "__is_pod";
- case UTT_IsPointer: return "__is_pointer";
- case UTT_IsPolymorphic: return "__is_polymorphic";
- case UTT_IsReference: return "__is_reference";
- case UTT_IsRvalueReference: return "__is_rvalue_reference";
- case UTT_IsScalar: return "__is_scalar";
- case UTT_IsSealed: return "__is_sealed";
- case UTT_IsSigned: return "__is_signed";
- case UTT_IsStandardLayout: return "__is_standard_layout";
- case UTT_IsTrivial: return "__is_trivial";
- case UTT_IsTriviallyCopyable: return "__is_trivially_copyable";
- case UTT_IsUnion: return "__is_union";
- case UTT_IsUnsigned: return "__is_unsigned";
- case UTT_IsVoid: return "__is_void";
- case UTT_IsVolatile: return "__is_volatile";
- }
- llvm_unreachable("Type trait not covered by switch statement");
-}
-
-static const char *getTypeTraitName(BinaryTypeTrait BTT) {
- switch (BTT) {
- case BTT_IsBaseOf: return "__is_base_of";
- case BTT_IsConvertible: return "__is_convertible";
- case BTT_IsSame: return "__is_same";
- case BTT_TypeCompatible: return "__builtin_types_compatible_p";
- case BTT_IsConvertibleTo: return "__is_convertible_to";
- case BTT_IsTriviallyAssignable: return "__is_trivially_assignable";
- }
- llvm_unreachable("Binary type trait not covered by switch");
-}
-
static const char *getTypeTraitName(TypeTrait TT) {
switch (TT) {
- case clang::TT_IsTriviallyConstructible:return "__is_trivially_constructible";
+#define TYPE_TRAIT_1(Spelling, Name, Key) \
+case clang::UTT_##Name: return #Spelling;
+#define TYPE_TRAIT_2(Spelling, Name, Key) \
+case clang::BTT_##Name: return #Spelling;
+#define TYPE_TRAIT_N(Spelling, Name, Key) \
+ case clang::TT_##Name: return #Spelling;
+#include "clang/Basic/TokenKinds.def"
}
llvm_unreachable("Type trait not covered by switch");
}
@@ -1765,20 +1939,6 @@ static const char *getExpressionTraitName(ExpressionTrait ET) {
llvm_unreachable("Expression type trait not covered by switch");
}
-void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
- OS << getTypeTraitName(E->getTrait()) << '(';
- E->getQueriedType().print(OS, Policy);
- OS << ')';
-}
-
-void StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
- OS << getTypeTraitName(E->getTrait()) << '(';
- E->getLhsType().print(OS, Policy);
- OS << ',';
- E->getRhsType().print(OS, Policy);
- OS << ')';
-}
-
void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
OS << getTypeTraitName(E->getTrait()) << "(";
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
@@ -1883,7 +2043,9 @@ void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
}
void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
- OS << "@selector(" << Node->getSelector().getAsString() << ')';
+ OS << "@selector(";
+ Node->getSelector().print(OS);
+ OS << ')';
}
void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
@@ -1989,18 +2151,13 @@ void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
//===----------------------------------------------------------------------===//
void Stmt::dumpPretty(const ASTContext &Context) const {
- printPretty(llvm::errs(), 0, PrintingPolicy(Context.getLangOpts()));
+ printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
}
void Stmt::printPretty(raw_ostream &OS,
PrinterHelper *Helper,
const PrintingPolicy &Policy,
unsigned Indentation) const {
- if (this == 0) {
- OS << "<NULL>";
- return;
- }
-
StmtPrinter P(OS, Helper, Policy, Indentation);
P.Visit(const_cast<Stmt*>(this));
}
diff --git a/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp b/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp
index 6805e62..f44f25c 100644
--- a/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/StmtProfile.cpp
@@ -79,9 +79,8 @@ void StmtProfiler::VisitStmt(const Stmt *S) {
void StmtProfiler::VisitDeclStmt(const DeclStmt *S) {
VisitStmt(S);
- for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
- D != DEnd; ++D)
- VisitDecl(*D);
+ for (const auto *D : S->decls())
+ VisitDecl(D);
}
void StmtProfiler::VisitNullStmt(const NullStmt *S) {
@@ -215,6 +214,10 @@ void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
VisitStmt(S);
}
+void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
+ VisitStmt(S);
+}
+
void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
VisitStmt(S);
}
@@ -265,14 +268,52 @@ public:
#include "clang/Basic/OpenMPKinds.def"
};
+void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) {
+ if (C->getCondition())
+ Profiler->VisitStmt(C->getCondition());
+}
+
+void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause *C) {
+ if (C->getCondition())
+ Profiler->VisitStmt(C->getCondition());
+}
+
+void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
+ if (C->getNumThreads())
+ Profiler->VisitStmt(C->getNumThreads());
+}
+
+void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
+ if (C->getSafelen())
+ Profiler->VisitStmt(C->getSafelen());
+}
+
+void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
+ if (C->getNumForLoops())
+ Profiler->VisitStmt(C->getNumForLoops());
+}
+
void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
+void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
+
+void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
+ if (C->getChunkSize())
+ Profiler->VisitStmt(C->getChunkSize());
+}
+
+void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *) {}
+
+void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
+
+void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {}
+
+void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {}
+
template<typename T>
void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
- for (typename T::varlist_const_iterator I = Node->varlist_begin(),
- E = Node->varlist_end();
- I != E; ++I)
- Profiler->VisitStmt(*I);
+ for (auto *I : Node->varlists())
+ Profiler->VisitStmt(I);
}
void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
@@ -282,13 +323,42 @@ void OMPClauseProfiler::VisitOMPFirstprivateClause(
const OMPFirstprivateClause *C) {
VisitOMPClauseList(C);
}
+void
+OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
+ VisitOMPClauseList(C);
+}
void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseProfiler::VisitOMPReductionClause(
+ const OMPReductionClause *C) {
+ Profiler->VisitNestedNameSpecifier(
+ C->getQualifierLoc().getNestedNameSpecifier());
+ Profiler->VisitName(C->getNameInfo().getName());
+ VisitOMPClauseList(C);
+}
+void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
+ VisitOMPClauseList(C);
+ Profiler->VisitStmt(C->getStep());
+}
+void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
+ VisitOMPClauseList(C);
+ Profiler->VisitStmt(C->getAlignment());
+}
+void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
+ VisitOMPClauseList(C);
+}
+void
+OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
+ VisitOMPClauseList(C);
+}
+void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
+ VisitOMPClauseList(C);
+}
}
void
-StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
+StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
VisitStmt(S);
OMPClauseProfiler P(this);
ArrayRef<OMPClause *> Clauses = S->clauses();
@@ -298,6 +368,69 @@ StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
P.Visit(*I);
}
+void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
+ VisitOMPExecutableDirective(S);
+ VisitName(S->getDirectiveName().getName());
+}
+
+void
+StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPParallelSectionsDirective(
+ const OMPParallelSectionsDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
+ VisitOMPExecutableDirective(S);
+}
+
void StmtProfiler::VisitExpr(const Expr *S) {
VisitStmt(S);
}
@@ -529,7 +662,7 @@ void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
QualType T = S->getAssocType(i);
if (T.isNull())
- ID.AddPointer(0);
+ ID.AddPointer(nullptr);
else
VisitType(T);
VisitExpr(S->getAssocExpr(i));
@@ -585,11 +718,11 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
case OO_Star:
if (S->getNumArgs() == 1) {
- UnaryOp = UO_Minus;
+ UnaryOp = UO_Deref;
return Stmt::UnaryOperatorClass;
}
- BinaryOp = BO_Sub;
+ BinaryOp = BO_Mul;
return Stmt::BinaryOperatorClass;
case OO_Slash:
@@ -734,7 +867,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
llvm_unreachable("Invalid overloaded operator expression");
}
-
+
void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
if (S->isTypeDependent()) {
@@ -743,7 +876,7 @@ void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
UnaryOperatorKind UnaryOp = UO_Extension;
BinaryOperatorKind BinaryOp = BO_Comma;
Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
-
+
ID.AddInteger(SC);
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
Visit(S->getArg(I));
@@ -754,10 +887,10 @@ void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
ID.AddInteger(BinaryOp);
else
assert(SC == Stmt::ArraySubscriptExprClass);
-
+
return;
}
-
+
VisitCallExpr(S);
ID.AddInteger(S->getOperator());
}
@@ -923,10 +1056,10 @@ StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
VisitExpr(S);
ID.AddBoolean(S->isArrow());
VisitNestedNameSpecifier(S->getQualifier());
- ID.AddBoolean(S->getScopeTypeInfo() != 0);
+ ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
if (S->getScopeTypeInfo())
VisitType(S->getScopeTypeInfo()->getType());
- ID.AddBoolean(S->getDestroyedTypeInfo() != 0);
+ ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
if (S->getDestroyedTypeInfo())
VisitType(S->getDestroyedType());
else
@@ -948,19 +1081,6 @@ StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
VisitOverloadExpr(S);
}
-void StmtProfiler::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *S) {
- VisitExpr(S);
- ID.AddInteger(S->getTrait());
- VisitType(S->getQueriedType());
-}
-
-void StmtProfiler::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *S) {
- VisitExpr(S);
- ID.AddInteger(S->getTrait());
- VisitType(S->getLhsType());
- VisitType(S->getRhsType());
-}
-
void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
VisitExpr(S);
ID.AddInteger(S->getTrait());
@@ -1200,7 +1320,7 @@ void StmtProfiler::VisitDecl(const Decl *D) {
}
}
- ID.AddPointer(D? D->getCanonicalDecl() : 0);
+ ID.AddPointer(D? D->getCanonicalDecl() : nullptr);
}
void StmtProfiler::VisitType(QualType T) {
@@ -1268,9 +1388,8 @@ void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
break;
case TemplateArgument::Pack:
- const TemplateArgument *Pack = Arg.pack_begin();
- for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
- VisitTemplateArgument(Pack[i]);
+ for (const auto &P : Arg.pack_elements())
+ VisitTemplateArgument(P);
break;
}
}
diff --git a/contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp b/contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp
index 16efb79..ac6a754 100644
--- a/contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/TemplateBase.cpp
@@ -114,11 +114,9 @@ bool TemplateArgument::isDependent() const {
return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
case Pack:
- for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
- if (P->isDependent())
+ for (const auto &P : pack_elements())
+ if (P.isDependent())
return true;
- }
-
return false;
}
@@ -155,11 +153,9 @@ bool TemplateArgument::isInstantiationDependent() const {
return getAsExpr()->isInstantiationDependent();
case Pack:
- for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
- if (P->isInstantiationDependent())
+ for (const auto &P : pack_elements())
+ if (P.isInstantiationDependent())
return true;
- }
-
return false;
}
@@ -214,8 +210,8 @@ bool TemplateArgument::containsUnexpandedParameterPack() const {
break;
case Pack:
- for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
- if (P->containsUnexpandedParameterPack())
+ for (const auto &P : pack_elements())
+ if (P.containsUnexpandedParameterPack())
return true;
break;
@@ -248,7 +244,7 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
break;
case Declaration:
- ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
+ ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
break;
case Template:
@@ -345,7 +341,7 @@ void TemplateArgument::print(const PrintingPolicy &Policy,
raw_ostream &Out) const {
switch (getKind()) {
case Null:
- Out << "<no value>";
+ Out << "(no value)";
break;
case Type: {
@@ -362,7 +358,7 @@ void TemplateArgument::print(const PrintingPolicy &Policy,
// FIXME: distinguish between pointer and reference args?
ND->printQualifiedName(Out);
} else {
- Out << "<anonymous>";
+ Out << "(anonymous)";
}
break;
}
@@ -386,20 +382,19 @@ void TemplateArgument::print(const PrintingPolicy &Policy,
}
case Expression:
- getAsExpr()->printPretty(Out, 0, Policy);
+ getAsExpr()->printPretty(Out, nullptr, Policy);
break;
case Pack:
Out << "<";
bool First = true;
- for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
- P != PEnd; ++P) {
+ for (const auto &P : pack_elements()) {
if (First)
First = false;
else
Out << ", ";
- P->print(Policy, Out);
+ P.print(Policy, Out);
}
Out << ">";
break;
@@ -489,7 +484,7 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
LangOptions LangOpts;
LangOpts.CPlusPlus = true;
PrintingPolicy Policy(LangOpts);
- Arg.getAsExpr()->printPretty(OS, 0, Policy);
+ Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
return DB << OS.str();
}
@@ -511,6 +506,8 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
const ASTTemplateArgumentListInfo *
ASTTemplateArgumentListInfo::Create(ASTContext &C,
const TemplateArgumentListInfo &List) {
+ assert(llvm::alignOf<ASTTemplateArgumentListInfo>() >=
+ llvm::alignOf<TemplateArgumentLoc>());
std::size_t size = ASTTemplateArgumentListInfo::sizeFor(List.size());
void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
diff --git a/contrib/llvm/tools/clang/lib/AST/TemplateName.cpp b/contrib/llvm/tools/clang/lib/AST/TemplateName.cpp
index 8767c63..77c8fd5 100644
--- a/contrib/llvm/tools/clang/lib/AST/TemplateName.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/TemplateName.cpp
@@ -78,7 +78,7 @@ TemplateDecl *TemplateName::getAsTemplateDecl() const {
if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
return sub->getReplacement().getAsTemplateDecl();
- return 0;
+ return nullptr;
}
bool TemplateName::isDependent() const {
@@ -121,7 +121,7 @@ bool TemplateName::containsUnexpandedParameterPack() const {
return DTN->getQualifier() &&
DTN->getQualifier()->containsUnexpandedParameterPack();
- return getAsSubstTemplateTemplateParmPack() != 0;
+ return getAsSubstTemplateTemplateParmPack() != nullptr;
}
void
diff --git a/contrib/llvm/tools/clang/lib/AST/Type.cpp b/contrib/llvm/tools/clang/lib/AST/Type.cpp
index 7421bae..1677874 100644
--- a/contrib/llvm/tools/clang/lib/AST/Type.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/Type.cpp
@@ -45,7 +45,7 @@ bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {
const IdentifierInfo* QualType::getBaseTypeIdentifier() const {
const Type* ty = getTypePtr();
- NamedDecl *ND = NULL;
+ NamedDecl *ND = nullptr;
if (ty->isPointerType() || ty->isReferenceType())
return ty->getPointeeType().getBaseTypeIdentifier();
else if (ty->isRecordType())
@@ -60,7 +60,7 @@ const IdentifierInfo* QualType::getBaseTypeIdentifier() const {
if (ND)
return ND->getIdentifier();
- return NULL;
+ return nullptr;
}
bool QualType::isConstant(QualType T, ASTContext &Ctx) {
@@ -202,7 +202,7 @@ const Type *Type::getArrayElementTypeNoTypeQual() const {
// If the canonical form of this type isn't the right kind, reject it.
if (!isa<ArrayType>(CanonicalType))
- return 0;
+ return nullptr;
// If this is a typedef for an array type, strip the typedef off without
// losing all typedef information.
@@ -410,7 +410,7 @@ const ComplexType *Type::getAsComplexIntegerType() const {
if (const ComplexType *Complex = getAs<ComplexType>())
if (Complex->getElementType()->isIntegerType())
return Complex;
- return 0;
+ return nullptr;
}
QualType Type::getPointeeType() const {
@@ -422,6 +422,10 @@ QualType Type::getPointeeType() const {
return BPT->getPointeeType();
if (const ReferenceType *RT = getAs<ReferenceType>())
return RT->getPointeeType();
+ if (const MemberPointerType *MPT = getAs<MemberPointerType>())
+ return MPT->getPointeeType();
+ if (const DecayedType *DT = getAs<DecayedType>())
+ return DT->getPointeeType();
return QualType();
}
@@ -435,13 +439,13 @@ const RecordType *Type::getAsStructureType() const {
// If the canonical form of this type isn't the right kind, reject it.
if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
if (!RT->getDecl()->isStruct())
- return 0;
+ return nullptr;
// If this is a typedef for a structure type, strip the typedef off without
// losing all typedef information.
return cast<RecordType>(getUnqualifiedDesugaredType());
}
- return 0;
+ return nullptr;
}
const RecordType *Type::getAsUnionType() const {
@@ -454,14 +458,14 @@ const RecordType *Type::getAsUnionType() const {
// If the canonical form of this type isn't the right kind, reject it.
if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
if (!RT->getDecl()->isUnion())
- return 0;
+ return nullptr;
// If this is a typedef for a union type, strip the typedef off without
// losing all typedef information.
return cast<RecordType>(getUnqualifiedDesugaredType());
}
- return 0;
+ return nullptr;
}
ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
@@ -485,11 +489,11 @@ const ObjCObjectType *Type::getAsObjCQualifiedInterfaceType() const {
if (const ObjCObjectType *T = getAs<ObjCObjectType>())
if (T->getNumProtocols() && T->getInterface())
return T;
- return 0;
+ return nullptr;
}
bool Type::isObjCQualifiedInterfaceType() const {
- return getAsObjCQualifiedInterfaceType() != 0;
+ return getAsObjCQualifiedInterfaceType() != nullptr;
}
const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
@@ -499,7 +503,7 @@ const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
if (OPT->isObjCQualifiedIdType())
return OPT;
}
- return 0;
+ return nullptr;
}
const ObjCObjectPointerType *Type::getAsObjCQualifiedClassType() const {
@@ -509,7 +513,7 @@ const ObjCObjectPointerType *Type::getAsObjCQualifiedClassType() const {
if (OPT->isObjCQualifiedClassType())
return OPT;
}
- return 0;
+ return nullptr;
}
const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const {
@@ -517,7 +521,7 @@ const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const {
if (OPT->getInterfaceType())
return OPT;
}
- return 0;
+ return nullptr;
}
const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const {
@@ -527,12 +531,12 @@ const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const {
else if (const ReferenceType *RT = getAs<ReferenceType>())
PointeeType = RT->getPointeeType();
else
- return 0;
+ return nullptr;
if (const RecordType *RT = PointeeType->getAs<RecordType>())
return dyn_cast<CXXRecordDecl>(RT->getDecl());
- return 0;
+ return nullptr;
}
CXXRecordDecl *Type::getAsCXXRecordDecl() const {
@@ -541,8 +545,8 @@ CXXRecordDecl *Type::getAsCXXRecordDecl() const {
else if (const InjectedClassNameType *Injected
= getAs<InjectedClassNameType>())
return Injected->getDecl();
-
- return 0;
+
+ return nullptr;
}
namespace {
@@ -552,7 +556,7 @@ namespace {
using TypeVisitor<GetContainedAutoVisitor, AutoType*>::Visit;
AutoType *Visit(QualType T) {
if (T.isNull())
- return 0;
+ return nullptr;
return Visit(T.getTypePtr());
}
@@ -585,7 +589,7 @@ namespace {
return Visit(T->getElementType());
}
AutoType *VisitFunctionType(const FunctionType *T) {
- return Visit(T->getResultType());
+ return Visit(T->getReturnType());
}
AutoType *VisitParenType(const ParenType *T) {
return Visit(T->getInnerType());
@@ -593,6 +597,9 @@ namespace {
AutoType *VisitAttributedType(const AttributedType *T) {
return Visit(T->getModifiedType());
}
+ AutoType *VisitAdjustedType(const AdjustedType *T) {
+ return Visit(T->getOriginalType());
+ }
};
}
@@ -688,7 +695,7 @@ bool Type::isChar32Type() const {
/// types.
bool Type::isAnyCharacterType() const {
const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType);
- if (BT == 0) return false;
+ if (!BT) return false;
switch (BT->getKind()) {
default: return false;
case BuiltinType::Char_U:
@@ -894,8 +901,8 @@ bool Type::isConstantSizeType() const {
/// determine its size.
bool Type::isIncompleteType(NamedDecl **Def) const {
if (Def)
- *Def = 0;
-
+ *Def = nullptr;
+
switch (CanonicalType->getTypeClass()) {
default: return false;
case Builtin:
@@ -1424,8 +1431,7 @@ TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
llvm_unreachable("Unknown elaborated type keyword.");
}
-const char*
-TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
+StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
switch (Keyword) {
case ETK_None: return "";
case ETK_Typename: return "typename";
@@ -1516,7 +1522,7 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
case ULong: return "unsigned long";
case ULongLong: return "unsigned long long";
case UInt128: return "unsigned __int128";
- case Half: return "half";
+ case Half: return Policy.Half ? "half" : "__fp16";
case Float: return "float";
case Double: return "double";
case LongDouble: return "long double";
@@ -1582,41 +1588,38 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
llvm_unreachable("Invalid calling convention.");
}
-FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> args,
+FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
QualType canonical,
const ExtProtoInfo &epi)
- : FunctionType(FunctionProto, result, epi.TypeQuals,
- canonical,
- result->isDependentType(),
- result->isInstantiationDependentType(),
- result->isVariablyModifiedType(),
- result->containsUnexpandedParameterPack(),
- epi.ExtInfo),
- NumArgs(args.size()), NumExceptions(epi.NumExceptions),
- ExceptionSpecType(epi.ExceptionSpecType),
- HasAnyConsumedArgs(epi.ConsumedArguments != 0),
- Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn),
- RefQualifier(epi.RefQualifier)
-{
- assert(NumArgs == args.size() && "function has too many parameters");
+ : FunctionType(FunctionProto, result, epi.TypeQuals, canonical,
+ result->isDependentType(),
+ result->isInstantiationDependentType(),
+ result->isVariablyModifiedType(),
+ result->containsUnexpandedParameterPack(), epi.ExtInfo),
+ NumParams(params.size()), NumExceptions(epi.NumExceptions),
+ ExceptionSpecType(epi.ExceptionSpecType),
+ HasAnyConsumedParams(epi.ConsumedParameters != nullptr),
+ Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn),
+ RefQualifier(epi.RefQualifier) {
+ assert(NumParams == params.size() && "function has too many parameters");
// Fill in the trailing argument array.
QualType *argSlot = reinterpret_cast<QualType*>(this+1);
- for (unsigned i = 0; i != NumArgs; ++i) {
- if (args[i]->isDependentType())
+ for (unsigned i = 0; i != NumParams; ++i) {
+ if (params[i]->isDependentType())
setDependent();
- else if (args[i]->isInstantiationDependentType())
+ else if (params[i]->isInstantiationDependentType())
setInstantiationDependent();
-
- if (args[i]->containsUnexpandedParameterPack())
+
+ if (params[i]->containsUnexpandedParameterPack())
setContainsUnexpandedParameterPack();
- argSlot[i] = args[i];
+ argSlot[i] = params[i];
}
if (getExceptionSpecType() == EST_Dynamic) {
// Fill in the exception array.
- QualType *exnSlot = argSlot + NumArgs;
+ QualType *exnSlot = argSlot + NumParams;
for (unsigned i = 0, e = epi.NumExceptions; i != e; ++i) {
if (epi.Exceptions[i]->isDependentType())
setDependent();
@@ -1630,7 +1633,7 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> args,
}
} else if (getExceptionSpecType() == EST_ComputedNoexcept) {
// Store the noexcept expression and context.
- Expr **noexSlot = reinterpret_cast<Expr**>(argSlot + NumArgs);
+ Expr **noexSlot = reinterpret_cast<Expr **>(argSlot + NumParams);
*noexSlot = epi.NoexceptExpr;
if (epi.NoexceptExpr) {
@@ -1643,7 +1646,8 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> args,
} else if (getExceptionSpecType() == EST_Uninstantiated) {
// Store the function decl from which we will resolve our
// exception specification.
- FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + NumArgs);
+ FunctionDecl **slot =
+ reinterpret_cast<FunctionDecl **>(argSlot + NumParams);
slot[0] = epi.ExceptionSpecDecl;
slot[1] = epi.ExceptionSpecTemplate;
// This exception specification doesn't make the type dependent, because
@@ -1651,14 +1655,15 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> args,
} else if (getExceptionSpecType() == EST_Unevaluated) {
// Store the function decl from which we will resolve our
// exception specification.
- FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + NumArgs);
+ FunctionDecl **slot =
+ reinterpret_cast<FunctionDecl **>(argSlot + NumParams);
slot[0] = epi.ExceptionSpecDecl;
}
- if (epi.ConsumedArguments) {
- bool *consumedArgs = const_cast<bool*>(getConsumedArgsBuffer());
- for (unsigned i = 0; i != NumArgs; ++i)
- consumedArgs[i] = epi.ConsumedArguments[i];
+ if (epi.ConsumedParameters) {
+ bool *consumedParams = const_cast<bool *>(getConsumedParamsBuffer());
+ for (unsigned i = 0; i != NumParams; ++i)
+ consumedParams[i] = epi.ConsumedParameters[i];
}
}
@@ -1678,7 +1683,7 @@ FunctionProtoType::getNoexceptSpec(const ASTContext &ctx) const {
return NR_Dependent;
llvm::APSInt value;
- bool isICE = noexceptExpr->isIntegerConstantExpr(value, ctx, 0,
+ bool isICE = noexceptExpr->isIntegerConstantExpr(value, ctx, nullptr,
/*evaluated*/false);
(void)isICE;
assert(isICE && "AST should not contain bad noexcept expressions.");
@@ -1686,16 +1691,41 @@ FunctionProtoType::getNoexceptSpec(const ASTContext &ctx) const {
return value.getBoolValue() ? NR_Nothrow : NR_Throw;
}
+bool FunctionProtoType::isNothrow(const ASTContext &Ctx,
+ bool ResultIfDependent) const {
+ ExceptionSpecificationType EST = getExceptionSpecType();
+ assert(EST != EST_Unevaluated && EST != EST_Uninstantiated);
+ if (EST == EST_DynamicNone || EST == EST_BasicNoexcept)
+ return true;
+
+ if (EST == EST_Dynamic && ResultIfDependent == true) {
+ // A dynamic exception specification is throwing unless every exception
+ // type is an (unexpanded) pack expansion type.
+ for (unsigned I = 0, N = NumExceptions; I != N; ++I)
+ if (!getExceptionType(I)->getAs<PackExpansionType>())
+ return false;
+ return ResultIfDependent;
+ }
+
+ if (EST != EST_ComputedNoexcept)
+ return false;
+
+ NoexceptResult NR = getNoexceptSpec(Ctx);
+ if (NR == NR_Dependent)
+ return ResultIfDependent;
+ return NR == NR_Nothrow;
+}
+
bool FunctionProtoType::isTemplateVariadic() const {
- for (unsigned ArgIdx = getNumArgs(); ArgIdx; --ArgIdx)
- if (isa<PackExpansionType>(getArgType(ArgIdx - 1)))
+ for (unsigned ArgIdx = getNumParams(); ArgIdx; --ArgIdx)
+ if (isa<PackExpansionType>(getParamType(ArgIdx - 1)))
return true;
return false;
}
void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
- const QualType *ArgTys, unsigned NumArgs,
+ const QualType *ArgTys, unsigned NumParams,
const ExtProtoInfo &epi,
const ASTContext &Context) {
@@ -1717,7 +1747,7 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
// whether the following bool is the EH spec or part of the arguments.
ID.AddPointer(Result.getAsOpaquePtr());
- for (unsigned i = 0; i != NumArgs; ++i)
+ for (unsigned i = 0; i != NumParams; ++i)
ID.AddPointer(ArgTys[i].getAsOpaquePtr());
// This method is relatively performance sensitive, so as a performance
// shortcut, use one AddInteger call instead of four for the next four
@@ -1740,9 +1770,9 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
epi.ExceptionSpecType == EST_Unevaluated) {
ID.AddPointer(epi.ExceptionSpecDecl->getCanonicalDecl());
}
- if (epi.ConsumedArguments) {
- for (unsigned i = 0; i != NumArgs; ++i)
- ID.AddBoolean(epi.ConsumedArguments[i]);
+ if (epi.ConsumedParameters) {
+ for (unsigned i = 0; i != NumParams; ++i)
+ ID.AddBoolean(epi.ConsumedParameters[i]);
}
epi.ExtInfo.Profile(ID);
ID.AddBoolean(epi.HasTrailingReturn);
@@ -1750,7 +1780,7 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Ctx) {
- Profile(ID, getResultType(), arg_type_begin(), NumArgs, getExtProtoInfo(),
+ Profile(ID, getReturnType(), param_type_begin(), NumParams, getExtProtoInfo(),
Ctx);
}
@@ -1819,11 +1849,9 @@ TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
decl(const_cast<TagDecl*>(D)) {}
static TagDecl *getInterestingTagDecl(TagDecl *decl) {
- for (TagDecl::redecl_iterator I = decl->redecls_begin(),
- E = decl->redecls_end();
- I != E; ++I) {
+ for (auto I : decl->redecls()) {
if (I->isCompleteDefinition() || I->isBeingDefined())
- return *I;
+ return I;
}
// If there's no definition (not even in progress), return what we have.
return decl;
@@ -1896,7 +1924,7 @@ CXXRecordDecl *InjectedClassNameType::getDecl() const {
}
IdentifierInfo *TemplateTypeParmType::getIdentifier() const {
- return isCanonicalUnqualified() ? 0 : getDecl()->getIdentifier();
+ return isCanonicalUnqualified() ? nullptr : getDecl()->getIdentifier();
}
SubstTemplateTypeParmPackType::
@@ -1922,10 +1950,8 @@ void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID,
const TemplateArgument &ArgPack) {
ID.AddPointer(Replaced);
ID.AddInteger(ArgPack.pack_size());
- for (TemplateArgument::pack_iterator P = ArgPack.pack_begin(),
- PEnd = ArgPack.pack_end();
- P != PEnd; ++P)
- ID.AddPointer(P->getAsType().getAsOpaquePtr());
+ for (const auto &P : ArgPack.pack_elements())
+ ID.AddPointer(P.getAsType().getAsOpaquePtr());
}
bool TemplateSpecializationType::
@@ -2200,13 +2226,12 @@ static CachedProperties computeCachedProperties(const Type *T) {
case Type::ExtVector:
return Cache::get(cast<VectorType>(T)->getElementType());
case Type::FunctionNoProto:
- return Cache::get(cast<FunctionType>(T)->getResultType());
+ return Cache::get(cast<FunctionType>(T)->getReturnType());
case Type::FunctionProto: {
const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
- CachedProperties result = Cache::get(FPT->getResultType());
- for (FunctionProtoType::arg_type_iterator ai = FPT->arg_type_begin(),
- ae = FPT->arg_type_end(); ai != ae; ++ai)
- result = merge(result, Cache::get(*ai));
+ CachedProperties result = Cache::get(FPT->getReturnType());
+ for (const auto &ai : FPT->param_types())
+ result = merge(result, Cache::get(ai));
return result;
}
case Type::ObjCInterface: {
@@ -2285,13 +2310,12 @@ static LinkageInfo computeLinkageInfo(const Type *T) {
case Type::ExtVector:
return computeLinkageInfo(cast<VectorType>(T)->getElementType());
case Type::FunctionNoProto:
- return computeLinkageInfo(cast<FunctionType>(T)->getResultType());
+ return computeLinkageInfo(cast<FunctionType>(T)->getReturnType());
case Type::FunctionProto: {
const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
- LinkageInfo LV = computeLinkageInfo(FPT->getResultType());
- for (FunctionProtoType::arg_type_iterator ai = FPT->arg_type_begin(),
- ae = FPT->arg_type_end(); ai != ae; ++ai)
- LV.merge(computeLinkageInfo(*ai));
+ LinkageInfo LV = computeLinkageInfo(FPT->getReturnType());
+ for (const auto &ai : FPT->param_types())
+ LV.merge(computeLinkageInfo(ai));
return LV;
}
case Type::ObjCInterface:
@@ -2441,3 +2465,7 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
return DK_none;
}
+
+CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
+ return getClass()->getAsCXXRecordDecl()->getMostRecentDecl();
+}
diff --git a/contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp b/contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp
index 22a51bc..208d695 100644
--- a/contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/TypeLoc.cpp
@@ -55,7 +55,7 @@ namespace {
/// \brief Returns the alignment of the type source info data block.
unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
if (Ty.isNull()) return 1;
- return TypeAligner().Visit(TypeLoc(Ty, 0));
+ return TypeAligner().Visit(TypeLoc(Ty, nullptr));
}
namespace {
@@ -73,7 +73,7 @@ namespace {
/// \brief Returns the size of the type source info data block.
unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
unsigned Total = 0;
- TypeLoc TyLoc(Ty, 0);
+ TypeLoc TyLoc(Ty, nullptr);
unsigned MaxAlign = 1;
while (!TyLoc.isNull()) {
unsigned Align = getLocalAlignmentForType(TyLoc.getType());
diff --git a/contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp b/contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp
index 571e3db..061473e 100644
--- a/contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/TypePrinter.cpp
@@ -204,6 +204,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
NeedARCStrongQualifier = true;
// Fall through
+ case Type::Adjusted:
case Type::Decayed:
case Type::Pointer:
case Type::BlockPointer:
@@ -429,7 +430,16 @@ void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
}
void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
raw_ostream &OS) {
- OS << '[' << T->getSize().getZExtValue() << ']';
+ OS << '[';
+ if (T->getIndexTypeQualifiers().hasQualifiers()) {
+ AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers());
+ OS << ' ';
+ }
+
+ if (T->getSizeModifier() == ArrayType::Static)
+ OS << "static ";
+
+ OS << T->getSize().getZExtValue() << ']';
printAfter(T->getElementType(), OS);
}
@@ -460,23 +470,32 @@ void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
}
if (T->getSizeModifier() == VariableArrayType::Static)
- OS << "static";
+ OS << "static ";
else if (T->getSizeModifier() == VariableArrayType::Star)
OS << '*';
if (T->getSizeExpr())
- T->getSizeExpr()->printPretty(OS, 0, Policy);
+ T->getSizeExpr()->printPretty(OS, nullptr, Policy);
OS << ']';
printAfter(T->getElementType(), OS);
}
+void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
+ // Print the adjusted representation, otherwise the adjustment will be
+ // invisible.
+ printBefore(T->getAdjustedType(), OS);
+}
+void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
+ printAfter(T->getAdjustedType(), OS);
+}
+
void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
// Print as though it's a pointer.
- printBefore(T->getDecayedType(), OS);
+ printAdjustedBefore(T, OS);
}
void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
- printAfter(T->getDecayedType(), OS);
+ printAdjustedAfter(T, OS);
}
void TypePrinter::printDependentSizedArrayBefore(
@@ -491,7 +510,7 @@ void TypePrinter::printDependentSizedArrayAfter(
raw_ostream &OS) {
OS << '[';
if (T->getSizeExpr())
- T->getSizeExpr()->printPretty(OS, 0, Policy);
+ T->getSizeExpr()->printPretty(OS, nullptr, Policy);
OS << ']';
printAfter(T->getElementType(), OS);
}
@@ -506,7 +525,7 @@ void TypePrinter::printDependentSizedExtVectorAfter(
raw_ostream &OS) {
OS << " __attribute__((ext_vector_type(";
if (T->getSizeExpr())
- T->getSizeExpr()->printPretty(OS, 0, Policy);
+ T->getSizeExpr()->printPretty(OS, nullptr, Policy);
OS << ")))";
printAfter(T->getElementType(), OS);
}
@@ -583,7 +602,8 @@ FunctionProtoType::printExceptionSpecification(raw_ostream &OS,
OS << " noexcept";
if (getExceptionSpecType() == EST_ComputedNoexcept) {
OS << '(';
- getNoexceptExpr()->printPretty(OS, 0, Policy);
+ if (getNoexceptExpr())
+ getNoexceptExpr()->printPretty(OS, nullptr, Policy);
OS << ')';
}
}
@@ -598,7 +618,7 @@ void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
} else {
// If needed for precedence reasons, wrap the inner part in grouping parens.
SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
- printBefore(T->getResultType(), OS);
+ printBefore(T->getReturnType(), OS);
if (!PrevPHIsEmpty.get())
OS << '(';
}
@@ -614,17 +634,17 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
OS << '(';
{
ParamPolicyRAII ParamPolicy(Policy);
- for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
+ for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
if (i) OS << ", ";
- print(T->getArgType(i), OS, StringRef());
+ print(T->getParamType(i), OS, StringRef());
}
}
if (T->isVariadic()) {
- if (T->getNumArgs())
+ if (T->getNumParams())
OS << ", ";
OS << "...";
- } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
+ } else if (T->getNumParams() == 0 && !Policy.LangOpts.CPlusPlus) {
// Do not emit int() if we have a proto, emit 'int(void)'.
OS << "void";
}
@@ -703,17 +723,17 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
T->printExceptionSpecification(OS, Policy);
if (T->hasTrailingReturn()) {
- OS << " -> ";
- print(T->getResultType(), OS, StringRef());
+ OS << " -> ";
+ print(T->getReturnType(), OS, StringRef());
} else
- printAfter(T->getResultType(), OS);
+ printAfter(T->getReturnType(), OS);
}
void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
raw_ostream &OS) {
// If needed for precedence reasons, wrap the inner part in grouping parens.
SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
- printBefore(T->getResultType(), OS);
+ printBefore(T->getReturnType(), OS);
if (!PrevPHIsEmpty.get())
OS << '(';
}
@@ -727,7 +747,7 @@ void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
OS << "()";
if (T->getNoReturnAttr())
OS << " __attribute__((noreturn))";
- printAfter(T->getResultType(), OS);
+ printAfter(T->getReturnType(), OS);
}
void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) {
@@ -751,7 +771,8 @@ void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { }
void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
raw_ostream &OS) {
OS << "typeof ";
- T->getUnderlyingExpr()->printPretty(OS, 0, Policy);
+ if (T->getUnderlyingExpr())
+ T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
spaceBeforePlaceHolder(OS);
}
void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
@@ -767,7 +788,8 @@ void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { }
void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
OS << "decltype(";
- T->getUnderlyingExpr()->printPretty(OS, 0, Policy);
+ if (T->getUnderlyingExpr())
+ T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
OS << ')';
spaceBeforePlaceHolder(OS);
}
@@ -838,7 +860,7 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
if (NS->getIdentifier())
OS << NS->getName() << "::";
else
- OS << "<anonymous>::";
+ OS << "(anonymous namespace)::";
} else if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
IncludeStrongLifetimeRAII Strong(Policy);
@@ -890,13 +912,13 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
OS << Typedef->getIdentifier()->getName();
} else {
// Make an unambiguous representation for anonymous types, e.g.
- // <anonymous enum at /usr/include/string.h:120:9>
+ // (anonymous enum at /usr/include/string.h:120:9)
if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
- OS << "<lambda";
+ OS << "(lambda";
HasKindDecoration = true;
} else {
- OS << "<anonymous";
+ OS << "(anonymous";
}
if (Policy.AnonymousTagLocations) {
@@ -915,7 +937,7 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
}
}
- OS << '>';
+ OS << ')';
}
// If this is a class template specialization, print the template
@@ -1249,13 +1271,12 @@ void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
print(T->getBaseType(), OS, StringRef());
OS << '<';
bool isFirst = true;
- for (ObjCObjectType::qual_iterator
- I = T->qual_begin(), E = T->qual_end(); I != E; ++I) {
+ for (const auto *I : T->quals()) {
if (isFirst)
isFirst = false;
else
OS << ',';
- OS << (*I)->getName();
+ OS << I->getName();
}
OS << '>';
spaceBeforePlaceHolder(OS);
@@ -1271,12 +1292,12 @@ void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
T->getPointeeType().getLocalQualifiers().print(OS, Policy,
/*appendSpaceIfNonEmpty=*/true);
+ assert(!T->isObjCSelType());
+
if (T->isObjCIdType() || T->isObjCQualifiedIdType())
OS << "id";
else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
OS << "Class";
- else if (T->isObjCSelType())
- OS << "SEL";
else
OS << T->getInterfaceDecl()->getName();
@@ -1292,7 +1313,8 @@ void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
OS << '>';
}
- if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) {
+ if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
+ !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {
OS << " *"; // Don't forget the implicit pointer.
} else {
spaceBeforePlaceHolder(OS);
@@ -1413,13 +1435,10 @@ void QualType::dump(const char *msg) const {
print(llvm::errs(), PrintingPolicy(LO), "identifier");
llvm::errs() << '\n';
}
-void QualType::dump() const {
- dump(0);
-}
-void Type::dump() const {
- QualType(this, 0).dump();
-}
+LLVM_DUMP_METHOD void QualType::dump() const { dump(nullptr); }
+
+LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
std::string Qualifiers::getAsString() const {
LangOptions LO;
diff --git a/contrib/llvm/tools/clang/lib/AST/VTTBuilder.cpp b/contrib/llvm/tools/clang/lib/AST/VTTBuilder.cpp
index 5ca4e86..c213d1c 100644
--- a/contrib/llvm/tools/clang/lib/AST/VTTBuilder.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/VTTBuilder.cpp
@@ -56,15 +56,13 @@ void VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
const CXXRecordDecl *RD = Base.getBase();
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
-
+ for (const auto &I : RD->bases()) {
// Don't layout virtual bases.
- if (I->isVirtual())
+ if (I.isVirtual())
continue;
const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
CharUnits BaseOffset = Base.getBaseOffset() +
@@ -88,10 +86,9 @@ VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
return;
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
+ for (const auto &I : RD->bases()) {
const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
// Itanium C++ ABI 2.6.2:
// Secondary virtual pointers are present for all bases with either
@@ -106,7 +103,7 @@ VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
bool BaseDeclIsNonVirtualPrimaryBase = false;
CharUnits BaseOffset;
- if (I->isVirtual()) {
+ if (I.isVirtual()) {
// Ignore virtual bases that we've already visited.
if (!VBases.insert(BaseDecl))
continue;
@@ -153,13 +150,12 @@ VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
VisitedVirtualBasesSetTy &VBases) {
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
+ for (const auto &I : RD->bases()) {
const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
// Check if this is a virtual base.
- if (I->isVirtual()) {
+ if (I.isVirtual()) {
// Check if we've seen this base before.
if (!VBases.insert(BaseDecl))
continue;
diff --git a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp b/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp
index 5f7ae0f..fa1127f 100644
--- a/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/VTableBuilder.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -43,9 +44,9 @@ struct BaseOffset {
/// path from the derived class to the base class involves a virtual base
/// class.
CharUnits NonVirtualOffset;
-
- BaseOffset() : DerivedClass(0), VirtualBase(0),
- NonVirtualOffset(CharUnits::Zero()) { }
+
+ BaseOffset() : DerivedClass(nullptr), VirtualBase(nullptr),
+ NonVirtualOffset(CharUnits::Zero()) { }
BaseOffset(const CXXRecordDecl *DerivedClass,
const CXXRecordDecl *VirtualBase, CharUnits NonVirtualOffset)
: DerivedClass(DerivedClass), VirtualBase(VirtualBase),
@@ -63,10 +64,15 @@ public:
/// Method - The method decl of the overrider.
const CXXMethodDecl *Method;
+ /// VirtualBase - The virtual base class subobject of this overridder.
+ /// Note that this records the closest derived virtual base class subobject.
+ const CXXRecordDecl *VirtualBase;
+
/// Offset - the base offset of the overrider's parent in the layout class.
CharUnits Offset;
-
- OverriderInfo() : Method(0), Offset(CharUnits::Zero()) { }
+
+ OverriderInfo() : Method(nullptr), VirtualBase(nullptr),
+ Offset(CharUnits::Zero()) { }
};
private:
@@ -200,6 +206,7 @@ FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass,
Overrider.Offset = OverriderOffset;
Overrider.Method = Method.Method;
+ Overrider.VirtualBase = Method.InVirtualSubobject;
}
}
@@ -215,8 +222,8 @@ static BaseOffset ComputeBaseOffset(ASTContext &Context,
CharUnits NonVirtualOffset = CharUnits::Zero();
unsigned NonVirtualStart = 0;
- const CXXRecordDecl *VirtualBase = 0;
-
+ const CXXRecordDecl *VirtualBase = nullptr;
+
// First, look for the virtual base class.
for (int I = Path.size(), E = 0; I != E; --I) {
const CXXBasePathElement &Element = Path[I - 1];
@@ -268,11 +275,11 @@ ComputeReturnAdjustmentBaseOffset(ASTContext &Context,
const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>();
// Canonicalize the return types.
- CanQualType CanDerivedReturnType =
- Context.getCanonicalType(DerivedFT->getResultType());
- CanQualType CanBaseReturnType =
- Context.getCanonicalType(BaseFT->getResultType());
-
+ CanQualType CanDerivedReturnType =
+ Context.getCanonicalType(DerivedFT->getReturnType());
+ CanQualType CanBaseReturnType =
+ Context.getCanonicalType(BaseFT->getReturnType());
+
assert(CanDerivedReturnType->getTypeClass() ==
CanBaseReturnType->getTypeClass() &&
"Types must have same type class!");
@@ -337,13 +344,12 @@ FinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual,
OffsetInLayoutClass;
// Traverse our bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+ for (const auto &B : RD->bases()) {
+ const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
CharUnits BaseOffset;
CharUnits BaseOffsetInLayoutClass;
- if (I->isVirtual()) {
+ if (B.isVirtual()) {
// Check if we've visited this virtual base before.
if (SubobjectOffsets.count(std::make_pair(BaseDecl, 0)))
continue;
@@ -363,7 +369,7 @@ FinalOverriders::ComputeBaseOffsets(BaseSubobject Base, bool IsVirtual,
}
ComputeBaseOffsets(BaseSubobject(BaseDecl, BaseOffset),
- I->isVirtual(), BaseOffsetInLayoutClass,
+ B.isVirtual(), BaseOffsetInLayoutClass,
SubobjectOffsets, SubobjectLayoutClassOffsets,
SubobjectCounts);
}
@@ -374,16 +380,15 @@ void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base,
const CXXRecordDecl *RD = Base.getBase();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+ for (const auto &B : RD->bases()) {
+ const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
// Ignore bases that don't have any virtual member functions.
if (!BaseDecl->isPolymorphic())
continue;
CharUnits BaseOffset;
- if (I->isVirtual()) {
+ if (B.isVirtual()) {
if (!VisitedVirtualBases.insert(BaseDecl)) {
// We've visited this base before.
continue;
@@ -397,21 +402,22 @@ void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base,
dump(Out, BaseSubobject(BaseDecl, BaseOffset), VisitedVirtualBases);
}
- Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", ";
+ Out << "Final overriders for (";
+ RD->printQualifiedName(Out);
+ Out << ", ";
Out << Base.getBaseOffset().getQuantity() << ")\n";
// Now dump the overriders for this base subobject.
- for (CXXRecordDecl::method_iterator I = RD->method_begin(),
- E = RD->method_end(); I != E; ++I) {
- const CXXMethodDecl *MD = *I;
-
+ for (const auto *MD : RD->methods()) {
if (!MD->isVirtual())
continue;
OverriderInfo Overrider = getOverrider(MD, Base.getBaseOffset());
- Out << " " << MD->getQualifiedNameAsString() << " - (";
- Out << Overrider.Method->getQualifiedNameAsString();
+ Out << " ";
+ MD->printQualifiedName(Out);
+ Out << " - (";
+ Overrider.Method->printQualifiedName(Out);
Out << ", " << Overrider.Offset.getQuantity() << ')';
BaseOffset Offset;
@@ -420,8 +426,10 @@ void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base,
if (!Offset.isEmpty()) {
Out << " [ret-adj: ";
- if (Offset.VirtualBase)
- Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, ";
+ if (Offset.VirtualBase) {
+ Offset.VirtualBase->printQualifiedName(Out);
+ Out << " vbase, ";
+ }
Out << Offset.NonVirtualOffset.getQuantity() << " nv]";
}
@@ -472,10 +480,10 @@ static bool HasSameVirtualSignature(const CXXMethodDecl *LHS,
// list here because there isn't necessarily an inheritance
// relationship between the two methods.
if (LT->getTypeQuals() != RT->getTypeQuals() ||
- LT->getNumArgs() != RT->getNumArgs())
+ LT->getNumParams() != RT->getNumParams())
return false;
- for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I)
- if (LT->getArgType(I) != RT->getArgType(I))
+ for (unsigned I = 0, E = LT->getNumParams(); I != E; ++I)
+ if (LT->getParamType(I) != RT->getParamType(I))
return false;
return true;
}
@@ -684,10 +692,7 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base,
}
// Add the vcall offsets.
- for (CXXRecordDecl::method_iterator I = RD->method_begin(),
- E = RD->method_end(); I != E; ++I) {
- const CXXMethodDecl *MD = *I;
-
+ for (const auto *MD : RD->methods()) {
if (!MD->isVirtual())
continue;
@@ -715,13 +720,11 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base,
}
// And iterate over all non-virtual bases (ignoring the primary base).
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
-
- if (I->isVirtual())
+ for (const auto &B : RD->bases()) {
+ if (B.isVirtual())
continue;
- const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+ const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
if (BaseDecl == PrimaryBase)
continue;
@@ -741,12 +744,11 @@ VCallAndVBaseOffsetBuilder::AddVBaseOffsets(const CXXRecordDecl *RD,
Context.getASTRecordLayout(LayoutClass);
// Add vbase offsets.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+ for (const auto &B : RD->bases()) {
+ const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
// Check if this is a virtual base that we haven't visited before.
- if (I->isVirtual() && VisitedVirtualBases.insert(BaseDecl)) {
+ if (B.isVirtual() && VisitedVirtualBases.insert(BaseDecl)) {
CharUnits Offset =
LayoutClassLayout.getVBaseClassOffset(BaseDecl) - OffsetInLayoutClass;
@@ -1294,7 +1296,7 @@ ThisAdjustment ItaniumVTableBuilder::ComputeThisAdjustment(
// We don't have vcall offsets for this virtual base, go ahead and
// build them.
VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass,
- /*FinalOverriders=*/0,
+ /*FinalOverriders=*/nullptr,
BaseSubobject(Offset.VirtualBase,
CharUnits::Zero()),
/*BaseIsVirtual=*/true,
@@ -1448,8 +1450,8 @@ FindNearestOverriddenMethod(const CXXMethodDecl *MD,
return OverriddenMD;
}
}
-
- return 0;
+
+ return nullptr;
}
void ItaniumVTableBuilder::AddMethods(
@@ -1503,16 +1505,13 @@ void ItaniumVTableBuilder::AddMethods(
llvm_unreachable("Found a duplicate primary base!");
}
- const CXXDestructorDecl *ImplicitVirtualDtor = 0;
+ const CXXDestructorDecl *ImplicitVirtualDtor = nullptr;
typedef llvm::SmallVector<const CXXMethodDecl *, 8> NewVirtualFunctionsTy;
NewVirtualFunctionsTy NewVirtualFunctions;
// Now go through all virtual member functions and add them.
- for (CXXRecordDecl::method_iterator I = RD->method_begin(),
- E = RD->method_end(); I != E; ++I) {
- const CXXMethodDecl *MD = *I;
-
+ for (const auto *MD : RD->methods()) {
if (!MD->isVirtual())
continue;
@@ -1759,13 +1758,12 @@ ItaniumVTableBuilder::LayoutSecondaryVTables(BaseSubobject Base,
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
+ for (const auto &B : RD->bases()) {
// Ignore virtual bases, we'll emit them later.
- if (I->isVirtual())
+ if (B.isVirtual())
continue;
- const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+ const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
// Ignore bases that don't have a vtable.
if (!BaseDecl->isDynamicClass())
@@ -1838,13 +1836,12 @@ void ItaniumVTableBuilder::DeterminePrimaryVirtualBases(
}
// Traverse bases, looking for more primary virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+ for (const auto &B : RD->bases()) {
+ const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
CharUnits BaseOffsetInLayoutClass;
- if (I->isVirtual()) {
+ if (B.isVirtual()) {
if (!VBases.insert(BaseDecl))
continue;
@@ -1868,13 +1865,12 @@ void ItaniumVTableBuilder::LayoutVTablesForVirtualBases(
// Then come the virtual base virtual tables, also in inheritance graph
// order, and again excluding primary bases (which share virtual tables with
// the classes for which they are primary).
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+ for (const auto &B : RD->bases()) {
+ const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
// Check if this base needs a vtable. (If it's virtual, not a primary base
// of some other class, and we haven't visited it before).
- if (I->isVirtual() && BaseDecl->isDynamicClass() &&
+ if (B.isVirtual() && BaseDecl->isDynamicClass() &&
!PrimaryVirtualBases.count(BaseDecl) && VBases.insert(BaseDecl)) {
const ASTRecordLayout &MostDerivedClassLayout =
Context.getASTRecordLayout(MostDerivedClass);
@@ -1900,21 +1896,6 @@ void ItaniumVTableBuilder::LayoutVTablesForVirtualBases(
}
}
-struct ItaniumThunkInfoComparator {
- bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) {
- assert(LHS.Method == 0);
- assert(RHS.Method == 0);
-
- if (LHS.This != RHS.This)
- return LHS.This < RHS.This;
-
- if (LHS.Return != RHS.Return)
- return LHS.Return < RHS.Return;
-
- return false;
- }
-};
-
/// dumpLayout - Dump the vtable layout.
void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
// FIXME: write more tests that actually use the dumpLayout output to prevent
@@ -1922,12 +1903,13 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
if (isBuildingConstructorVTable()) {
Out << "Construction vtable for ('";
- Out << MostDerivedClass->getQualifiedNameAsString() << "', ";
+ MostDerivedClass->printQualifiedName(Out);
+ Out << "', ";
Out << MostDerivedClassOffset.getQuantity() << ") in '";
- Out << LayoutClass->getQualifiedNameAsString();
+ LayoutClass->printQualifiedName(Out);
} else {
Out << "Vtable for '";
- Out << MostDerivedClass->getQualifiedNameAsString();
+ MostDerivedClass->printQualifiedName(Out);
}
Out << "' (" << Components.size() << " entries).\n";
@@ -1973,7 +1955,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
break;
case VTableComponent::CK_RTTI:
- Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI";
+ Component.getRTTIDecl()->printQualifiedName(Out);
+ Out << " RTTI";
break;
case VTableComponent::CK_FunctionPointer: {
@@ -2028,7 +2011,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
const CXXDestructorDecl *DD = Component.getDestructorDecl();
- Out << DD->getQualifiedNameAsString();
+ DD->printQualifiedName(Out);
if (IsComplete)
Out << "() [complete]";
else
@@ -2078,7 +2061,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
const BaseSubobject &Base =
AddressPointsByIndex.find(NextIndex)->second;
- Out << " -- (" << Base.getBase()->getQualifiedNameAsString();
+ Out << " -- (";
+ Base.getBase()->printQualifiedName(Out);
Out << ", " << Base.getBaseOffset().getQuantity();
Out << ") vtable address --\n";
} else {
@@ -2124,7 +2108,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
}
Out << "Virtual base offset offsets for '";
- Out << MostDerivedClass->getQualifiedNameAsString() << "' (";
+ MostDerivedClass->printQualifiedName(Out);
+ Out << "' (";
Out << ClassNamesAndOffsets.size();
Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n";
@@ -2158,7 +2143,10 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
ThunkInfoVectorTy ThunksVector = Thunks[MD];
std::sort(ThunksVector.begin(), ThunksVector.end(),
- ItaniumThunkInfoComparator());
+ [](const ThunkInfo &LHS, const ThunkInfo &RHS) {
+ assert(LHS.Method == nullptr && RHS.Method == nullptr);
+ return std::tie(LHS.This, LHS.Return) < std::tie(RHS.This, RHS.Return);
+ });
Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
@@ -2203,10 +2191,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
// Store them in a map keyed by the index so we'll get a sorted table.
std::map<uint64_t, std::string> IndicesMap;
- for (CXXRecordDecl::method_iterator i = MostDerivedClass->method_begin(),
- e = MostDerivedClass->method_end(); i != e; ++i) {
- const CXXMethodDecl *MD = *i;
-
+ for (const auto *MD : MostDerivedClass->methods()) {
// We only want virtual member functions.
if (!MD->isVirtual())
continue;
@@ -2230,7 +2215,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
// Print the vtable indices for all the member functions.
if (!IndicesMap.empty()) {
Out << "VTable indices for '";
- Out << MostDerivedClass->getQualifiedNameAsString();
+ MostDerivedClass->printQualifiedName(Out);
Out << "' (" << IndicesMap.size() << " entries).\n";
for (std::map<uint64_t, std::string>::const_iterator I = IndicesMap.begin(),
@@ -2245,17 +2230,6 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
Out << '\n';
}
-
-struct VTableThunksComparator {
- bool operator()(const VTableLayout::VTableThunkTy &LHS,
- const VTableLayout::VTableThunkTy &RHS) {
- if (LHS.first == RHS.first) {
- assert(LHS.second == RHS.second &&
- "Different thunks should have unique indices!");
- }
- return LHS.first < RHS.first;
- }
-};
}
VTableLayout::VTableLayout(uint64_t NumVTableComponents,
@@ -2276,14 +2250,18 @@ VTableLayout::VTableLayout(uint64_t NumVTableComponents,
this->VTableThunks.get());
std::sort(this->VTableThunks.get(),
this->VTableThunks.get() + NumVTableThunks,
- VTableThunksComparator());
+ [](const VTableLayout::VTableThunkTy &LHS,
+ const VTableLayout::VTableThunkTy &RHS) {
+ assert((LHS.first != RHS.first || LHS.second == RHS.second) &&
+ "Different thunks should have unique indices!");
+ return LHS.first < RHS.first;
+ });
}
VTableLayout::~VTableLayout() { }
ItaniumVTableContext::ItaniumVTableContext(ASTContext &Context)
- : IsMicrosoftABI(Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-}
+ : VTableContextBase(/*MS=*/false) {}
ItaniumVTableContext::~ItaniumVTableContext() {
llvm::DeleteContainerSeconds(VTableLayouts);
@@ -2312,8 +2290,8 @@ ItaniumVTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
VirtualBaseClassOffsetOffsets.find(ClassPair);
if (I != VirtualBaseClassOffsetOffsets.end())
return I->second;
-
- VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0,
+
+ VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/nullptr,
BaseSubobject(RD, CharUnits::Zero()),
/*BaseIsVirtual=*/false,
/*OffsetInLayoutClass=*/CharUnits::Zero());
@@ -2348,8 +2326,6 @@ static VTableLayout *CreateVTableLayout(const ItaniumVTableBuilder &Builder) {
void
ItaniumVTableContext::computeVTableRelatedInformation(const CXXRecordDecl *RD) {
- assert(!IsMicrosoftABI && "Shouldn't be called in this ABI!");
-
const VTableLayout *&Entry = VTableLayouts[RD];
// Check if we've computed this information before.
@@ -2444,6 +2420,9 @@ public:
typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
MethodVFTableLocationsTy;
+ typedef llvm::iterator_range<MethodVFTableLocationsTy::const_iterator>
+ method_locations_range;
+
private:
/// VTables - Global vtable information.
MicrosoftVTableContext &VTables;
@@ -2457,7 +2436,7 @@ private:
const ASTRecordLayout &MostDerivedClassLayout;
- VFPtrInfo WhichVFPtr;
+ const VPtrInfo &WhichVFPtr;
/// FinalOverriders - The final overriders of the most derived class.
const FinalOverriders Overriders;
@@ -2467,6 +2446,9 @@ private:
MethodVFTableLocationsTy MethodVFTableLocations;
+ /// \brief Does this class have an RTTI component?
+ bool HasRTTIComponent;
+
/// MethodInfo - Contains information about a method in a vtable.
/// (Used for computing 'this' pointer adjustment thunks.
struct MethodInfo {
@@ -2521,11 +2503,8 @@ private:
}
/// ComputeThisOffset - Returns the 'this' argument offset for the given
- /// method in the given subobject, relative to the beginning of the
- /// MostDerivedClass.
- CharUnits ComputeThisOffset(const CXXMethodDecl *MD,
- BaseSubobject Base,
- FinalOverriders::OverriderInfo Overrider);
+ /// method, relative to the beginning of the MostDerivedClass.
+ CharUnits ComputeThisOffset(FinalOverriders::OverriderInfo Overrider);
void CalculateVtordispAdjustment(FinalOverriders::OverriderInfo Overrider,
CharUnits ThisOffset, ThisAdjustment &TA);
@@ -2533,17 +2512,21 @@ private:
/// AddMethod - Add a single virtual member function to the vftable
/// components vector.
void AddMethod(const CXXMethodDecl *MD, ThunkInfo TI) {
+ if (!TI.isEmpty()) {
+ VTableThunks[Components.size()] = TI;
+ AddThunk(MD, TI);
+ }
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
assert(TI.Return.isEmpty() &&
"Destructor can't have return adjustment!");
Components.push_back(VTableComponent::MakeDeletingDtor(DD));
} else {
- if (!TI.isEmpty())
- VTableThunks[Components.size()] = TI;
Components.push_back(VTableComponent::MakeFunction(MD));
}
}
+ bool NeedsReturnAdjustingThunk(const CXXMethodDecl *MD);
+
/// AddMethods - Add the methods of this base subobject and the relevant
/// subbases to the vftable we're currently laying out.
void AddMethods(BaseSubobject Base, unsigned BaseDepth,
@@ -2555,8 +2538,9 @@ private:
// pointing to the middle of a section.
BasesSetVectorTy VisitedBases;
- AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, 0,
+ AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, nullptr,
VisitedBases);
+ assert(Components.size() && "vftable can't be empty");
assert(MethodVFTableLocations.empty());
for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(),
@@ -2567,8 +2551,8 @@ private:
// and the entries shadowed by return adjusting thunks.
if (MD->getParent() != MostDerivedClass || MI.Shadowed)
continue;
- MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.LastVBase,
- WhichVFPtr.VFPtrOffset, MI.VFTableIndex);
+ MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.getVBaseWithVPtr(),
+ WhichVFPtr.NonVirtualOffset, MI.VFTableIndex);
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc;
} else {
@@ -2586,13 +2570,20 @@ private:
public:
VFTableBuilder(MicrosoftVTableContext &VTables,
- const CXXRecordDecl *MostDerivedClass, VFPtrInfo Which)
+ const CXXRecordDecl *MostDerivedClass, const VPtrInfo *Which)
: VTables(VTables),
Context(MostDerivedClass->getASTContext()),
MostDerivedClass(MostDerivedClass),
MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)),
- WhichVFPtr(Which),
+ WhichVFPtr(*Which),
Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) {
+ // Only include the RTTI component if we know that we will provide a
+ // definition of the vftable.
+ HasRTTIComponent = Context.getLangOpts().RTTIData &&
+ !MostDerivedClass->hasAttr<DLLImportAttr>();
+ if (HasRTTIComponent)
+ Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
+
LayoutVFTable();
if (Context.getLangOpts().DumpVTableLayouts)
@@ -2605,12 +2596,9 @@ public:
ThunksMapTy::const_iterator thunks_end() const { return Thunks.end(); }
- MethodVFTableLocationsTy::const_iterator vtable_indices_begin() const {
- return MethodVFTableLocations.begin();
- }
-
- MethodVFTableLocationsTy::const_iterator vtable_indices_end() const {
- return MethodVFTableLocations.end();
+ method_locations_range vtable_locations() const {
+ return method_locations_range(MethodVFTableLocations.begin(),
+ MethodVFTableLocations.end());
}
uint64_t getNumVTableComponents() const { return Components.size(); }
@@ -2634,6 +2622,8 @@ public:
void dumpLayout(raw_ostream &);
};
+} // end namespace
+
/// InitialOverriddenDefinitionCollector - Finds the set of least derived bases
/// that define the given method.
struct InitialOverriddenDefinitionCollector {
@@ -2655,14 +2645,18 @@ static bool BaseInSet(const CXXBaseSpecifier *Specifier,
}
CharUnits
-VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD,
- BaseSubobject Base,
- FinalOverriders::OverriderInfo Overrider) {
+VFTableBuilder::ComputeThisOffset(FinalOverriders::OverriderInfo Overrider) {
InitialOverriddenDefinitionCollector Collector;
- visitAllOverriddenMethods(MD, Collector);
+ visitAllOverriddenMethods(Overrider.Method, Collector);
+
+ // If there are no overrides then 'this' is located
+ // in the base that defines the method.
+ if (Collector.Bases.size() == 0)
+ return Overrider.Offset;
CXXBasePaths Paths;
- Base.getBase()->lookupInBases(BaseInSet, &Collector.Bases, Paths);
+ Overrider.Method->getParent()->lookupInBases(BaseInSet, &Collector.Bases,
+ Paths);
// This will hold the smallest this offset among overridees of MD.
// This implies that an offset of a non-virtual base will dominate an offset
@@ -2671,10 +2665,12 @@ VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD,
CharUnits Ret;
bool First = true;
+ const ASTRecordLayout &OverriderRDLayout =
+ Context.getASTRecordLayout(Overrider.Method->getParent());
for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end();
I != E; ++I) {
const CXXBasePath &Path = (*I);
- CharUnits ThisOffset = Base.getBaseOffset();
+ CharUnits ThisOffset = Overrider.Offset;
CharUnits LastVBaseOffset;
// For each path from the overrider to the parents of the overridden methods,
@@ -2687,34 +2683,33 @@ VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD,
const ASTRecordLayout &Layout = Context.getASTRecordLayout(PrevRD);
if (Element.Base->isVirtual()) {
- LastVBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(CurRD);
- if (Overrider.Method->getParent() == PrevRD) {
- // This one's interesting. If the final overrider is in a vbase B of the
- // most derived class and it overrides a method of the B's own vbase A,
- // it uses A* as "this". In its prologue, it can cast A* to B* with
- // a static offset. This offset is used regardless of the actual
- // offset of A from B in the most derived class, requiring an
- // this-adjusting thunk in the vftable if A and B are laid out
- // differently in the most derived class.
- ThisOffset += Layout.getVBaseClassOffset(CurRD);
- } else {
- ThisOffset = LastVBaseOffset;
- }
+ // The interesting things begin when you have virtual inheritance.
+ // The final overrider will use a static adjustment equal to the offset
+ // of the vbase in the final overrider class.
+ // For example, if the final overrider is in a vbase B of the most
+ // derived class and it overrides a method of the B's own vbase A,
+ // it uses A* as "this". In its prologue, it can cast A* to B* with
+ // a static offset. This offset is used regardless of the actual
+ // offset of A from B in the most derived class, requiring an
+ // this-adjusting thunk in the vftable if A and B are laid out
+ // differently in the most derived class.
+ LastVBaseOffset = ThisOffset =
+ Overrider.Offset + OverriderRDLayout.getVBaseClassOffset(CurRD);
} else {
ThisOffset += Layout.getBaseClassOffset(CurRD);
}
}
- if (isa<CXXDestructorDecl>(MD)) {
+ if (isa<CXXDestructorDecl>(Overrider.Method)) {
if (LastVBaseOffset.isZero()) {
// If a "Base" class has at least one non-virtual base with a virtual
// destructor, the "Base" virtual destructor will take the address
// of the "Base" subobject as the "this" argument.
- return Base.getBaseOffset();
+ ThisOffset = Overrider.Offset;
} else {
// A virtual destructor of a virtual base takes the address of the
// virtual base subobject as the "this" argument.
- return LastVBaseOffset;
+ ThisOffset = LastVBaseOffset;
}
}
@@ -2734,39 +2729,35 @@ void VFTableBuilder::CalculateVtordispAdjustment(
const ASTRecordLayout::VBaseOffsetsMapTy &VBaseMap =
MostDerivedClassLayout.getVBaseOffsetsMap();
const ASTRecordLayout::VBaseOffsetsMapTy::const_iterator &VBaseMapEntry =
- VBaseMap.find(WhichVFPtr.LastVBase);
+ VBaseMap.find(WhichVFPtr.getVBaseWithVPtr());
assert(VBaseMapEntry != VBaseMap.end());
- // Check if we need a vtordisp adjustment at all.
- if (!VBaseMapEntry->second.hasVtorDisp())
+ // If there's no vtordisp or the final overrider is defined in the same vbase
+ // as the initial declaration, we don't need any vtordisp adjustment.
+ if (!VBaseMapEntry->second.hasVtorDisp() ||
+ Overrider.VirtualBase == WhichVFPtr.getVBaseWithVPtr())
return;
- CharUnits VFPtrVBaseOffset = VBaseMapEntry->second.VBaseOffset;
+ // OK, now we know we need to use a vtordisp thunk.
// The implicit vtordisp field is located right before the vbase.
+ CharUnits VFPtrVBaseOffset = VBaseMapEntry->second.VBaseOffset;
TA.Virtual.Microsoft.VtordispOffset =
- (VFPtrVBaseOffset - WhichVFPtr.VFPtrFullOffset).getQuantity() - 4;
-
- // If the final overrider is defined in either:
- // - the most derived class or its non-virtual base or
- // - the same vbase as the initial declaration,
- // a simple vtordisp thunk will suffice.
- const CXXRecordDecl *OverriderRD = Overrider.Method->getParent();
- if (OverriderRD == MostDerivedClass)
- return;
+ (VFPtrVBaseOffset - WhichVFPtr.FullOffsetInMDC).getQuantity() - 4;
- const CXXRecordDecl *OverriderVBase =
- ComputeBaseOffset(Context, OverriderRD, MostDerivedClass).VirtualBase;
- if (!OverriderVBase || OverriderVBase == WhichVFPtr.LastVBase)
+ // A simple vtordisp thunk will suffice if the final overrider is defined
+ // in either the most derived class or its non-virtual base.
+ if (Overrider.Method->getParent() == MostDerivedClass ||
+ !Overrider.VirtualBase)
return;
// Otherwise, we need to do use the dynamic offset of the final overrider
// in order to get "this" adjustment right.
TA.Virtual.Microsoft.VBPtrOffset =
- (VFPtrVBaseOffset + WhichVFPtr.VFPtrOffset -
+ (VFPtrVBaseOffset + WhichVFPtr.NonVirtualOffset -
MostDerivedClassLayout.getVBPtrOffset()).getQuantity();
TA.Virtual.Microsoft.VBOffsetOffset =
Context.getTypeSizeInChars(Context.IntTy).getQuantity() *
- VTables.getVBTableIndex(MostDerivedClass, OverriderVBase);
+ VTables.getVBTableIndex(MostDerivedClass, Overrider.VirtualBase);
TA.NonVirtual = (ThisOffset - Overrider.Offset).getQuantity();
}
@@ -2777,25 +2768,20 @@ static void GroupNewVirtualOverloads(
// Put the virtual methods into VirtualMethods in the proper order:
// 1) Group overloads by declaration name. New groups are added to the
// vftable in the order of their first declarations in this class
- // (including overrides).
+ // (including overrides and non-virtual methods).
// 2) In each group, new overloads appear in the reverse order of declaration.
typedef SmallVector<const CXXMethodDecl *, 1> MethodGroup;
SmallVector<MethodGroup, 10> Groups;
typedef llvm::DenseMap<DeclarationName, unsigned> VisitedGroupIndicesTy;
VisitedGroupIndicesTy VisitedGroupIndices;
- for (CXXRecordDecl::method_iterator I = RD->method_begin(),
- E = RD->method_end(); I != E; ++I) {
- const CXXMethodDecl *MD = *I;
- if (!MD->isVirtual())
- continue;
-
+ for (const auto *MD : RD->methods()) {
VisitedGroupIndicesTy::iterator J;
bool Inserted;
- llvm::tie(J, Inserted) = VisitedGroupIndices.insert(
+ std::tie(J, Inserted) = VisitedGroupIndices.insert(
std::make_pair(MD->getDeclName(), Groups.size()));
if (Inserted)
- Groups.push_back(MethodGroup(1, MD));
- else
+ Groups.push_back(MethodGroup());
+ if (MD->isVirtual())
Groups[J->second].push_back(MD);
}
@@ -2803,6 +2789,32 @@ static void GroupNewVirtualOverloads(
VirtualMethods.append(Groups[I].rbegin(), Groups[I].rend());
}
+/// We need a return adjusting thunk for this method if its return type is
+/// not trivially convertible to the return type of any of its overridden
+/// methods.
+bool VFTableBuilder::NeedsReturnAdjustingThunk(const CXXMethodDecl *MD) {
+ OverriddenMethodsSetTy OverriddenMethods;
+ ComputeAllOverriddenMethods(MD, OverriddenMethods);
+ for (OverriddenMethodsSetTy::iterator I = OverriddenMethods.begin(),
+ E = OverriddenMethods.end();
+ I != E; ++I) {
+ const CXXMethodDecl *OverriddenMD = *I;
+ BaseOffset Adjustment =
+ ComputeReturnAdjustmentBaseOffset(Context, MD, OverriddenMD);
+ if (!Adjustment.isEmpty())
+ return true;
+ }
+ return false;
+}
+
+static bool isDirectVBase(const CXXRecordDecl *Base, const CXXRecordDecl *RD) {
+ for (const auto &B : RD->bases()) {
+ if (B.isVirtual() && B.getType()->getAsCXXRecordDecl() == Base)
+ return true;
+ }
+ return false;
+}
+
void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
const CXXRecordDecl *LastVBase,
BasesSetVectorTy &VisitedBases) {
@@ -2814,11 +2826,11 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
// See if this class expands a vftable of the base we look at, which is either
// the one defined by the vfptr base path or the primary base of the current class.
- const CXXRecordDecl *NextBase = 0, *NextLastVBase = LastVBase;
+ const CXXRecordDecl *NextBase = nullptr, *NextLastVBase = LastVBase;
CharUnits NextBaseOffset;
- if (BaseDepth < WhichVFPtr.PathToBaseWithVFPtr.size()) {
- NextBase = WhichVFPtr.PathToBaseWithVFPtr[BaseDepth];
- if (Layout.getVBaseOffsetsMap().count(NextBase)) {
+ if (BaseDepth < WhichVFPtr.PathToBaseWithVPtr.size()) {
+ NextBase = WhichVFPtr.PathToBaseWithVPtr[BaseDepth];
+ if (isDirectVBase(NextBase, RD)) {
NextLastVBase = NextBase;
NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(NextBase);
} else {
@@ -2856,13 +2868,21 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
FinalOverriders::OverriderInfo Overrider =
Overriders.getOverrider(MD, Base.getBaseOffset());
- ThisAdjustment ThisAdjustmentOffset;
- bool ForceThunk = false;
+ const CXXMethodDecl *OverriderMD = Overrider.Method;
+ const CXXMethodDecl *OverriddenMD =
+ FindNearestOverriddenMethod(MD, VisitedBases);
- // Check if this virtual member function overrides
- // a method in one of the visited bases.
- if (const CXXMethodDecl *OverriddenMD =
- FindNearestOverriddenMethod(MD, VisitedBases)) {
+ ThisAdjustment ThisAdjustmentOffset;
+ bool ReturnAdjustingThunk = false;
+ CharUnits ThisOffset = ComputeThisOffset(Overrider);
+ ThisAdjustmentOffset.NonVirtual =
+ (ThisOffset - WhichVFPtr.FullOffsetInMDC).getQuantity();
+ if ((OverriddenMD || OverriderMD != MD) &&
+ WhichVFPtr.getVBaseWithVPtr())
+ CalculateVtordispAdjustment(Overrider, ThisOffset, ThisAdjustmentOffset);
+
+ if (OverriddenMD) {
+ // If MD overrides anything in this vftable, we need to update the entries.
MethodInfoMapTy::iterator OverriddenMDIterator =
MethodInfoMap.find(OverriddenMD);
@@ -2872,23 +2892,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
MethodInfo &OverriddenMethodInfo = OverriddenMDIterator->second;
- // Create a this-adjusting thunk if needed.
- CharUnits TI = ComputeThisOffset(MD, Base, Overrider);
- if (TI != WhichVFPtr.VFPtrFullOffset) {
- ThisAdjustmentOffset.NonVirtual =
- (TI - WhichVFPtr.VFPtrFullOffset).getQuantity();
- }
-
- if (WhichVFPtr.LastVBase)
- CalculateVtordispAdjustment(Overrider, TI, ThisAdjustmentOffset);
-
- if (!ThisAdjustmentOffset.isEmpty()) {
- VTableThunks[OverriddenMethodInfo.VFTableIndex].This =
- ThisAdjustmentOffset;
- AddThunk(MD, VTableThunks[OverriddenMethodInfo.VFTableIndex]);
- }
-
- if (MD->getResultType() == OverriddenMD->getResultType()) {
+ if (!NeedsReturnAdjustingThunk(MD)) {
// No return adjustment needed - just replace the overridden method info
// with the current info.
MethodInfo MI(OverriddenMethodInfo.VBTableIndex,
@@ -2899,33 +2903,17 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
"Should not have method info for this method yet!");
MethodInfoMap.insert(std::make_pair(MD, MI));
continue;
- } else {
- // In case we need a return adjustment, we'll add a new slot for
- // the overrider and put a return-adjusting thunk where the overridden
- // method was in the vftable.
- // For now, just mark the overriden method as shadowed by a new slot.
- OverriddenMethodInfo.Shadowed = true;
- ForceThunk = true;
-
- // Also apply this adjustment to the shadowed slots.
- if (!ThisAdjustmentOffset.isEmpty()) {
- // FIXME: this is O(N^2), can be O(N).
- const CXXMethodDecl *SubOverride = OverriddenMD;
- while ((SubOverride =
- FindNearestOverriddenMethod(SubOverride, VisitedBases))) {
- MethodInfoMapTy::iterator SubOverrideIterator =
- MethodInfoMap.find(SubOverride);
- if (SubOverrideIterator == MethodInfoMap.end())
- break;
- MethodInfo &SubOverrideMI = SubOverrideIterator->second;
- assert(SubOverrideMI.Shadowed);
- VTableThunks[SubOverrideMI.VFTableIndex].This =
- ThisAdjustmentOffset;
- AddThunk(MD, VTableThunks[SubOverrideMI.VFTableIndex]);
- }
- }
}
- } else if (Base.getBaseOffset() != WhichVFPtr.VFPtrFullOffset ||
+
+ // In case we need a return adjustment, we'll add a new slot for
+ // the overrider. Mark the overriden method as shadowed by the new slot.
+ OverriddenMethodInfo.Shadowed = true;
+
+ // Force a special name mangling for a return-adjusting thunk
+ // unless the method is the final overrider without this adjustment.
+ ReturnAdjustingThunk =
+ !(MD == OverriderMD && ThisAdjustmentOffset.isEmpty());
+ } else if (Base.getBaseOffset() != WhichVFPtr.FullOffsetInMDC ||
MD->size_overridden_methods()) {
// Skip methods that don't belong to the vftable of the current class,
// e.g. each method that wasn't seen in any of the visited sub-bases
@@ -2937,14 +2925,13 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
// it requires return adjustment. Insert the method info for this method.
unsigned VBIndex =
LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase) : 0;
- MethodInfo MI(VBIndex, Components.size());
+ MethodInfo MI(VBIndex,
+ HasRTTIComponent ? Components.size() - 1 : Components.size());
assert(!MethodInfoMap.count(MD) &&
"Should not have method info for this method yet!");
MethodInfoMap.insert(std::make_pair(MD, MI));
- const CXXMethodDecl *OverriderMD = Overrider.Method;
-
// Check if this overrider needs a return adjustment.
// We don't want to do this for pure virtual member functions.
BaseOffset ReturnAdjustmentOffset;
@@ -2954,7 +2941,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD);
}
if (!ReturnAdjustmentOffset.isEmpty()) {
- ForceThunk = true;
+ ReturnAdjustingThunk = true;
ReturnAdjustment.NonVirtual =
ReturnAdjustmentOffset.NonVirtualOffset.getQuantity();
if (ReturnAdjustmentOffset.VirtualBase) {
@@ -2969,40 +2956,30 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
}
AddMethod(OverriderMD, ThunkInfo(ThisAdjustmentOffset, ReturnAdjustment,
- ForceThunk ? MD : 0));
+ ReturnAdjustingThunk ? MD : nullptr));
}
}
-void PrintBasePath(const VFPtrInfo::BasePath &Path, raw_ostream &Out) {
- for (VFPtrInfo::BasePath::const_reverse_iterator I = Path.rbegin(),
+static void PrintBasePath(const VPtrInfo::BasePath &Path, raw_ostream &Out) {
+ for (VPtrInfo::BasePath::const_reverse_iterator I = Path.rbegin(),
E = Path.rend(); I != E; ++I) {
- Out << "'" << (*I)->getQualifiedNameAsString() << "' in ";
+ Out << "'";
+ (*I)->printQualifiedName(Out);
+ Out << "' in ";
}
}
-struct MicrosoftThunkInfoStableSortComparator {
- bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) {
- if (LHS.This != RHS.This)
- return LHS.This < RHS.This;
-
- if (LHS.Return != RHS.Return)
- return LHS.Return < RHS.Return;
-
- // Keep different thunks with the same adjustments in the order they
- // were put into the vector.
- return false;
- }
-};
-
static void dumpMicrosoftThunkAdjustment(const ThunkInfo &TI, raw_ostream &Out,
bool ContinueFirstLine) {
const ReturnAdjustment &R = TI.Return;
bool Multiline = false;
- const char *LinePrefix = "\n ";
- if (!R.isEmpty()) {
+ const char *LinePrefix = "\n ";
+ if (!R.isEmpty() || TI.Method) {
if (!ContinueFirstLine)
Out << LinePrefix;
- Out << "[return adjustment: ";
+ Out << "[return adjustment (to type '"
+ << TI.Method->getReturnType().getCanonicalType().getAsString()
+ << "'): ";
if (R.Virtual.Microsoft.VBPtrOffset)
Out << "vbptr at offset " << R.Virtual.Microsoft.VBPtrOffset << ", ";
if (R.Virtual.Microsoft.VBIndex)
@@ -3021,7 +2998,7 @@ static void dumpMicrosoftThunkAdjustment(const ThunkInfo &TI, raw_ostream &Out,
Out << "vtordisp at " << T.Virtual.Microsoft.VtordispOffset << ", ";
if (T.Virtual.Microsoft.VBPtrOffset) {
Out << "vbptr at " << T.Virtual.Microsoft.VBPtrOffset
- << " to the left, ";
+ << " to the left,";
assert(T.Virtual.Microsoft.VBOffsetOffset > 0);
Out << LinePrefix << " vboffset at "
<< T.Virtual.Microsoft.VBOffsetOffset << " in the vbtable, ";
@@ -3033,9 +3010,11 @@ static void dumpMicrosoftThunkAdjustment(const ThunkInfo &TI, raw_ostream &Out,
void VFTableBuilder::dumpLayout(raw_ostream &Out) {
Out << "VFTable for ";
- PrintBasePath(WhichVFPtr.PathToBaseWithVFPtr, Out);
- Out << "'" << MostDerivedClass->getQualifiedNameAsString();
- Out << "' (" << Components.size() << " entries).\n";
+ PrintBasePath(WhichVFPtr.PathToBaseWithVPtr, Out);
+ Out << "'";
+ MostDerivedClass->printQualifiedName(Out);
+ Out << "' (" << Components.size()
+ << (Components.size() == 1 ? " entry" : " entries") << ").\n";
for (unsigned I = 0, E = Components.size(); I != E; ++I) {
Out << llvm::format("%4d | ", I);
@@ -3045,12 +3024,15 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
// Dump the component.
switch (Component.getKind()) {
case VTableComponent::CK_RTTI:
- Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI";
+ Component.getRTTIDecl()->printQualifiedName(Out);
+ Out << " RTTI";
break;
case VTableComponent::CK_FunctionPointer: {
const CXXMethodDecl *MD = Component.getFunctionDecl();
+ // FIXME: Figure out how to print the real thunk type, since they can
+ // differ in the return type.
std::string Str = PredefinedExpr::ComputeName(
PredefinedExpr::PrettyFunctionNoVirtual, MD);
Out << Str;
@@ -3072,7 +3054,7 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
case VTableComponent::CK_DeletingDtorPointer: {
const CXXDestructorDecl *DD = Component.getDestructorDecl();
- Out << DD->getQualifiedNameAsString();
+ DD->printQualifiedName(Out);
Out << "() [scalar deleting]";
if (DD->isPure())
@@ -3124,7 +3106,11 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
ThunkInfoVectorTy ThunksVector = Thunks[MD];
std::stable_sort(ThunksVector.begin(), ThunksVector.end(),
- MicrosoftThunkInfoStableSortComparator());
+ [](const ThunkInfo &LHS, const ThunkInfo &RHS) {
+ // Keep different thunks with the same adjustments in the order they
+ // were put into the vector.
+ return std::tie(LHS.This, LHS.Return) < std::tie(RHS.This, RHS.Return);
+ });
Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
@@ -3140,123 +3126,170 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
Out << '\n';
}
}
-}
+
+ Out.flush();
}
-void MicrosoftVTableContext::enumerateVFPtrs(
- const CXXRecordDecl *MostDerivedClass,
- const ASTRecordLayout &MostDerivedClassLayout, BaseSubobject Base,
- const CXXRecordDecl *LastVBase,
- const VFPtrInfo::BasePath &PathFromCompleteClass,
- BasesSetVectorTy &VisitedVBases,
- VFPtrListTy &Result) {
- const CXXRecordDecl *CurrentClass = Base.getBase();
- CharUnits OffsetInCompleteClass = Base.getBaseOffset();
- const ASTRecordLayout &CurrentClassLayout =
- Context.getASTRecordLayout(CurrentClass);
-
- if (CurrentClassLayout.hasOwnVFPtr()) {
- if (LastVBase) {
- uint64_t VBIndex = getVBTableIndex(MostDerivedClass, LastVBase);
- assert(VBIndex > 0 && "vbases must have vbindex!");
- CharUnits VFPtrOffset =
- OffsetInCompleteClass -
- MostDerivedClassLayout.getVBaseClassOffset(LastVBase);
- Result.push_back(VFPtrInfo(VBIndex, LastVBase, VFPtrOffset,
- PathFromCompleteClass, OffsetInCompleteClass));
- } else {
- Result.push_back(VFPtrInfo(OffsetInCompleteClass, PathFromCompleteClass));
- }
+static bool setsIntersect(const llvm::SmallPtrSet<const CXXRecordDecl *, 4> &A,
+ const ArrayRef<const CXXRecordDecl *> &B) {
+ for (ArrayRef<const CXXRecordDecl *>::iterator I = B.begin(), E = B.end();
+ I != E; ++I) {
+ if (A.count(*I))
+ return true;
}
+ return false;
+}
- for (CXXRecordDecl::base_class_const_iterator I = CurrentClass->bases_begin(),
- E = CurrentClass->bases_end(); I != E; ++I) {
- const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+static bool rebucketPaths(VPtrInfoVector &Paths);
- CharUnits NextBaseOffset;
- const CXXRecordDecl *NextLastVBase;
- if (I->isVirtual()) {
- if (!VisitedVBases.insert(BaseDecl))
- continue;
- NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
- NextLastVBase = BaseDecl;
- } else {
- NextBaseOffset = OffsetInCompleteClass +
- CurrentClassLayout.getBaseClassOffset(BaseDecl);
- NextLastVBase = LastVBase;
- }
+/// Produces MSVC-compatible vbtable data. The symbols produced by this
+/// algorithm match those produced by MSVC 2012 and newer, which is different
+/// from MSVC 2010.
+///
+/// MSVC 2012 appears to minimize the vbtable names using the following
+/// algorithm. First, walk the class hierarchy in the usual order, depth first,
+/// left to right, to find all of the subobjects which contain a vbptr field.
+/// Visiting each class node yields a list of inheritance paths to vbptrs. Each
+/// record with a vbptr creates an initially empty path.
+///
+/// To combine paths from child nodes, the paths are compared to check for
+/// ambiguity. Paths are "ambiguous" if multiple paths have the same set of
+/// components in the same order. Each group of ambiguous paths is extended by
+/// appending the class of the base from which it came. If the current class
+/// node produced an ambiguous path, its path is extended with the current class.
+/// After extending paths, MSVC again checks for ambiguity, and extends any
+/// ambiguous path which wasn't already extended. Because each node yields an
+/// unambiguous set of paths, MSVC doesn't need to extend any path more than once
+/// to produce an unambiguous set of paths.
+///
+/// TODO: Presumably vftables use the same algorithm.
+void MicrosoftVTableContext::computeVTablePaths(bool ForVBTables,
+ const CXXRecordDecl *RD,
+ VPtrInfoVector &Paths) {
+ assert(Paths.empty());
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- VFPtrInfo::BasePath NewPath = PathFromCompleteClass;
- NewPath.push_back(BaseDecl);
- BaseSubobject NextBase(BaseDecl, NextBaseOffset);
+ // Base case: this subobject has its own vptr.
+ if (ForVBTables ? Layout.hasOwnVBPtr() : Layout.hasOwnVFPtr())
+ Paths.push_back(new VPtrInfo(RD));
- enumerateVFPtrs(MostDerivedClass, MostDerivedClassLayout, NextBase,
- NextLastVBase, NewPath, VisitedVBases, Result);
- }
-}
+ // Recursive case: get all the vbtables from our bases and remove anything
+ // that shares a virtual base.
+ llvm::SmallPtrSet<const CXXRecordDecl*, 4> VBasesSeen;
+ for (const auto &B : RD->bases()) {
+ const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
+ if (B.isVirtual() && VBasesSeen.count(Base))
+ continue;
-/// CalculatePathToMangle - Calculate the subset of records that should be used
-/// to mangle the vftable for the given vfptr.
-/// Should only be called if a class has multiple vftables.
-static void
-CalculatePathToMangle(const CXXRecordDecl *RD, VFPtrInfo &VFPtr) {
- // FIXME: In some rare cases this code produces a slightly incorrect mangling.
- // It's very likely that the vbtable mangling code can be adjusted to mangle
- // both vftables and vbtables correctly.
-
- VFPtrInfo::BasePath &FullPath = VFPtr.PathToBaseWithVFPtr;
- if (FullPath.empty()) {
- // Mangle the class's own vftable.
- assert(RD->getNumVBases() &&
- "Something's wrong: if the most derived "
- "class has more than one vftable, it can only have its own "
- "vftable if it has vbases");
- VFPtr.PathToMangle.push_back(RD);
- return;
- }
+ if (!Base->isDynamicClass())
+ continue;
+
+ const VPtrInfoVector &BasePaths =
+ ForVBTables ? enumerateVBTables(Base) : getVFPtrOffsets(Base);
- unsigned Begin = 0;
+ for (VPtrInfo *BaseInfo : BasePaths) {
+ // Don't include the path if it goes through a virtual base that we've
+ // already included.
+ if (setsIntersect(VBasesSeen, BaseInfo->ContainingVBases))
+ continue;
- // First, skip all the bases before the vbase.
- if (VFPtr.LastVBase) {
- while (FullPath[Begin] != VFPtr.LastVBase) {
- Begin++;
- assert(Begin < FullPath.size());
+ // Copy the path and adjust it as necessary.
+ VPtrInfo *P = new VPtrInfo(*BaseInfo);
+
+ // We mangle Base into the path if the path would've been ambiguous and it
+ // wasn't already extended with Base.
+ if (P->MangledPath.empty() || P->MangledPath.back() != Base)
+ P->NextBaseToMangle = Base;
+
+ // Keep track of the full path.
+ // FIXME: Why do we need this?
+ P->PathToBaseWithVPtr.insert(P->PathToBaseWithVPtr.begin(), Base);
+
+ // Keep track of which vtable the derived class is going to extend with
+ // new methods or bases. We append to either the vftable of our primary
+ // base, or the first non-virtual base that has a vbtable.
+ if (P->ReusingBase == Base &&
+ Base == (ForVBTables ? Layout.getBaseSharingVBPtr()
+ : Layout.getPrimaryBase()))
+ P->ReusingBase = RD;
+
+ // Keep track of the full adjustment from the MDC to this vtable. The
+ // adjustment is captured by an optional vbase and a non-virtual offset.
+ if (B.isVirtual())
+ P->ContainingVBases.push_back(Base);
+ else if (P->ContainingVBases.empty())
+ P->NonVirtualOffset += Layout.getBaseClassOffset(Base);
+
+ // Update the full offset in the MDC.
+ P->FullOffsetInMDC = P->NonVirtualOffset;
+ if (const CXXRecordDecl *VB = P->getVBaseWithVPtr())
+ P->FullOffsetInMDC += Layout.getVBaseClassOffset(VB);
+
+ Paths.push_back(P);
}
+
+ if (B.isVirtual())
+ VBasesSeen.insert(Base);
+
+ // After visiting any direct base, we've transitively visited all of its
+ // morally virtual bases.
+ for (const auto &VB : Base->vbases())
+ VBasesSeen.insert(VB.getType()->getAsCXXRecordDecl());
}
- // Then, put the rest of the base path in the reverse order.
- for (unsigned I = FullPath.size(); I != Begin; --I) {
- const CXXRecordDecl *CurBase = FullPath[I - 1],
- *ItsBase = (I == 1) ? RD : FullPath[I - 2];
- bool BaseIsVirtual = false;
- for (CXXRecordDecl::base_class_const_iterator J = ItsBase->bases_begin(),
- F = ItsBase->bases_end(); J != F; ++J) {
- if (J->getType()->getAsCXXRecordDecl() == CurBase) {
- BaseIsVirtual = J->isVirtual();
- break;
- }
- }
+ // Sort the paths into buckets, and if any of them are ambiguous, extend all
+ // paths in ambiguous buckets.
+ bool Changed = true;
+ while (Changed)
+ Changed = rebucketPaths(Paths);
+}
- // Should skip the current base if it is a non-virtual base with no siblings.
- if (BaseIsVirtual || ItsBase->getNumBases() != 1)
- VFPtr.PathToMangle.push_back(CurBase);
+static bool extendPath(VPtrInfo *P) {
+ if (P->NextBaseToMangle) {
+ P->MangledPath.push_back(P->NextBaseToMangle);
+ P->NextBaseToMangle = nullptr;// Prevent the path from being extended twice.
+ return true;
}
+ return false;
}
-void MicrosoftVTableContext::enumerateVFPtrs(
- const CXXRecordDecl *ForClass,
- MicrosoftVTableContext::VFPtrListTy &Result) {
- Result.clear();
- const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(ForClass);
- BasesSetVectorTy VisitedVBases;
- enumerateVFPtrs(ForClass, ClassLayout,
- BaseSubobject(ForClass, CharUnits::Zero()), 0,
- VFPtrInfo::BasePath(), VisitedVBases, Result);
- if (Result.size() > 1) {
- for (unsigned I = 0, E = Result.size(); I != E; ++I)
- CalculatePathToMangle(ForClass, Result[I]);
+static bool rebucketPaths(VPtrInfoVector &Paths) {
+ // What we're essentially doing here is bucketing together ambiguous paths.
+ // Any bucket with more than one path in it gets extended by NextBase, which
+ // is usually the direct base of the inherited the vbptr. This code uses a
+ // sorted vector to implement a multiset to form the buckets. Note that the
+ // ordering is based on pointers, but it doesn't change our output order. The
+ // current algorithm is designed to match MSVC 2012's names.
+ VPtrInfoVector PathsSorted(Paths);
+ std::sort(PathsSorted.begin(), PathsSorted.end(),
+ [](const VPtrInfo *LHS, const VPtrInfo *RHS) {
+ return LHS->MangledPath < RHS->MangledPath;
+ });
+ bool Changed = false;
+ for (size_t I = 0, E = PathsSorted.size(); I != E;) {
+ // Scan forward to find the end of the bucket.
+ size_t BucketStart = I;
+ do {
+ ++I;
+ } while (I != E && PathsSorted[BucketStart]->MangledPath ==
+ PathsSorted[I]->MangledPath);
+
+ // If this bucket has multiple paths, extend them all.
+ if (I - BucketStart > 1) {
+ for (size_t II = BucketStart; II != I; ++II)
+ Changed |= extendPath(PathsSorted[II]);
+ assert(Changed && "no paths were extended to fix ambiguity");
+ }
}
+ return Changed;
+}
+
+MicrosoftVTableContext::~MicrosoftVTableContext() {
+ for (auto &P : VFPtrLocations)
+ llvm::DeleteContainerPointers(*P.second);
+ llvm::DeleteContainerSeconds(VFPtrLocations);
+ llvm::DeleteContainerSeconds(VFTableLayouts);
+ llvm::DeleteContainerSeconds(VBaseInfo);
}
void MicrosoftVTableContext::computeVTableRelatedInformation(
@@ -3269,24 +3302,31 @@ void MicrosoftVTableContext::computeVTableRelatedInformation(
const VTableLayout::AddressPointsMapTy EmptyAddressPointsMap;
- VFPtrListTy &VFPtrs = VFPtrLocations[RD];
- enumerateVFPtrs(RD, VFPtrs);
+ VPtrInfoVector *VFPtrs = new VPtrInfoVector();
+ computeVTablePaths(/*ForVBTables=*/false, RD, *VFPtrs);
+ VFPtrLocations[RD] = VFPtrs;
MethodVFTableLocationsTy NewMethodLocations;
- for (VFPtrListTy::iterator I = VFPtrs.begin(), E = VFPtrs.end();
+ for (VPtrInfoVector::iterator I = VFPtrs->begin(), E = VFPtrs->end();
I != E; ++I) {
VFTableBuilder Builder(*this, RD, *I);
- VFTableIdTy id(RD, I->VFPtrFullOffset);
+ VFTableIdTy id(RD, (*I)->FullOffsetInMDC);
assert(VFTableLayouts.count(id) == 0);
SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks(
Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
VFTableLayouts[id] = new VTableLayout(
Builder.getNumVTableComponents(), Builder.vtable_component_begin(),
VTableThunks.size(), VTableThunks.data(), EmptyAddressPointsMap, true);
- NewMethodLocations.insert(Builder.vtable_indices_begin(),
- Builder.vtable_indices_end());
Thunks.insert(Builder.thunks_begin(), Builder.thunks_end());
+
+ for (const auto &Loc : Builder.vtable_locations()) {
+ GlobalDecl GD = Loc.first;
+ MethodVFTableLocation NewLoc = Loc.second;
+ auto M = NewMethodLocations.find(GD);
+ if (M == NewMethodLocations.end() || NewLoc < M->second)
+ NewMethodLocations[GD] = NewLoc;
+ }
}
MethodVFTableLocations.insert(NewMethodLocations.begin(),
@@ -3324,8 +3364,10 @@ void MicrosoftVTableContext::dumpMethodLocations(
// Print the vtable indices for all the member functions.
if (!IndicesMap.empty()) {
Out << "VFTable indices for ";
- Out << "'" << RD->getQualifiedNameAsString();
- Out << "' (" << IndicesMap.size() << " entries).\n";
+ Out << "'";
+ RD->printQualifiedName(Out);
+ Out << "' (" << IndicesMap.size()
+ << (IndicesMap.size() == 1 ? " entry" : " entries") << ").\n";
CharUnits LastVFPtrOffset = CharUnits::fromQuantity(-1);
uint64_t LastVBIndex = 0;
@@ -3352,49 +3394,66 @@ void MicrosoftVTableContext::dumpMethodLocations(
}
Out << '\n';
}
+
+ Out.flush();
}
-void MicrosoftVTableContext::computeVBTableRelatedInformation(
+const VirtualBaseInfo *MicrosoftVTableContext::computeVBTableRelatedInformation(
const CXXRecordDecl *RD) {
- if (ComputedVBTableIndices.count(RD))
- return;
- ComputedVBTableIndices.insert(RD);
+ VirtualBaseInfo *VBI;
- const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- BasesSetVectorTy VisitedBases;
+ {
+ // Get or create a VBI for RD. Don't hold a reference to the DenseMap cell,
+ // as it may be modified and rehashed under us.
+ VirtualBaseInfo *&Entry = VBaseInfo[RD];
+ if (Entry)
+ return Entry;
+ Entry = VBI = new VirtualBaseInfo();
+ }
+
+ computeVTablePaths(/*ForVBTables=*/true, RD, VBI->VBPtrPaths);
// First, see if the Derived class shared the vbptr with a non-virtual base.
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
if (const CXXRecordDecl *VBPtrBase = Layout.getBaseSharingVBPtr()) {
- // If the Derived class shares the vbptr with a non-virtual base,
- // it inherits its vbase indices.
- computeVBTableRelatedInformation(VBPtrBase);
- for (CXXRecordDecl::base_class_const_iterator I = VBPtrBase->vbases_begin(),
- E = VBPtrBase->vbases_end(); I != E; ++I) {
- const CXXRecordDecl *SubVBase = I->getType()->getAsCXXRecordDecl();
- assert(VBTableIndices.count(ClassPairTy(VBPtrBase, SubVBase)));
- VBTableIndices[ClassPairTy(RD, SubVBase)] =
- VBTableIndices[ClassPairTy(VBPtrBase, SubVBase)];
- VisitedBases.insert(SubVBase);
- }
+ // If the Derived class shares the vbptr with a non-virtual base, the shared
+ // virtual bases come first so that the layout is the same.
+ const VirtualBaseInfo *BaseInfo =
+ computeVBTableRelatedInformation(VBPtrBase);
+ VBI->VBTableIndices.insert(BaseInfo->VBTableIndices.begin(),
+ BaseInfo->VBTableIndices.end());
}
// New vbases are added to the end of the vbtable.
// Skip the self entry and vbases visited in the non-virtual base, if any.
- unsigned VBTableIndex = 1 + VisitedBases.size();
- for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
- E = RD->vbases_end(); I != E; ++I) {
- const CXXRecordDecl *CurVBase = I->getType()->getAsCXXRecordDecl();
- if (VisitedBases.insert(CurVBase))
- VBTableIndices[ClassPairTy(RD, CurVBase)] = VBTableIndex++;
+ unsigned VBTableIndex = 1 + VBI->VBTableIndices.size();
+ for (const auto &VB : RD->vbases()) {
+ const CXXRecordDecl *CurVBase = VB.getType()->getAsCXXRecordDecl();
+ if (!VBI->VBTableIndices.count(CurVBase))
+ VBI->VBTableIndices[CurVBase] = VBTableIndex++;
}
+
+ return VBI;
+}
+
+unsigned MicrosoftVTableContext::getVBTableIndex(const CXXRecordDecl *Derived,
+ const CXXRecordDecl *VBase) {
+ const VirtualBaseInfo *VBInfo = computeVBTableRelatedInformation(Derived);
+ assert(VBInfo->VBTableIndices.count(VBase));
+ return VBInfo->VBTableIndices.find(VBase)->second;
+}
+
+const VPtrInfoVector &
+MicrosoftVTableContext::enumerateVBTables(const CXXRecordDecl *RD) {
+ return computeVBTableRelatedInformation(RD)->VBPtrPaths;
}
-const MicrosoftVTableContext::VFPtrListTy &
+const VPtrInfoVector &
MicrosoftVTableContext::getVFPtrOffsets(const CXXRecordDecl *RD) {
computeVTableRelatedInformation(RD);
assert(VFPtrLocations.count(RD) && "Couldn't find vfptr locations");
- return VFPtrLocations[RD];
+ return *VFPtrLocations[RD];
}
const VTableLayout &
OpenPOWER on IntegriCloud