r230712 - [modules] When loading in multiple canonical definitions of a template,

Manuel Klimek klimek at google.com
Mon Mar 2 02:17:48 PST 2015


On Fri, Feb 27, 2015 at 1:30 AM Richard Smith <richard-llvm at metafoo.co.uk>
wrote:

> Author: rsmith
> Date: Thu Feb 26 18:25:58 2015
> New Revision: 230712
>
> URL: http://llvm.org/viewvc/llvm-project?rev=230712&view=rev
> Log:
> [modules] When loading in multiple canonical definitions of a template,
> accumulate the set of specializations rather than overwriting one list
> with another.
>
> Added:
>     cfe/trunk/test/Modules/Inputs/merge-decl-context/d.h
> Modified:
>     cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
>     cfe/trunk/test/Modules/Inputs/merge-decl-context/a.h
>     cfe/trunk/test/Modules/Inputs/merge-decl-context/merge-decl-
> context.modulemap
>     cfe/trunk/test/Modules/merge-decl-context.cpp
>
> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
> Serialization/ASTReaderDecl.cpp?rev=230712&r1=230711&r2=230712&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Feb 26 18:25:58 2015
> @@ -66,7 +66,12 @@ namespace clang {
>      serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {
>        return Reader.ReadDeclID(F, R, I);
>      }
> -
> +
> +    void ReadDeclIDList(SmallVectorImpl<DeclID> &IDs) {
> +      for (unsigned I = 0, Size = Record[Idx++]; I != Size; ++I)
> +        IDs.push_back(ReadDeclID(Record, Idx));
> +    }
> +
>      Decl *ReadDecl(const RecordData &R, unsigned &I) {
>        return Reader.ReadDecl(F, R, I);
>      }
> @@ -398,7 +403,6 @@ void ASTDeclReader::Visit(Decl *D) {
>      // FunctionDecl's body was written last after all other Stmts/Exprs.
>      // We only read it if FD doesn't already have a body (e.g., from
> another
>      // module).
> -    // FIXME: Also consider = default and = delete.
>      // FIXME: Can we diagnose ODR violations somehow?
>      if (Record[Idx++]) {
>        Reader.PendingBodies[FD] = GetCurrentCursorOffset();
> @@ -1393,8 +1397,6 @@ void ASTDeclReader::MergeDefinitionData(
>    }
>
>    // FIXME: Move this out into a .def file?
> -  // FIXME: Issue a diagnostic on a mismatched MATCH_FIELD, rather than
> -  // asserting; this can happen in the case of an ODR violation.
>    bool DetectedOdrViolation = false;
>  #define OR_FIELD(Field) DD.Field |= MergeDD.Field;
>  #define MATCH_FIELD(Field) \
> @@ -1723,36 +1725,37 @@ ASTDeclReader::VisitRedeclarableTemplate
>    return Redecl;
>  }
>
> +static DeclID *newDeclIDList(ASTContext &Context, DeclID *Old,
> +                             SmallVectorImpl<DeclID> &IDs) {
> +  assert(!IDs.empty() && "no IDs to add to list");
> +
> +  size_t OldCount = Old ? *Old : 0;
> +  size_t NewCount = OldCount + IDs.size();
> +  auto *Result = new (Context) DeclID[1 + NewCount];
> +  auto *Pos = Result;
> +  *Pos++ = NewCount;
> +  if (OldCount)
> +    Pos = std::copy(Old + 1, Old + 1 + OldCount, Pos);
> +  std::copy(IDs.begin(), IDs.end(), Pos);
> +  return Result;
> +}
> +
>  void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
>    RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
>
>    if (ThisDeclID == Redecl.getFirstID()) {
>      // This ClassTemplateDecl owns a CommonPtr; read it to keep track of
> all of
>      // the specializations.
> -    SmallVector<serialization::DeclID, 2> SpecIDs;
> -    SpecIDs.push_back(0);
> -
> +    SmallVector<serialization::DeclID, 32> SpecIDs;
>      // Specializations.
> -    unsigned Size = Record[Idx++];
> -    SpecIDs[0] += Size;
> -    for (unsigned I = 0; I != Size; ++I)
> -      SpecIDs.push_back(ReadDeclID(Record, Idx));
> -
> +    ReadDeclIDList(SpecIDs);
>      // Partial specializations.
> -    Size = Record[Idx++];
> -    SpecIDs[0] += Size;
> -    for (unsigned I = 0; I != Size; ++I)
> -      SpecIDs.push_back(ReadDeclID(Record, Idx));
> -
> -    ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr();
> -    if (SpecIDs[0]) {
> -      typedef serialization::DeclID DeclID;
> -
> -      // FIXME: Append specializations!
> -      CommonPtr->LazySpecializations
> -        = new (Reader.getContext()) DeclID [SpecIDs.size()];
> -      memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),
> -             SpecIDs.size() * sizeof(DeclID));
> +    ReadDeclIDList(SpecIDs);
> +
> +    if (!SpecIDs.empty()) {
> +      auto *CommonPtr = D->getCommonPtr();
> +      CommonPtr->LazySpecializations = newDeclIDList(
> +          Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
>      }
>    }
>
> @@ -1774,30 +1777,16 @@ void ASTDeclReader::VisitVarTemplateDecl
>    if (ThisDeclID == Redecl.getFirstID()) {
>      // This VarTemplateDecl owns a CommonPtr; read it to keep track of
> all of
>      // the specializations.
> -    SmallVector<serialization::DeclID, 2> SpecIDs;
> -    SpecIDs.push_back(0);
> -
> +    SmallVector<serialization::DeclID, 32> SpecIDs;
>      // Specializations.
> -    unsigned Size = Record[Idx++];
> -    SpecIDs[0] += Size;
> -    for (unsigned I = 0; I != Size; ++I)
> -      SpecIDs.push_back(ReadDeclID(Record, Idx));
> -
> +    ReadDeclIDList(SpecIDs);
>      // Partial specializations.
> -    Size = Record[Idx++];
> -    SpecIDs[0] += Size;
> -    for (unsigned I = 0; I != Size; ++I)
> -      SpecIDs.push_back(ReadDeclID(Record, Idx));
> -
> -    VarTemplateDecl::Common *CommonPtr = D->getCommonPtr();
> -    if (SpecIDs[0]) {
> -      typedef serialization::DeclID DeclID;
> -
> -      // FIXME: Append specializations!
> -      CommonPtr->LazySpecializations =
> -          new (Reader.getContext()) DeclID[SpecIDs.size()];
> -      memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),
> -             SpecIDs.size() * sizeof(DeclID));
> +    ReadDeclIDList(SpecIDs);
> +
> +    if (!SpecIDs.empty()) {
> +      auto *CommonPtr = D->getCommonPtr();
> +      CommonPtr->LazySpecializations = newDeclIDList(
> +          Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
>      }
>    }
>  }
>

This seems 100% identical to VisitClassTemplateDecl now (unless I'm missing
something).


> @@ -1909,17 +1898,13 @@ void ASTDeclReader::VisitFunctionTemplat
>
>    if (ThisDeclID == Redecl.getFirstID()) {
>      // This FunctionTemplateDecl owns a CommonPtr; read it.
> +    SmallVector<serialization::DeclID, 32> SpecIDs;
> +    ReadDeclIDList(SpecIDs);
>
> -    // Read the function specialization declaration IDs. The
> specializations
> -    // themselves will be loaded if they're needed.
> -    if (unsigned NumSpecs = Record[Idx++]) {
> -      // FIXME: Append specializations!
> -      FunctionTemplateDecl::Common *CommonPtr = D->getCommonPtr();
> -      CommonPtr->LazySpecializations = new (Reader.getContext())
> -          serialization::DeclID[NumSpecs + 1];
> -      CommonPtr->LazySpecializations[0] = NumSpecs;
> -      for (unsigned I = 0; I != NumSpecs; ++I)
> -        CommonPtr->LazySpecializations[I + 1] = ReadDeclID(Record, Idx);
> +    if (!SpecIDs.empty()) {
> +      auto *CommonPtr = D->getCommonPtr();
> +      CommonPtr->LazySpecializations = newDeclIDList(
> +          Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
>      }
>    }
>  }
>
> Modified: cfe/trunk/test/Modules/Inputs/merge-decl-context/a.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> Modules/Inputs/merge-decl-context/a.h?rev=230712&r1=
> 230711&r2=230712&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Modules/Inputs/merge-decl-context/a.h (original)
> +++ cfe/trunk/test/Modules/Inputs/merge-decl-context/a.h Thu Feb 26
> 18:25:58 2015
> @@ -8,6 +8,8 @@ struct A {
>    }
>    A(double) {}
>    A(double, double) {}
> +  A(double, int) {}
> +  A(int, double) {}
>  };
>
>  template <typename T1, typename T2>
>
> Added: cfe/trunk/test/Modules/Inputs/merge-decl-context/d.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> Modules/Inputs/merge-decl-context/d.h?rev=230712&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/Modules/Inputs/merge-decl-context/d.h (added)
> +++ cfe/trunk/test/Modules/Inputs/merge-decl-context/d.h Thu Feb 26
> 18:25:58 2015
> @@ -0,0 +1,7 @@
> +#ifndef D_H
> +#define D_H
> +
> +#include "a.h"
> +#include "b.h"
> +
> +#endif
>
> Modified: cfe/trunk/test/Modules/Inputs/merge-decl-context/merge-decl-
> context.modulemap
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> Modules/Inputs/merge-decl-context/merge-decl-context.
> modulemap?rev=230712&r1=230711&r2=230712&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap
> (original)
> +++ cfe/trunk/test/Modules/Inputs/merge-decl-context/merge-decl-context.modulemap
> Thu Feb 26 18:25:58 2015
> @@ -11,3 +11,8 @@ module "c" {
>    export *
>    header "c.h"
>  }
> +
> +module "d" {
> +  export *
> +  header "d.h"
> +}
>
> Modified: cfe/trunk/test/Modules/merge-decl-context.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> Modules/merge-decl-context.cpp?rev=230712&r1=230711&r2=230712&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Modules/merge-decl-context.cpp (original)
> +++ cfe/trunk/test/Modules/merge-decl-context.cpp Thu Feb 26 18:25:58 2015
> @@ -4,21 +4,25 @@
>  // RUN:     -emit-module %S/Inputs/merge-decl-context/merge-decl-context.modulemap
> -I%S/Inputs \
>  // RUN:     -I %S/Inputs/merge-decl-context
>  // RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=c -o
> %t/c.pcm -fmodule-maps \
> -// RUN:     -fmodule-file=%t/b.pcm \
> +// RUN:     -fmodule-file=%t/b.pcm -fno-implicit-modules \
> +// RUN:     -emit-module %S/Inputs/merge-decl-context/merge-decl-context.modulemap
> -I%S/Inputs \
> +// RUN:     -I %S/Inputs/merge-decl-context
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=d -o
> %t/d.pcm -fmodule-maps \
> +// RUN:     -fmodule-file=%t/b.pcm -fno-implicit-modules \
>  // RUN:     -emit-module %S/Inputs/merge-decl-context/merge-decl-context.modulemap
> -I%S/Inputs \
>  // RUN:     -I %S/Inputs/merge-decl-context
>
>  // Use the two modules in a single compile.
>  // RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/c.pcm
> -fmodule-file=%t/b.pcm \
> +// RUN:     -fmodule-file=%t/d.pcm -fno-implicit-modules \
>  // RUN:     -fmodule-map-file=%S/Inputs/merge-decl-context/merge-decl-context.modulemap
> -I%S/Inputs \
>  // RUN:     -emit-llvm -o %t/test.o %s
>
>  #include "Inputs/merge-decl-context/a.h"
>  #include "Inputs/merge-decl-context/b.h"
>  #include "Inputs/merge-decl-context/c.h"
> +#include "Inputs/merge-decl-context/d.h"
>
>  void t() {
>    ff(42);
>  }
> -
> -
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150302/c3a192b6/attachment.html>


More information about the cfe-commits mailing list