From: Abramo Bagnara Date: Wed, 26 May 2010 18:09:23 +0000 (+0000) Subject: Added source order to CXXBaseOrMemberInitializer. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a0af3b453160fc4c67363c204da13820b0586909;p=clang Added source order to CXXBaseOrMemberInitializer. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104712 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 538da74776..a8f7b7a272 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1068,14 +1068,20 @@ class CXXBaseOrMemberInitializer { /// RParenLoc - Location of the right paren of the ctor-initializer. SourceLocation RParenLoc; - /// \brief The number of array index variables stored after this object - /// in memory. - unsigned NumArrayIndices; - /// IsVirtual - If the initializer is a base initializer, this keeps track /// of whether the base is virtual or not. - bool IsVirtual; - + bool IsVirtual : 1; + + /// IsWritten - Whether or not the initializer is explicitly written + /// in the sources. + bool IsWritten : 1; + /// SourceOrderOrNumArrayIndices - If IsImplicit is false, then this + /// number keeps track of the textual order of this initializer in the + /// original sources, counting from 0; otherwise, if IsImplicit is true, + /// it stores the number of array index variables stored after this + /// object in memory. + unsigned SourceOrderOrNumArrayIndices : 14; + CXXBaseOrMemberInitializer(ASTContext &Context, FieldDecl *Member, SourceLocation MemberLoc, SourceLocation L, @@ -1169,6 +1175,30 @@ public: /// \brief Determine the source range covering the entire initializer. SourceRange getSourceRange() const; + + /// isWritten - Returns true if this initializer is explicitly written + /// in the source code. + bool isWritten() const { return IsWritten; } + + /// \brief Return the source position of the initializer, counting from 0. + /// If the initializer was implicit, -1 is returned. + int getSourceOrder() const { + return IsWritten ? static_cast(SourceOrderOrNumArrayIndices) : -1; + } + + /// \brief Set the source order of this initializer. This method can only + /// be called once for each initializer; it cannot be called on an + /// initializer having a positive number of (implicit) array indices. + void setSourceOrder(int pos) { + assert(!IsWritten && + "calling twice setSourceOrder() on the same initializer"); + assert(SourceOrderOrNumArrayIndices == 0 && + "setSourceOrder() used when there are implicit array indices"); + assert(pos >= 0 && + "setSourceOrder() used to make an initializer implicit"); + IsWritten = true; + SourceOrderOrNumArrayIndices = static_cast(pos); + } FieldDecl *getAnonUnionMember() const { return AnonUnionMember; @@ -1183,20 +1213,22 @@ public: /// \brief Determine the number of implicit array indices used while /// described an array member initialization. - unsigned getNumArrayIndices() const { return NumArrayIndices; } + unsigned getNumArrayIndices() const { + return IsWritten ? 0 : SourceOrderOrNumArrayIndices; + } /// \brief Retrieve a particular array index variable used to /// describe an array member initialization. VarDecl *getArrayIndex(unsigned I) { - assert(I < NumArrayIndices && "Out of bounds member array index"); + assert(I < getNumArrayIndices() && "Out of bounds member array index"); return reinterpret_cast(this + 1)[I]; } const VarDecl *getArrayIndex(unsigned I) const { - assert(I < NumArrayIndices && "Out of bounds member array index"); + assert(I < getNumArrayIndices() && "Out of bounds member array index"); return reinterpret_cast(this + 1)[I]; } void setArrayIndex(unsigned I, VarDecl *Index) { - assert(I < NumArrayIndices && "Out of bounds member array index"); + assert(I < getNumArrayIndices() && "Out of bounds member array index"); reinterpret_cast(this + 1)[I] = Index; } diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 47ff957fa3..cd7afd98b6 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -700,8 +700,9 @@ CXXBaseOrMemberInitializer:: CXXBaseOrMemberInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual, SourceLocation L, Expr *Init, SourceLocation R) - : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0), - LParenLoc(L), RParenLoc(R), NumArrayIndices(0), IsVirtual(IsVirtual) + : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0), + LParenLoc(L), RParenLoc(R), IsVirtual(IsVirtual), IsWritten(false), + SourceOrderOrNumArrayIndices(0) { } @@ -709,9 +710,9 @@ CXXBaseOrMemberInitializer:: CXXBaseOrMemberInitializer(ASTContext &Context, FieldDecl *Member, SourceLocation MemberLoc, SourceLocation L, Expr *Init, SourceLocation R) - : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init), - AnonUnionMember(0), LParenLoc(L), RParenLoc(R) , NumArrayIndices(0), - IsVirtual(false) + : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init), + AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false), + IsWritten(false), SourceOrderOrNumArrayIndices(0) { } @@ -722,8 +723,8 @@ CXXBaseOrMemberInitializer(ASTContext &Context, VarDecl **Indices, unsigned NumIndices) : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init), - AnonUnionMember(0), LParenLoc(L), RParenLoc(R) , - NumArrayIndices(NumIndices), IsVirtual(false) + AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false), + IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices) { VarDecl **MyIndices = reinterpret_cast (this + 1); memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *)); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 60f3fe9283..29fb6d6eac 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2142,6 +2142,9 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, for (unsigned i = 0; i < NumMemInits; i++) { CXXBaseOrMemberInitializer *Init = MemInits[i]; + // Set the source order index. + Init->setSourceOrder(i); + if (Init->isMemberInitializer()) { FieldDecl *Field = Init->getMember(); if (CheckRedundantInit(*this, Init, Members[Field]) ||