<commit_before>// @(#)root/graf:$Id$
// Author: Rene Brun   108/08/2002

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Riostream.h"
#include "TROOT.h"
#include "TMath.h"
#include "TCrown.h"
#include "TVirtualPad.h"

ClassImp(TCrown)

//______________________________________________________________________________
/* Begin_Html

TCrown : to draw crown

A crown is specified with the position of its centre, its inner/outer radius
a minimum and maximum angle. The attributes of the outline line are given via
TAttLine. The attributes of the fill area are given via TAttFill.

 Example:
End_Html
Begin_Macro(source)
{
   TCanvas *c1 = new TCanvas("c1","c1",400,400);
   TCrown cr1(.5,.5,.3,.4);
   cr1->SetLineStyle(2);
   cr1->SetLineWidth(4);
   cr1.Draw();
   TCrown cr2(.5,.5,.2,.3,45,315);
   cr2.SetFillColor(38);
   cr2.SetFillStyle(3010);
   cr2.Draw();
   TCrown cr3(.5,.5,.2,.3,-45,45);
   cr3.SetFillColor(50);
   cr3.SetFillStyle(3025);
   cr3.Draw();
   TCrown cr4(.5,.5,.0,.2);
   cr4.SetFillColor(4);
   cr4.SetFillStyle(3008);
   cr4.Draw();
   return c1;
}
End_Macro */

//______________________________________________________________________________
TCrown::TCrown(): TEllipse()
{
   /* Begin_Html
   Crown default constructor.
   End_Html */

}

//______________________________________________________________________________
TCrown::TCrown(Double_t x1, Double_t y1,Double_t radin, Double_t radout,Double_t phimin,Double_t phimax)
      :TEllipse(x1,y1,radin,radout,phimin,phimax,0)
{
   /* Begin_Html
   Crown normal constructor.

 x1,y1  : coordinates of centre of crown

 radin  : inner crown radius

 radout : outer crown radius

 phimin : min angle in degrees (default is 0)

 phimax : max angle in degrees (default is 360)

   When a crown sector only is drawn, the lines connecting the center
   of the crown to the edges are drawn by default. One can specify
   the drawing option "only" to not draw these lines.
   End_Html */

}

//______________________________________________________________________________
TCrown::TCrown(const TCrown &crown) : TEllipse(crown)
{
   /* Begin_Html
   Crown copy constructor.
   End_Html */

   ((TCrown&)crown).Copy(*this);
}

//______________________________________________________________________________
TCrown::~TCrown()
{
   /* Begin_Html
   Crown default destructor.
   End_Html */
}

//______________________________________________________________________________
void TCrown::Copy(TObject &crown) const
{
   /* Begin_Html
   Copy this crown to crown.
   End_Html */

   TEllipse::Copy(crown);
}

//______________________________________________________________________________
Int_t TCrown::DistancetoPrimitive(Int_t px, Int_t py)
{
   /* Begin_Html
   Compute distance from point px,py to a crown.

   If crown is filled, return OK if we are inside
   otherwise, crown is found if near the crown edges.
   End_Html */

   const Double_t kPI = TMath::Pi();
   Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px)) - fX1;
   Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py)) - fY1;

   Double_t r1 = fR1;
   Double_t r2 = fR2;
   Double_t r  = TMath::Sqrt(x*x+y*y);

   if (r1>r2) {
      r1 = fR2;
      r2 = fR1;
   }

   Int_t dist = 9999;
   if (r > r2) return dist;
   if (r < r1) return dist;
   if (fPhimax-fPhimin < 360) {
      Double_t phi = 180*TMath::ACos(x/r)/kPI;
      if (phi < fPhimin) return dist;
      if (phi > fPhimax) return dist;
   }

   if (GetFillColor() && GetFillStyle()) {
      return 0;
   } else {
      if (TMath::Abs(r2-r)/r2 < 0.02) return 0;
      if (TMath::Abs(r1-r)/r1 < 0.02) return 0;
   }
   return dist;
}

//______________________________________________________________________________
void TCrown::DrawCrown(Double_t x1, Double_t y1,Double_t radin,Double_t radout,Double_t phimin,Double_t phimax,Option_t *option)
{
   /* Begin_Html
   Draw this crown with new coordinates.
   End_Html */

   TCrown *newcrown = new TCrown(x1, y1, radin, radout, phimin, phimax);
   TAttLine::Copy(*newcrown);
   TAttFill::Copy(*newcrown);
   newcrown->SetBit(kCanDelete);
   newcrown->AppendPad(option);
}

//______________________________________________________________________________
void TCrown::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   /* Begin_Html
   Execute action corresponding to one event

   For the time being TEllipse::ExecuteEvent is used.
   End_Html */

   TEllipse::ExecuteEvent(event,px,py);
}

//______________________________________________________________________________
void TCrown::Paint(Option_t *)
{
   /* Begin_Html
   Paint this crown with its current attributes.
   End_Html */

   const Double_t kPI = TMath::Pi();
   const Int_t np = 40;
   static Double_t x[2*np+3], y[2*np+3];
   TAttLine::Modify();
   TAttFill::Modify();

   Double_t angle,dx,dy;
   Double_t dphi = (fPhimax-fPhimin)*kPI/(180*np);
   Double_t ct   = TMath::Cos(kPI*fTheta/180);
   Double_t st   = TMath::Sin(kPI*fTheta/180);
   Int_t i;
   //compute outer points
   for (i=0;i<=np;i++) {
      angle = fPhimin*kPI/180 + Double_t(i)*dphi;
      dx    = fR2*TMath::Cos(angle);
      dy    = fR2*TMath::Sin(angle);
      x[i]  = fX1 + dx*ct - dy*st;
      y[i]  = fY1 + dx*st + dy*ct;
   }
   //compute inner points
   for (i=0;i<=np;i++) {
      angle = fPhimin*kPI/180 + Double_t(i)*dphi;
      dx    = fR1*TMath::Cos(angle);
      dy    = fR1*TMath::Sin(angle);
      x[2*np-i+1]  = fX1 + dx*ct - dy*st;
      y[2*np-i+1]  = fY1 + dx*st + dy*ct;
   }
   x[2*np+2]  = x[0];
   y[2*np+2]  = y[0];
   if (fPhimax-fPhimin >= 360 ) {
      // a complete filled crown
      if (GetFillColor()  && GetFillStyle()) {
         gPad->PaintFillArea(2*np+2,x,y);
      }
      // a complete empty crown
      if (GetLineStyle()) {
         gPad->PaintPolyLine(np+1,x,y);
         gPad->PaintPolyLine(np+1,&x[np+1],&y[np+1]);
      }
   } else {
      //crown segment
      if (GetFillColor()  && GetFillStyle()) gPad->PaintFillArea(2*np+2,x,y);
      if (GetLineStyle()) gPad->PaintPolyLine(2*np+3,x,y);
   }
}

//______________________________________________________________________________
void TCrown::SavePrimitive(ostream &out, Option_t * /*= ""*/)
{
   /* Begin_Html
   Save primitive as a C++ statement(s) on output stream out.
   End_Html */

   out<<"   "<<endl;
   if (gROOT->ClassSaved(TCrown::Class())) {
      out<<"   ";
   } else {
      out<<"   TCrown *";
   }
   out<<"crown = new TCrown("<<fX1<<","<<fY1<<","<<fR1<<","<<fR2
      <<","<<fPhimin<<","<<fPhimax<<");"<<endl;

   SaveFillAttributes(out,"crown",0,1001);
   SaveLineAttributes(out,"crown",1,1,1);

   if (GetNoEdges()) out<<"   crown->SetNoEdges();"<<endl;

   out<<"   crown->Draw();"<<endl;
}
<commit_msg>- DistancetoPrimitive needs more improvements   (angles related).<commit_after>// @(#)root/graf:$Id$
// Author: Rene Brun   108/08/2002

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Riostream.h"
#include "TROOT.h"
#include "TMath.h"
#include "TCrown.h"
#include "TVirtualPad.h"

ClassImp(TCrown)

//______________________________________________________________________________
/* Begin_Html

TCrown : to draw crown

A crown is specified with the position of its centre, its inner/outer radius
a minimum and maximum angle. The attributes of the outline line are given via
TAttLine. The attributes of the fill area are given via TAttFill.

 Example:
End_Html
Begin_Macro(source)
{
   TCanvas *c1 = new TCanvas("c1","c1",400,400);
   TCrown cr1(.5,.5,.3,.4);
   cr1->SetLineStyle(2);
   cr1->SetLineWidth(4);
   cr1.Draw();
   TCrown cr2(.5,.5,.2,.3,45,315);
   cr2.SetFillColor(38);
   cr2.SetFillStyle(3010);
   cr2.Draw();
   TCrown cr3(.5,.5,.2,.3,-45,45);
   cr3.SetFillColor(50);
   cr3.SetFillStyle(3025);
   cr3.Draw();
   TCrown cr4(.5,.5,.0,.2);
   cr4.SetFillColor(4);
   cr4.SetFillStyle(3008);
   cr4.Draw();
   return c1;
}
End_Macro */

//______________________________________________________________________________
TCrown::TCrown(): TEllipse()
{
   /* Begin_Html
   Crown default constructor.
   End_Html */

}

//______________________________________________________________________________
TCrown::TCrown(Double_t x1, Double_t y1,Double_t radin, Double_t radout,Double_t phimin,Double_t phimax)
      :TEllipse(x1,y1,radin,radout,phimin,phimax,0)
{
   /* Begin_Html
   Crown normal constructor.

 x1,y1  : coordinates of centre of crown

 radin  : inner crown radius

 radout : outer crown radius

 phimin : min angle in degrees (default is 0)

 phimax : max angle in degrees (default is 360)

   When a crown sector only is drawn, the lines connecting the center
   of the crown to the edges are drawn by default. One can specify
   the drawing option "only" to not draw these lines.
   End_Html */

}

//______________________________________________________________________________
TCrown::TCrown(const TCrown &crown) : TEllipse(crown)
{
   /* Begin_Html
   Crown copy constructor.
   End_Html */

   ((TCrown&)crown).Copy(*this);
}

//______________________________________________________________________________
TCrown::~TCrown()
{
   /* Begin_Html
   Crown default destructor.
   End_Html */
}

//______________________________________________________________________________
void TCrown::Copy(TObject &crown) const
{
   /* Begin_Html
   Copy this crown to crown.
   End_Html */

   TEllipse::Copy(crown);
}

//______________________________________________________________________________
Int_t TCrown::DistancetoPrimitive(Int_t px, Int_t py)
{
   /* Begin_Html
   Compute distance from point px,py to a crown.

   If crown is filled, return OK if we are inside
   otherwise, crown is found if near the crown edges.
   End_Html */

   const Double_t kPI = TMath::Pi();
   Double_t x = gPad->PadtoX(gPad->AbsPixeltoX(px)) - fX1;
   Double_t y = gPad->PadtoY(gPad->AbsPixeltoY(py)) - fY1;

   Double_t r1 = fR1;
   Double_t r2 = fR2;
   Double_t r  = TMath::Sqrt(x*x+y*y);

   if (r1>r2) {
      r1 = fR2;
      r2 = fR1;
   }

   Int_t dist = 9999;
   if (r > r2) return dist;
   if (r < r1) return dist;
   if (fPhimax-fPhimin < 360) {
      Double_t phi = 180*TMath::ACos(x/r)/kPI;
      if (y<0) phi = 360-phi;
      Double_t phi1 = fPhimin;
      Double_t phi2 = fPhimax;
      if (phi1<0) phi1=phi1+360;
      if (phi2<0) phi2=phi2+360;
      if (phi2<phi1) {
         if (phi < phi1 && phi > phi2) return dist;
      } else {
         if (phi < phi1) return dist;
         if (phi > phi2) return dist;
      }
   }

   if (GetFillColor() && GetFillStyle()) {
      return 0;
   } else {
      if (TMath::Abs(r2-r)/r2 < 0.02) return 0;
      if (TMath::Abs(r1-r)/r1 < 0.02) return 0;
   }
   return dist;
}

//______________________________________________________________________________
void TCrown::DrawCrown(Double_t x1, Double_t y1,Double_t radin,Double_t radout,Double_t phimin,Double_t phimax,Option_t *option)
{
   /* Begin_Html
   Draw this crown with new coordinates.
   End_Html */

   TCrown *newcrown = new TCrown(x1, y1, radin, radout, phimin, phimax);
   TAttLine::Copy(*newcrown);
   TAttFill::Copy(*newcrown);
   newcrown->SetBit(kCanDelete);
   newcrown->AppendPad(option);
}

//______________________________________________________________________________
void TCrown::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   /* Begin_Html
   Execute action corresponding to one event

   For the time being TEllipse::ExecuteEvent is used.
   End_Html */

   TEllipse::ExecuteEvent(event,px,py);
}

//______________________________________________________________________________
void TCrown::Paint(Option_t *)
{
   /* Begin_Html
   Paint this crown with its current attributes.
   End_Html */

   const Double_t kPI = TMath::Pi();
   const Int_t np = 40;
   static Double_t x[2*np+3], y[2*np+3];
   TAttLine::Modify();
   TAttFill::Modify();

   Double_t angle,dx,dy;
   Double_t dphi = (fPhimax-fPhimin)*kPI/(180*np);
   Double_t ct   = TMath::Cos(kPI*fTheta/180);
   Double_t st   = TMath::Sin(kPI*fTheta/180);
   Int_t i;
   //compute outer points
   for (i=0;i<=np;i++) {
      angle = fPhimin*kPI/180 + Double_t(i)*dphi;
      dx    = fR2*TMath::Cos(angle);
      dy    = fR2*TMath::Sin(angle);
      x[i]  = fX1 + dx*ct - dy*st;
      y[i]  = fY1 + dx*st + dy*ct;
   }
   //compute inner points
   for (i=0;i<=np;i++) {
      angle = fPhimin*kPI/180 + Double_t(i)*dphi;
      dx    = fR1*TMath::Cos(angle);
      dy    = fR1*TMath::Sin(angle);
      x[2*np-i+1]  = fX1 + dx*ct - dy*st;
      y[2*np-i+1]  = fY1 + dx*st + dy*ct;
   }
   x[2*np+2]  = x[0];
   y[2*np+2]  = y[0];
   if (fPhimax-fPhimin >= 360 ) {
      // a complete filled crown
      if (GetFillColor()  && GetFillStyle()) {
         gPad->PaintFillArea(2*np+2,x,y);
      }
      // a complete empty crown
      if (GetLineStyle()) {
         gPad->PaintPolyLine(np+1,x,y);
         gPad->PaintPolyLine(np+1,&x[np+1],&y[np+1]);
      }
   } else {
      //crown segment
      if (GetFillColor()  && GetFillStyle()) gPad->PaintFillArea(2*np+2,x,y);
      if (GetLineStyle()) gPad->PaintPolyLine(2*np+3,x,y);
   }
}

//______________________________________________________________________________
void TCrown::SavePrimitive(ostream &out, Option_t * /*= ""*/)
{
   /* Begin_Html
   Save primitive as a C++ statement(s) on output stream out.
   End_Html */

   out<<"   "<<endl;
   if (gROOT->ClassSaved(TCrown::Class())) {
      out<<"   ";
   } else {
      out<<"   TCrown *";
   }
   out<<"crown = new TCrown("<<fX1<<","<<fY1<<","<<fR1<<","<<fR2
      <<","<<fPhimin<<","<<fPhimax<<");"<<endl;

   SaveFillAttributes(out,"crown",0,1001);
   SaveLineAttributes(out,"crown",1,1,1);

   if (GetNoEdges()) out<<"   crown->SetNoEdges();"<<endl;

   out<<"   crown->Draw();"<<endl;
}
<|endoftext|>


<commit_before><commit_msg>store_test: fix warning<commit_after><|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkCellPicker.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2000 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "vtkCellPicker.h"
#include "vtkObjectFactory.h"
#include "vtkVolumeMapper.h"

//----------------------------------------------------------------------------
vtkCellPicker* vtkCellPicker::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkCellPicker");
  if(ret)
    {
    return (vtkCellPicker*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkCellPicker;
}

vtkCellPicker::vtkCellPicker()
{
  this->CellId = -1;
  this->SubId = -1;
  for (int i=0; i<3; i++)
    {
    this->PCoords[i] = 0.0;
    }
  this->Cell = vtkGenericCell::New();
}

vtkCellPicker::~vtkCellPicker()
{
  this->Cell->Delete();
}

float vtkCellPicker::IntersectWithLine(float p1[3], float p2[3], float tol,
                                       vtkAssemblyPath *path,
                                       vtkProp3D *prop3D,
                                       vtkAbstractMapper3D *m)
{
  int numCells;
  int cellId, i, minCellId, minSubId, subId;
  float x[3], tMin, t, pcoords[3], minXYZ[3], minPcoords[3];
  vtkDataSet *input;
  vtkMapper *mapper;
  vtkVolumeMapper *volumeMapper;

  // Get the underlying dataset
  if ( (mapper=vtkMapper::SafeDownCast(m)) != NULL )
    {
    input = mapper->GetInput();
    }
  else if ( (volumeMapper=vtkVolumeMapper::SafeDownCast(m)) != NULL )
    {
    input = volumeMapper->GetInput();
    }
  else
    {
    return VTK_LARGE_FLOAT;
    }

  if ( (numCells = input->GetNumberOfCells()) < 1 )
    {
    return 2.0;
    }

  //  Intersect each cell with ray.  Keep track of one closest to
  //  the eye (and within the clipping range).
  //
  minCellId = -1;
  minSubId = -1;
  for (tMin=VTK_LARGE_FLOAT,cellId=0; cellId<numCells; cellId++)
    {
    input->GetCell(cellId,this->Cell);

    if ( this->Cell->IntersectWithLine(p1, p2, tol, t, x, pcoords, subId)
    && t < tMin )
      {
      minCellId = cellId;
      minSubId = subId;
      for (i=0; i<3; i++)
        {
        minXYZ[i] = x[i];
        minPcoords[i] = pcoords[i];
        }
      tMin = t;
      }
    }

  //  Now compare this against other actors.
  //
  if ( minCellId>(-1) && tMin < this->GlobalTMin )
    {
    this->MarkPicked(path, prop3D, m, tMin, minXYZ);
    this->CellId = minCellId;
    this->SubId = minSubId;
    for (i=0; i<3; i++)
      {
      this->PCoords[i] = minPcoords[i];
      }
    vtkDebugMacro("Picked cell id= " << minCellId);
    }
  return tMin;
}

void vtkCellPicker::Initialize()
{
  this->CellId = (-1);
  this->SubId = (-1);
  for (int i=0; i<3; i++)
    {
    this->PCoords[i] = 0.0;
    }
  this->vtkPicker::Initialize();
}

void vtkCellPicker::PrintSelf(ostream& os, vtkIndent indent)
{
  this->vtkPicker::PrintSelf(os,indent);

  os << indent << "Cell Id: " << this->CellId << "\n";
  os << indent << "SubId: " << this->SubId << "\n";
  os << indent << "PCoords: (" << this->PCoords[0] << ", "
     << this->PCoords[1] << ", " << this->PCoords[2] << ")\n";
}
<commit_msg>ENH:Removing Purify UMC's<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkCellPicker.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2000 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "vtkCellPicker.h"
#include "vtkObjectFactory.h"
#include "vtkVolumeMapper.h"

//----------------------------------------------------------------------------
vtkCellPicker* vtkCellPicker::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkCellPicker");
  if(ret)
    {
    return (vtkCellPicker*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkCellPicker;
}

vtkCellPicker::vtkCellPicker()
{
  this->CellId = -1;
  this->SubId = -1;
  for (int i=0; i<3; i++)
    {
    this->PCoords[i] = 0.0;
    }
  this->Cell = vtkGenericCell::New();
}

vtkCellPicker::~vtkCellPicker()
{
  this->Cell->Delete();
}

float vtkCellPicker::IntersectWithLine(float p1[3], float p2[3], float tol,
                                       vtkAssemblyPath *path,
                                       vtkProp3D *prop3D,
                                       vtkAbstractMapper3D *m)
{
  int numCells;
  int cellId, i, minCellId, minSubId, subId;
  float x[3], tMin, t, pcoords[3], minXYZ[3], minPcoords[3];
  vtkDataSet *input;
  vtkMapper *mapper;
  vtkVolumeMapper *volumeMapper;

  // Get the underlying dataset
  if ( (mapper=vtkMapper::SafeDownCast(m)) != NULL )
    {
    input = mapper->GetInput();
    }
  else if ( (volumeMapper=vtkVolumeMapper::SafeDownCast(m)) != NULL )
    {
    input = volumeMapper->GetInput();
    }
  else
    {
    return VTK_LARGE_FLOAT;
    }

  if ( (numCells = input->GetNumberOfCells()) < 1 )
    {
    return 2.0;
    }

  //  Intersect each cell with ray.  Keep track of one closest to
  //  the eye (and within the clipping range).
  //
  minCellId = -1;
  minSubId = -1;
  minPcoords[0] = minPcoords[1] = minPcoords[2] = 0.0;
  for (tMin=VTK_LARGE_FLOAT,cellId=0; cellId<numCells; cellId++)
    {
    input->GetCell(cellId,this->Cell);

    if ( this->Cell->IntersectWithLine(p1, p2, tol, t, x, pcoords, subId)
    && t < tMin )
      {
      minCellId = cellId;
      minSubId = subId;
      for (i=0; i<3; i++)
        {
        minXYZ[i] = x[i];
        minPcoords[i] = pcoords[i];
        }
      tMin = t;
      }
    }

  //  Now compare this against other actors.
  //
  if ( minCellId>(-1) && tMin < this->GlobalTMin )
    {
    this->MarkPicked(path, prop3D, m, tMin, minXYZ);
    this->CellId = minCellId;
    this->SubId = minSubId;
    for (i=0; i<3; i++)
      {
      this->PCoords[i] = minPcoords[i];
      }
    vtkDebugMacro("Picked cell id= " << minCellId);
    }
  return tMin;
}

void vtkCellPicker::Initialize()
{
  this->CellId = (-1);
  this->SubId = (-1);
  for (int i=0; i<3; i++)
    {
    this->PCoords[i] = 0.0;
    }
  this->vtkPicker::Initialize();
}

void vtkCellPicker::PrintSelf(ostream& os, vtkIndent indent)
{
  this->vtkPicker::PrintSelf(os,indent);

  os << indent << "Cell Id: " << this->CellId << "\n";
  os << indent << "SubId: " << this->SubId << "\n";
  os << indent << "PCoords: (" << this->PCoords[0] << ", "
     << this->PCoords[1] << ", " << this->PCoords[2] << ")\n";
}
<|endoftext|>


<commit_before>/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_DATA_HPP
#define NDN_DATA_HPP

#include "common.hpp"
#include "name.hpp"
#include "util/signed-blob.hpp"
#include "c/data-types.h"
#include "encoding/wire-format.hpp"

struct ndn_MetaInfo;
struct ndn_Signature;
struct ndn_Data;

namespace ndn {

/**
 * A Signature is an abstract base class providing methods to work with the signature information in a Data packet.
 * You must create an object of a subclass, for example Sha256WithRsaSignature.
 */
class Signature {
public:
  /**
   * Return a pointer to a new Signature which is a copy of this signature.
   * This is pure virtual, the subclass must implement it.
   */
  virtual ptr_lib::shared_ptr<Signature>
  clone() const = 0;

  /**
   * The virtual destructor.
   */
  virtual
  ~Signature();

    /**
   * Set the signatureStruct to point to the values in this signature object, without copying any memory.
   * WARNING: The resulting pointers in signatureStruct are invalid after a further use of this object which could reallocate memory.
   * This is pure virtual, the subclass must implement it.
   * @param signatureStruct a C ndn_Signature struct where the name components array is already allocated.
   */
  virtual void
  get(struct ndn_Signature& signatureStruct) const = 0;

  /**
   * Clear this signature, and set the values by copying from the ndn_Signature struct.
   * This is pure virtual, the subclass must implement it.
   * @param signatureStruct a C ndn_Signature struct
   */
  virtual void
  set(const struct ndn_Signature& signatureStruct) = 0;
};

/**
 * An MetaInfo holds the meta info which is signed inside the data packet.
 */
class MetaInfo {
public:
  MetaInfo()
  {
    type_ = ndn_ContentType_DATA;
    freshnessSeconds_ = -1;
  }

  /**
   * Set the metaInfoStruct to point to the values in this meta info object, without copying any memory.
   * WARNING: The resulting pointers in metaInfoStruct are invalid after a further use of this object which could reallocate memory.
   * @param metaInfoStruct a C ndn_MetaInfo struct where the name components array is already allocated.
   */
  void
  get(struct ndn_MetaInfo& metaInfoStruct) const;

  /**
   * Clear this meta info, and set the values by copying from the ndn_MetaInfo struct.
   * @param metaInfoStruct a C ndn_MetaInfo struct
   */
  void
  set(const struct ndn_MetaInfo& metaInfoStruct);

  MillisecondsSince1970
  getTimestampMilliseconds() const { return timestampMilliseconds_; }

  ndn_ContentType
  getType() const { return type_; }

  int
  getFreshnessSeconds() const { return freshnessSeconds_; }

  const Name::Component&
  getFinalBlockID() const { return finalBlockID_; }

  void
  setTimestampMilliseconds(MillisecondsSince1970 timestampMilliseconds) { timestampMilliseconds_ = timestampMilliseconds; }

  void
  setType(ndn_ContentType type) { type_ = type; }

  void
  setFreshnessSeconds(int freshnessSeconds) { freshnessSeconds_ = freshnessSeconds; }

  void
  setFinalBlockID(const Blob& finalBlockID) { finalBlockID_ = Name::Component(finalBlockID); }

  void
  setFinalBlockID(const std::vector<uint8_t>& finalBlockID) { finalBlockID_ = Name::Component(finalBlockID); }

  void
  setFinalBlockID(const uint8_t* finalBlockID, size_t finalBlockIdLength)
  {
    finalBlockID_ = Name::Component(finalBlockID, finalBlockIdLength);
  }

private:
  MillisecondsSince1970 timestampMilliseconds_; /**< milliseconds since 1/1/1970. -1 for none */
  ndn_ContentType type_;         /**< default is ndn_ContentType_DATA. -1 for none */
  int freshnessSeconds_;         /**< -1 for none */
  Name::Component finalBlockID_; /** size 0 for none */
};

class Data {
public:
  /**
   * Create a new Data object with default values and where the signature is a blank Sha256WithRsaSignature.
   */
  Data();

  /**
   * Create a new Data object with the given name and default values and where the signature is a blank Sha256WithRsaSignature.
   * @param name A reference to the name which is copied.
   */
  Data(const Name& name);

  /**
   * The copy constructor: Create a deep copy of the given data object, including a clone of the signature object.
   * @param data The data object to copy.
   */
  Data(const Data& data);

  /**
   * The virtual destructor.
   */
  virtual ~Data();

  /**
   * The assignment operator: Copy fields and make a clone of the signature.
   * @param data The other object to copy from.
   * @return A reference to this object.
   */
  Data& operator=(const Data& data);

  /**
   * Encode this Data for a particular wire format. If wireFormat is the default wire format, also set the defaultWireEncoding
   * field to the encoded result.
   * Even though this is const, if wireFormat is the default wire format we update the defaultWireEncoding.
   * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
   * @return The encoded byte array.
   */
  SignedBlob
  wireEncode(WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) const;

  /**
   * Decode the input using a particular wire format and update this Data. If wireFormat is the default wire format, also
   * set the defaultWireEncoding field to the input.
   * @param input The input byte array to be decoded.
   * @param inputLength The length of input.
   * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat getDefaultWireFormat().
   */
  void
  wireDecode(const uint8_t* input, size_t inputLength, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat());

  /**
   * Decode the input using a particular wire format and update this Data. If wireFormat is the default wire format, also
   * set the defaultWireEncoding field to the input.
   * @param input The input byte array to be decoded.
   * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat getDefaultWireFormat().
   */
  void
  wireDecode(const std::vector<uint8_t>& input, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
  {
    wireDecode(&input[0], input.size(), wireFormat);
  }

  /**
   * Set the dataStruct to point to the values in this interest, without copying any memory.
   * WARNING: The resulting pointers in dataStruct are invalid after a further use of this object which could reallocate memory.
   * @param dataStruct a C ndn_Data struct where the name components array is already allocated.
   */
  void
  get(struct ndn_Data& dataStruct) const;

  /**
   * Clear this data object, and set the values by copying from the ndn_Data struct.
   * @param dataStruct a C ndn_Data struct
   */
  void
  set(const struct ndn_Data& dataStruct);

  const Signature*
  getSignature() const { return signature_.get(); }

  Signature*
  getSignature()
  {
    // TODO: Should add an OnChanged listener instead of always calling onChanged.
    onChanged();
    return signature_.get();
  }

  const Name&
  getName() const { return name_; }

  Name&
  getName()
  {
    // TODO: Should add an OnChanged listener instead of always calling onChanged.
    onChanged();
    return name_;
  }

  const MetaInfo&
  getMetaInfo() const { return metaInfo_; }

  MetaInfo&
  getMetaInfo()
  {
    // TODO: Should add an OnChanged listener instead of always calling onChanged.
    onChanged();
    return metaInfo_;
  }

  const Blob&
  getContent() const { return content_; }

  /**
   * Return a pointer to the defaultWireEncoding.  It may be null.
   */
  const SignedBlob&
  getDefaultWireEncoding() const { return defaultWireEncoding_; }

  /**
   * Set the signature to a copy of the given signature.
   * @param signature The signature object which is cloned.
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setSignature(const Signature& signature)
  {
    signature_ = signature.clone();
    onChanged();
    return *this;
  }

  /**
   * Set name to a copy of the given Name.  This is virtual so that a subclass can override to validate the name.
   * @param name The Name which is copied.
   * @return This Data so that you can chain calls to update values.
   */
  virtual Data&
  setName(const Name& name);

  /**
   * Set metaInfo to a copy of the given MetaInfo.
   * @param metaInfo The MetaInfo which is copied.
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setMetainfo(const MetaInfo& metaInfo)
  {
    metaInfo_ = metaInfo;
    onChanged();
    return *this;
  }

  /**
   * Set the content to a copy of the data in the vector.
   * @param content A vector whose contents are copied.
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setContent(const std::vector<uint8_t>& content)
  {
    content_ = content;
    onChanged();
    return *this;
  }

  Data&
  setContent(const uint8_t* content, size_t contentLength)
  {
    content_ = Blob(content, contentLength);
    onChanged();
    return *this;
  }

  Data&
  setContent(const Blob& content)
  {
    content_ = content;
    onChanged();
    return *this;
  }

private:
  /**
   * Clear the wire encoding.
   */
  void
  onChanged();

  ptr_lib::shared_ptr<Signature> signature_;
  Name name_;
  MetaInfo metaInfo_;
  Blob content_;
  SignedBlob defaultWireEncoding_;
};

}

#endif
<commit_msg>MetaInfo: Added setFinalBlockID for Name::Component.<commit_after>/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_DATA_HPP
#define NDN_DATA_HPP

#include "common.hpp"
#include "name.hpp"
#include "util/signed-blob.hpp"
#include "c/data-types.h"
#include "encoding/wire-format.hpp"

struct ndn_MetaInfo;
struct ndn_Signature;
struct ndn_Data;

namespace ndn {

/**
 * A Signature is an abstract base class providing methods to work with the signature information in a Data packet.
 * You must create an object of a subclass, for example Sha256WithRsaSignature.
 */
class Signature {
public:
  /**
   * Return a pointer to a new Signature which is a copy of this signature.
   * This is pure virtual, the subclass must implement it.
   */
  virtual ptr_lib::shared_ptr<Signature>
  clone() const = 0;

  /**
   * The virtual destructor.
   */
  virtual
  ~Signature();

    /**
   * Set the signatureStruct to point to the values in this signature object, without copying any memory.
   * WARNING: The resulting pointers in signatureStruct are invalid after a further use of this object which could reallocate memory.
   * This is pure virtual, the subclass must implement it.
   * @param signatureStruct a C ndn_Signature struct where the name components array is already allocated.
   */
  virtual void
  get(struct ndn_Signature& signatureStruct) const = 0;

  /**
   * Clear this signature, and set the values by copying from the ndn_Signature struct.
   * This is pure virtual, the subclass must implement it.
   * @param signatureStruct a C ndn_Signature struct
   */
  virtual void
  set(const struct ndn_Signature& signatureStruct) = 0;
};

/**
 * An MetaInfo holds the meta info which is signed inside the data packet.
 */
class MetaInfo {
public:
  MetaInfo()
  {
    type_ = ndn_ContentType_DATA;
    freshnessSeconds_ = -1;
  }

  /**
   * Set the metaInfoStruct to point to the values in this meta info object, without copying any memory.
   * WARNING: The resulting pointers in metaInfoStruct are invalid after a further use of this object which could reallocate memory.
   * @param metaInfoStruct a C ndn_MetaInfo struct where the name components array is already allocated.
   */
  void
  get(struct ndn_MetaInfo& metaInfoStruct) const;

  /**
   * Clear this meta info, and set the values by copying from the ndn_MetaInfo struct.
   * @param metaInfoStruct a C ndn_MetaInfo struct
   */
  void
  set(const struct ndn_MetaInfo& metaInfoStruct);

  MillisecondsSince1970
  getTimestampMilliseconds() const { return timestampMilliseconds_; }

  ndn_ContentType
  getType() const { return type_; }

  int
  getFreshnessSeconds() const { return freshnessSeconds_; }

  const Name::Component&
  getFinalBlockID() const { return finalBlockID_; }

  void
  setTimestampMilliseconds(MillisecondsSince1970 timestampMilliseconds) { timestampMilliseconds_ = timestampMilliseconds; }

  void
  setType(ndn_ContentType type) { type_ = type; }

  void
  setFreshnessSeconds(int freshnessSeconds) { freshnessSeconds_ = freshnessSeconds; }

  void
  setFinalBlockID(const Name::Component& finalBlockID) { finalBlockID_ = finalBlockID; }

  void
  setFinalBlockID(const Blob& finalBlockID) { finalBlockID_ = Name::Component(finalBlockID); }

  void
  setFinalBlockID(const std::vector<uint8_t>& finalBlockID) { finalBlockID_ = Name::Component(finalBlockID); }

  void
  setFinalBlockID(const uint8_t* finalBlockID, size_t finalBlockIdLength)
  {
    finalBlockID_ = Name::Component(finalBlockID, finalBlockIdLength);
  }

private:
  MillisecondsSince1970 timestampMilliseconds_; /**< milliseconds since 1/1/1970. -1 for none */
  ndn_ContentType type_;         /**< default is ndn_ContentType_DATA. -1 for none */
  int freshnessSeconds_;         /**< -1 for none */
  Name::Component finalBlockID_; /** size 0 for none */
};

class Data {
public:
  /**
   * Create a new Data object with default values and where the signature is a blank Sha256WithRsaSignature.
   */
  Data();

  /**
   * Create a new Data object with the given name and default values and where the signature is a blank Sha256WithRsaSignature.
   * @param name A reference to the name which is copied.
   */
  Data(const Name& name);

  /**
   * The copy constructor: Create a deep copy of the given data object, including a clone of the signature object.
   * @param data The data object to copy.
   */
  Data(const Data& data);

  /**
   * The virtual destructor.
   */
  virtual ~Data();

  /**
   * The assignment operator: Copy fields and make a clone of the signature.
   * @param data The other object to copy from.
   * @return A reference to this object.
   */
  Data& operator=(const Data& data);

  /**
   * Encode this Data for a particular wire format. If wireFormat is the default wire format, also set the defaultWireEncoding
   * field to the encoded result.
   * Even though this is const, if wireFormat is the default wire format we update the defaultWireEncoding.
   * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
   * @return The encoded byte array.
   */
  SignedBlob
  wireEncode(WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) const;

  /**
   * Decode the input using a particular wire format and update this Data. If wireFormat is the default wire format, also
   * set the defaultWireEncoding field to the input.
   * @param input The input byte array to be decoded.
   * @param inputLength The length of input.
   * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat getDefaultWireFormat().
   */
  void
  wireDecode(const uint8_t* input, size_t inputLength, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat());

  /**
   * Decode the input using a particular wire format and update this Data. If wireFormat is the default wire format, also
   * set the defaultWireEncoding field to the input.
   * @param input The input byte array to be decoded.
   * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat getDefaultWireFormat().
   */
  void
  wireDecode(const std::vector<uint8_t>& input, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
  {
    wireDecode(&input[0], input.size(), wireFormat);
  }

  /**
   * Set the dataStruct to point to the values in this interest, without copying any memory.
   * WARNING: The resulting pointers in dataStruct are invalid after a further use of this object which could reallocate memory.
   * @param dataStruct a C ndn_Data struct where the name components array is already allocated.
   */
  void
  get(struct ndn_Data& dataStruct) const;

  /**
   * Clear this data object, and set the values by copying from the ndn_Data struct.
   * @param dataStruct a C ndn_Data struct
   */
  void
  set(const struct ndn_Data& dataStruct);

  const Signature*
  getSignature() const { return signature_.get(); }

  Signature*
  getSignature()
  {
    // TODO: Should add an OnChanged listener instead of always calling onChanged.
    onChanged();
    return signature_.get();
  }

  const Name&
  getName() const { return name_; }

  Name&
  getName()
  {
    // TODO: Should add an OnChanged listener instead of always calling onChanged.
    onChanged();
    return name_;
  }

  const MetaInfo&
  getMetaInfo() const { return metaInfo_; }

  MetaInfo&
  getMetaInfo()
  {
    // TODO: Should add an OnChanged listener instead of always calling onChanged.
    onChanged();
    return metaInfo_;
  }

  const Blob&
  getContent() const { return content_; }

  /**
   * Return a pointer to the defaultWireEncoding.  It may be null.
   */
  const SignedBlob&
  getDefaultWireEncoding() const { return defaultWireEncoding_; }

  /**
   * Set the signature to a copy of the given signature.
   * @param signature The signature object which is cloned.
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setSignature(const Signature& signature)
  {
    signature_ = signature.clone();
    onChanged();
    return *this;
  }

  /**
   * Set name to a copy of the given Name.  This is virtual so that a subclass can override to validate the name.
   * @param name The Name which is copied.
   * @return This Data so that you can chain calls to update values.
   */
  virtual Data&
  setName(const Name& name);

  /**
   * Set metaInfo to a copy of the given MetaInfo.
   * @param metaInfo The MetaInfo which is copied.
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setMetainfo(const MetaInfo& metaInfo)
  {
    metaInfo_ = metaInfo;
    onChanged();
    return *this;
  }

  /**
   * Set the content to a copy of the data in the vector.
   * @param content A vector whose contents are copied.
   * @return This Data so that you can chain calls to update values.
   */
  Data&
  setContent(const std::vector<uint8_t>& content)
  {
    content_ = content;
    onChanged();
    return *this;
  }

  Data&
  setContent(const uint8_t* content, size_t contentLength)
  {
    content_ = Blob(content, contentLength);
    onChanged();
    return *this;
  }

  Data&
  setContent(const Blob& content)
  {
    content_ = content;
    onChanged();
    return *this;
  }

private:
  /**
   * Clear the wire encoding.
   */
  void
  onChanged();

  ptr_lib::shared_ptr<Signature> signature_;
  Name name_;
  MetaInfo metaInfo_;
  Blob content_;
  SignedBlob defaultWireEncoding_;
};

}

#endif
<|endoftext|>


<commit_before>//===-- GCRootLowering.cpp - Garbage collection infrastructure ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the lowering for the gc.root mechanism.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace {

/// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or
/// llvm.gcwrite intrinsics, replacing them with simple loads and stores as
/// directed by the GCStrategy. It also performs automatic root initialization
/// and custom intrinsic lowering.
class LowerIntrinsics : public FunctionPass {
  bool DoLowering(Function &F, GCStrategy &S);

public:
  static char ID;

  LowerIntrinsics();
  StringRef getPassName() const override;
  void getAnalysisUsage(AnalysisUsage &AU) const override;

  bool doInitialization(Module &M) override;
  bool runOnFunction(Function &F) override;
};

/// GCMachineCodeAnalysis - This is a target-independent pass over the machine
/// function representation to identify safe points for the garbage collector
/// in the machine code. It inserts labels at safe points and populates a
/// GCMetadata record for each function.
class GCMachineCodeAnalysis : public MachineFunctionPass {
  GCFunctionInfo *FI;
  MachineModuleInfo *MMI;
  const TargetInstrInfo *TII;

  void FindSafePoints(MachineFunction &MF);
  void VisitCallPoint(MachineBasicBlock::iterator CI);
  MCSymbol *InsertLabel(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                        const DebugLoc &DL) const;

  void FindStackOffsets(MachineFunction &MF);

public:
  static char ID;

  GCMachineCodeAnalysis();
  void getAnalysisUsage(AnalysisUsage &AU) const override;

  bool runOnMachineFunction(MachineFunction &MF) override;
};
}

// -----------------------------------------------------------------------------

INITIALIZE_PASS_BEGIN(LowerIntrinsics, "gc-lowering", "GC Lowering", false,
                      false)
INITIALIZE_PASS_DEPENDENCY(GCModuleInfo)
INITIALIZE_PASS_END(LowerIntrinsics, "gc-lowering", "GC Lowering", false, false)

FunctionPass *llvm::createGCLoweringPass() { return new LowerIntrinsics(); }

char LowerIntrinsics::ID = 0;

LowerIntrinsics::LowerIntrinsics() : FunctionPass(ID) {
  initializeLowerIntrinsicsPass(*PassRegistry::getPassRegistry());
}

StringRef LowerIntrinsics::getPassName() const {
  return "Lower Garbage Collection Instructions";
}

void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
  FunctionPass::getAnalysisUsage(AU);
  AU.addRequired<GCModuleInfo>();
  AU.addPreserved<DominatorTreeWrapperPass>();
}

/// doInitialization - If this module uses the GC intrinsics, find them now.
bool LowerIntrinsics::doInitialization(Module &M) {
  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
  assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?");
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration() && I->hasGC())
      MI->getFunctionInfo(*I); // Instantiate the GC strategy.

  return false;
}

/// CouldBecomeSafePoint - Predicate to conservatively determine whether the
/// instruction could introduce a safe point.
static bool CouldBecomeSafePoint(Instruction *I) {
  // The natural definition of instructions which could introduce safe points
  // are:
  //
  //   - call, invoke (AfterCall, BeforeCall)
  //   - phis (Loops)
  //   - invoke, ret, unwind (Exit)
  //
  // However, instructions as seemingly inoccuous as arithmetic can become
  // libcalls upon lowering (e.g., div i64 on a 32-bit platform), so instead
  // it is necessary to take a conservative approach.

  if (isa<AllocaInst>(I) || isa<GetElementPtrInst>(I) || isa<StoreInst>(I) ||
      isa<LoadInst>(I))
    return false;

  // llvm.gcroot is safe because it doesn't do anything at runtime.
  if (CallInst *CI = dyn_cast<CallInst>(I))
    if (Function *F = CI->getCalledFunction())
      if (Intrinsic::ID IID = F->getIntrinsicID())
        if (IID == Intrinsic::gcroot)
          return false;

  return true;
}

static bool InsertRootInitializers(Function &F, AllocaInst **Roots,
                                   unsigned Count) {
  // Scroll past alloca instructions.
  BasicBlock::iterator IP = F.getEntryBlock().begin();
  while (isa<AllocaInst>(IP))
    ++IP;

  // Search for initializers in the initial BB.
  SmallPtrSet<AllocaInst *, 16> InitedRoots;
  for (; !CouldBecomeSafePoint(&*IP); ++IP)
    if (StoreInst *SI = dyn_cast<StoreInst>(IP))
      if (AllocaInst *AI =
              dyn_cast<AllocaInst>(SI->getOperand(1)->stripPointerCasts()))
        InitedRoots.insert(AI);

  // Add root initializers.
  bool MadeChange = false;

  for (AllocaInst **I = Roots, **E = Roots + Count; I != E; ++I)
    if (!InitedRoots.count(*I)) {
      StoreInst *SI = new StoreInst(
          ConstantPointerNull::get(cast<PointerType>((*I)->getAllocatedType())),
          *I);
      SI->insertAfter(*I);
      MadeChange = true;
    }

  return MadeChange;
}

/// runOnFunction - Replace gcread/gcwrite intrinsics with loads and stores.
/// Leave gcroot intrinsics; the code generator needs to see those.
bool LowerIntrinsics::runOnFunction(Function &F) {
  // Quick exit for functions that do not use GC.
  if (!F.hasGC())
    return false;

  GCFunctionInfo &FI = getAnalysis<GCModuleInfo>().getFunctionInfo(F);
  GCStrategy &S = FI.getStrategy();

  return DoLowering(F, S);
}

/// Lower barriers out of existance (if the associated GCStrategy hasn't
/// already done so...), and insert initializing stores to roots as a defensive
/// measure.  Given we're going to report all roots live at all safepoints, we
/// need to be able to ensure each root has been initialized by the point the
/// first safepoint is reached.  This really should have been done by the
/// frontend, but the old API made this non-obvious, so we do a potentially
/// redundant store just in case.
bool LowerIntrinsics::DoLowering(Function &F, GCStrategy &S) {
  SmallVector<AllocaInst *, 32> Roots;

  bool MadeChange = false;
  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
    for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) {
      if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++)) {
        Function *F = CI->getCalledFunction();
        switch (F->getIntrinsicID()) {
        default: break;
        case Intrinsic::gcwrite: {
          // Replace a write barrier with a simple store.
          Value *St = new StoreInst(CI->getArgOperand(0),
                                    CI->getArgOperand(2), CI);
          CI->replaceAllUsesWith(St);
          CI->eraseFromParent();
          MadeChange = true;
          break;
        }
        case Intrinsic::gcread: {
          // Replace a read barrier with a simple load.
          Value *Ld = new LoadInst(CI->getArgOperand(1), "", CI);
          Ld->takeName(CI);
          CI->replaceAllUsesWith(Ld);
          CI->eraseFromParent();
          MadeChange = true;
          break;
        }
        case Intrinsic::gcroot: {
          // Initialize the GC root, but do not delete the intrinsic. The
          // backend needs the intrinsic to flag the stack slot.
          Roots.push_back(
              cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts()));
          break;
        }
        }
      }
    }
  }

  if (Roots.size())
    MadeChange |= InsertRootInitializers(F, Roots.begin(), Roots.size());

  return MadeChange;
}

// -----------------------------------------------------------------------------

char GCMachineCodeAnalysis::ID = 0;
char &llvm::GCMachineCodeAnalysisID = GCMachineCodeAnalysis::ID;

INITIALIZE_PASS(GCMachineCodeAnalysis, "gc-analysis",
                "Analyze Machine Code For Garbage Collection", false, false)

GCMachineCodeAnalysis::GCMachineCodeAnalysis() : MachineFunctionPass(ID) {}

void GCMachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
  MachineFunctionPass::getAnalysisUsage(AU);
  AU.setPreservesAll();
  AU.addRequired<MachineModuleInfo>();
  AU.addRequired<GCModuleInfo>();
}

MCSymbol *GCMachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB,
                                             MachineBasicBlock::iterator MI,
                                             const DebugLoc &DL) const {
  MCSymbol *Label = MBB.getParent()->getContext().createTempSymbol();
  BuildMI(MBB, MI, DL, TII->get(TargetOpcode::GC_LABEL)).addSym(Label);
  return Label;
}

void GCMachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) {
  // Find the return address (next instruction), too, so as to bracket the call
  // instruction.
  MachineBasicBlock::iterator RAI = CI;
  ++RAI;

  if (FI->getStrategy().needsSafePoint(GC::PreCall)) {
    MCSymbol *Label = InsertLabel(*CI->getParent(), CI, CI->getDebugLoc());
    FI->addSafePoint(GC::PreCall, Label, CI->getDebugLoc());
  }

  if (FI->getStrategy().needsSafePoint(GC::PostCall)) {
    MCSymbol *Label = InsertLabel(*CI->getParent(), RAI, CI->getDebugLoc());
    FI->addSafePoint(GC::PostCall, Label, CI->getDebugLoc());
  }
}

void GCMachineCodeAnalysis::FindSafePoints(MachineFunction &MF) {
  for (MachineFunction::iterator BBI = MF.begin(), BBE = MF.end(); BBI != BBE;
       ++BBI)
    for (MachineBasicBlock::iterator MI = BBI->begin(), ME = BBI->end();
         MI != ME; ++MI)
      if (MI->isCall()) {
        // Do not treat tail or sibling call sites as safe points.  This is
        // legal since any arguments passed to the callee which live in the
        // remnants of the callers frame will be owned and updated by the
        // callee if required.
        if (MI->isTerminator())
          continue;
        VisitCallPoint(MI);
      }
}

void GCMachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) {
  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
  assert(TFI && "TargetRegisterInfo not available!");

  for (GCFunctionInfo::roots_iterator RI = FI->roots_begin();
       RI != FI->roots_end();) {
    // If the root references a dead object, no need to keep it.
    if (MF.getFrameInfo().isDeadObjectIndex(RI->Num)) {
      RI = FI->removeStackRoot(RI);
    } else {
      unsigned FrameReg; // FIXME: surely GCRoot ought to store the
                         // register that the offset is from?
      RI->StackOffset = TFI->getFrameIndexReference(MF, RI->Num, FrameReg);
      ++RI;
    }
  }
}

bool GCMachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) {
  // Quick exit for functions that do not use GC.
  if (!MF.getFunction().hasGC())
    return false;

  FI = &getAnalysis<GCModuleInfo>().getFunctionInfo(MF.getFunction());
  MMI = &getAnalysis<MachineModuleInfo>();
  TII = MF.getSubtarget().getInstrInfo();

  // Find the size of the stack frame.  There may be no correct static frame
  // size, we use UINT64_MAX to represent this.
  const MachineFrameInfo &MFI = MF.getFrameInfo();
  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
  const bool DynamicFrameSize = MFI.hasVarSizedObjects() ||
    RegInfo->needsStackRealignment(MF);
  FI->setFrameSize(DynamicFrameSize ? UINT64_MAX : MFI.getStackSize());

  // Find all safe points.
  if (FI->getStrategy().needsSafePoints())
    FindSafePoints(MF);

  // Find the concrete stack offsets for all roots (stack slots)
  FindStackOffsets(MF);

  return false;
}
<commit_msg>[GC] Minor style modernization<commit_after>//===-- GCRootLowering.cpp - Garbage collection infrastructure ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the lowering for the gc.root mechanism.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace {

/// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or
/// llvm.gcwrite intrinsics, replacing them with simple loads and stores as
/// directed by the GCStrategy. It also performs automatic root initialization
/// and custom intrinsic lowering.
class LowerIntrinsics : public FunctionPass {
  bool DoLowering(Function &F, GCStrategy &S);

public:
  static char ID;

  LowerIntrinsics();
  StringRef getPassName() const override;
  void getAnalysisUsage(AnalysisUsage &AU) const override;

  bool doInitialization(Module &M) override;
  bool runOnFunction(Function &F) override;
};

/// GCMachineCodeAnalysis - This is a target-independent pass over the machine
/// function representation to identify safe points for the garbage collector
/// in the machine code. It inserts labels at safe points and populates a
/// GCMetadata record for each function.
class GCMachineCodeAnalysis : public MachineFunctionPass {
  GCFunctionInfo *FI;
  MachineModuleInfo *MMI;
  const TargetInstrInfo *TII;

  void FindSafePoints(MachineFunction &MF);
  void VisitCallPoint(MachineBasicBlock::iterator CI);
  MCSymbol *InsertLabel(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                        const DebugLoc &DL) const;

  void FindStackOffsets(MachineFunction &MF);

public:
  static char ID;

  GCMachineCodeAnalysis();
  void getAnalysisUsage(AnalysisUsage &AU) const override;

  bool runOnMachineFunction(MachineFunction &MF) override;
};
}

// -----------------------------------------------------------------------------

INITIALIZE_PASS_BEGIN(LowerIntrinsics, "gc-lowering", "GC Lowering", false,
                      false)
INITIALIZE_PASS_DEPENDENCY(GCModuleInfo)
INITIALIZE_PASS_END(LowerIntrinsics, "gc-lowering", "GC Lowering", false, false)

FunctionPass *llvm::createGCLoweringPass() { return new LowerIntrinsics(); }

char LowerIntrinsics::ID = 0;

LowerIntrinsics::LowerIntrinsics() : FunctionPass(ID) {
  initializeLowerIntrinsicsPass(*PassRegistry::getPassRegistry());
}

StringRef LowerIntrinsics::getPassName() const {
  return "Lower Garbage Collection Instructions";
}

void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
  FunctionPass::getAnalysisUsage(AU);
  AU.addRequired<GCModuleInfo>();
  AU.addPreserved<DominatorTreeWrapperPass>();
}

/// doInitialization - If this module uses the GC intrinsics, find them now.
bool LowerIntrinsics::doInitialization(Module &M) {
  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
  assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?");
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration() && I->hasGC())
      MI->getFunctionInfo(*I); // Instantiate the GC strategy.

  return false;
}

/// CouldBecomeSafePoint - Predicate to conservatively determine whether the
/// instruction could introduce a safe point.
static bool CouldBecomeSafePoint(Instruction *I) {
  // The natural definition of instructions which could introduce safe points
  // are:
  //
  //   - call, invoke (AfterCall, BeforeCall)
  //   - phis (Loops)
  //   - invoke, ret, unwind (Exit)
  //
  // However, instructions as seemingly inoccuous as arithmetic can become
  // libcalls upon lowering (e.g., div i64 on a 32-bit platform), so instead
  // it is necessary to take a conservative approach.

  if (isa<AllocaInst>(I) || isa<GetElementPtrInst>(I) || isa<StoreInst>(I) ||
      isa<LoadInst>(I))
    return false;

  // llvm.gcroot is safe because it doesn't do anything at runtime.
  if (CallInst *CI = dyn_cast<CallInst>(I))
    if (Function *F = CI->getCalledFunction())
      if (Intrinsic::ID IID = F->getIntrinsicID())
        if (IID == Intrinsic::gcroot)
          return false;

  return true;
}

static bool InsertRootInitializers(Function &F, ArrayRef<AllocaInst *> Roots) {
  // Scroll past alloca instructions.
  BasicBlock::iterator IP = F.getEntryBlock().begin();
  while (isa<AllocaInst>(IP))
    ++IP;

  // Search for initializers in the initial BB.
  SmallPtrSet<AllocaInst *, 16> InitedRoots;
  for (; !CouldBecomeSafePoint(&*IP); ++IP)
    if (StoreInst *SI = dyn_cast<StoreInst>(IP))
      if (AllocaInst *AI =
              dyn_cast<AllocaInst>(SI->getOperand(1)->stripPointerCasts()))
        InitedRoots.insert(AI);

  // Add root initializers.
  bool MadeChange = false;

  for (AllocaInst *Root : Roots)
    if (!InitedRoots.count(Root)) {
      StoreInst *SI = new StoreInst(
          ConstantPointerNull::get(cast<PointerType>(Root->getAllocatedType())),
          Root);
      SI->insertAfter(Root);
      MadeChange = true;
    }

  return MadeChange;
}

/// runOnFunction - Replace gcread/gcwrite intrinsics with loads and stores.
/// Leave gcroot intrinsics; the code generator needs to see those.
bool LowerIntrinsics::runOnFunction(Function &F) {
  // Quick exit for functions that do not use GC.
  if (!F.hasGC())
    return false;

  GCFunctionInfo &FI = getAnalysis<GCModuleInfo>().getFunctionInfo(F);
  GCStrategy &S = FI.getStrategy();

  return DoLowering(F, S);
}

/// Lower barriers out of existance (if the associated GCStrategy hasn't
/// already done so...), and insert initializing stores to roots as a defensive
/// measure.  Given we're going to report all roots live at all safepoints, we
/// need to be able to ensure each root has been initialized by the point the
/// first safepoint is reached.  This really should have been done by the
/// frontend, but the old API made this non-obvious, so we do a potentially
/// redundant store just in case.
bool LowerIntrinsics::DoLowering(Function &F, GCStrategy &S) {
  SmallVector<AllocaInst *, 32> Roots;

  bool MadeChange = false;
  for (BasicBlock &BB : F)
    for (BasicBlock::iterator II = BB.begin(), E = BB.end(); II != E;) {
      IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++);
      if (!CI)
        continue;

      Function *F = CI->getCalledFunction();
      switch (F->getIntrinsicID()) {
      default: break;
      case Intrinsic::gcwrite: {
        // Replace a write barrier with a simple store.
        Value *St = new StoreInst(CI->getArgOperand(0),
                                  CI->getArgOperand(2), CI);
        CI->replaceAllUsesWith(St);
        CI->eraseFromParent();
        MadeChange = true;
        break;
      }
      case Intrinsic::gcread: {
        // Replace a read barrier with a simple load.
        Value *Ld = new LoadInst(CI->getArgOperand(1), "", CI);
        Ld->takeName(CI);
        CI->replaceAllUsesWith(Ld);
        CI->eraseFromParent();
        MadeChange = true;
        break;
      }
      case Intrinsic::gcroot: {
        // Initialize the GC root, but do not delete the intrinsic. The
        // backend needs the intrinsic to flag the stack slot.
        Roots.push_back(
            cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts()));
        break;
      }
      }
    }

  if (Roots.size())
    MadeChange |= InsertRootInitializers(F, Roots);

  return MadeChange;
}

// -----------------------------------------------------------------------------

char GCMachineCodeAnalysis::ID = 0;
char &llvm::GCMachineCodeAnalysisID = GCMachineCodeAnalysis::ID;

INITIALIZE_PASS(GCMachineCodeAnalysis, "gc-analysis",
                "Analyze Machine Code For Garbage Collection", false, false)

GCMachineCodeAnalysis::GCMachineCodeAnalysis() : MachineFunctionPass(ID) {}

void GCMachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
  MachineFunctionPass::getAnalysisUsage(AU);
  AU.setPreservesAll();
  AU.addRequired<MachineModuleInfo>();
  AU.addRequired<GCModuleInfo>();
}

MCSymbol *GCMachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB,
                                             MachineBasicBlock::iterator MI,
                                             const DebugLoc &DL) const {
  MCSymbol *Label = MBB.getParent()->getContext().createTempSymbol();
  BuildMI(MBB, MI, DL, TII->get(TargetOpcode::GC_LABEL)).addSym(Label);
  return Label;
}

void GCMachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) {
  // Find the return address (next instruction), too, so as to bracket the call
  // instruction.
  MachineBasicBlock::iterator RAI = CI;
  ++RAI;

  if (FI->getStrategy().needsSafePoint(GC::PreCall)) {
    MCSymbol *Label = InsertLabel(*CI->getParent(), CI, CI->getDebugLoc());
    FI->addSafePoint(GC::PreCall, Label, CI->getDebugLoc());
  }

  if (FI->getStrategy().needsSafePoint(GC::PostCall)) {
    MCSymbol *Label = InsertLabel(*CI->getParent(), RAI, CI->getDebugLoc());
    FI->addSafePoint(GC::PostCall, Label, CI->getDebugLoc());
  }
}

void GCMachineCodeAnalysis::FindSafePoints(MachineFunction &MF) {
  for (MachineBasicBlock &MBB : MF)
    for (MachineBasicBlock::iterator MI = MBB.begin(), ME = MBB.end();
         MI != ME; ++MI)
      if (MI->isCall()) {
        // Do not treat tail or sibling call sites as safe points.  This is
        // legal since any arguments passed to the callee which live in the
        // remnants of the callers frame will be owned and updated by the
        // callee if required.
        if (MI->isTerminator())
          continue;
        VisitCallPoint(MI);
      }
}

void GCMachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) {
  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
  assert(TFI && "TargetRegisterInfo not available!");

  for (GCFunctionInfo::roots_iterator RI = FI->roots_begin();
       RI != FI->roots_end();) {
    // If the root references a dead object, no need to keep it.
    if (MF.getFrameInfo().isDeadObjectIndex(RI->Num)) {
      RI = FI->removeStackRoot(RI);
    } else {
      unsigned FrameReg; // FIXME: surely GCRoot ought to store the
                         // register that the offset is from?
      RI->StackOffset = TFI->getFrameIndexReference(MF, RI->Num, FrameReg);
      ++RI;
    }
  }
}

bool GCMachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) {
  // Quick exit for functions that do not use GC.
  if (!MF.getFunction().hasGC())
    return false;

  FI = &getAnalysis<GCModuleInfo>().getFunctionInfo(MF.getFunction());
  MMI = &getAnalysis<MachineModuleInfo>();
  TII = MF.getSubtarget().getInstrInfo();

  // Find the size of the stack frame.  There may be no correct static frame
  // size, we use UINT64_MAX to represent this.
  const MachineFrameInfo &MFI = MF.getFrameInfo();
  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
  const bool DynamicFrameSize = MFI.hasVarSizedObjects() ||
    RegInfo->needsStackRealignment(MF);
  FI->setFrameSize(DynamicFrameSize ? UINT64_MAX : MFI.getStackSize());

  // Find all safe points.
  if (FI->getStrategy().needsSafePoints())
    FindSafePoints(MF);

  // Find the concrete stack offsets for all roots (stack slots)
  FindStackOffsets(MF);

  return false;
}
<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#ifndef NIX_PROPERTY_H
#define NIX_PROPERTY_H

#include <stdexcept>

#include <nix/base/NamedEntity.hpp>
#include <nix/base/IProperty.hpp>
#include <nix/Value.hpp>

#include <nix/Platform.hpp>

namespace nix {

class NIXAPI Property : virtual public base::IProperty, public base::NamedEntity<base::IProperty> {

public:

    Property()
        : NamedEntity()
    {
    }

    Property(const Property &other)
        : NamedEntity(other.impl())
    {
    }

    Property(const std::shared_ptr<base::IProperty> &p_impl)
        : NamedEntity(p_impl)
    {
    }

    //--------------------------------------------------
    // Attribute getter and setter
    //--------------------------------------------------

    /**
     * Set the mapping information for this Property. The mapping defines how
     * this Property should be treated in a mapping procedure. The mapping is provided
     * in form of an url pointing to the definition of a section into which this
     * property should be mapped
     * (e.g. http:// ... /preparation/preparation.xml#preparation:BathSolution
     *
     * @param mapping string the mapping information.
     *
     */
    void mapping(const std::string &mapping) {
        backend()->mapping(mapping);
    }

    /**
     * Getter for the mapping information stored in this Property.
     * The result may be not initialized, check on true before
     * dereferencing.
     *
     * @returns boost::optional<String> the mapping
     */
    boost::optional<std::string> mapping() const {
        return backend()->mapping();
    }

    /**
     * Deletes the mapping information.
     *
     * @param boost::none_t
     */
    void mapping(const boost::none_t t) {
        backend()->mapping(t);
    }

    /**
     * Returns the dataType of the stored Values. Returned value may be
     * not initialized if no value present, check on true before dereferencing.
     *
     * @param boost::optional<nix::DataType> the value DataType
     *
     */
    boost::optional<DataType> dataType() const {
        return backend()->dataType();
    }

    /**
     * Set the unit of the stored values. Note: all values
     * have the same unit.
     *
     * @param std::string the unit
     */
    void unit(const std::string &unit) {
        if (backend()->valueCount() > 0 && backend()->unit()) {
            throw std::runtime_error("Cannot change unit of a not-empty property!");
        }
        if (!(util::isSIUnit(unit) || util::isCompoundSIUnit(unit))) {
            throw InvalidUnit("Unit is not SI or composite of SI units.", "Property::unit(const string &unit)");
        }
        backend()->unit(unit);
    }

    /**
     * Returns the unit. Return value may be uninitialized,
     * check for true before dereferencing.
     *
     * @return boost::optional<String> the unit
     *
     */
    boost::optional<std::string> unit() const {
        return backend()->unit();
    }

    /**
     * Deletes the unit information.
     *
     * @param boost::none_t
     */
    void unit(const boost::none_t t) {
        return backend()->unit(t);
    }

    //--------------------------------------------------
    // Methods for Value access
    //--------------------------------------------------

    /**
     * Deletes all values of this Property.
     *
     */
    void deleteValues() {
        backend()->deleteValues();
    }

    /**
     * Returns the number of values stored in this Property.
     *
     * @return size_t the count
     */
    size_t valueCount() const {
        return backend()->valueCount();
    }

    /**
     * Set the values of this Property. Replaces all existing Values.
     *
     * @param std::vector<Value> the new values.
     */
    void values(const std::vector<Value> &values) {
        backend()->values(values);
    }

    /**
     * Returns the values stored in this Property. Returned vector may
     * be empty.
     *
     * @return std::vector<Value> the values.
     */
    std::vector<Value> values(void) const {
        return backend()->values();
    }

    /**
     * Deletes the values stored in this Property.
     *
     * @param boost::none_t
     */
    void values(const boost::none_t t) {
        backend()->values(t);
    }

    //------------------------------------------------------
    // Operators and other functions
    //------------------------------------------------------

    virtual Property &operator=(none_t) {
        nullify();
        return *this;
    }

    /**
     * Output operator
     */
    friend std::ostream& operator<<(std::ostream &out, const Property &ent) {
        out << "Property: {name = " << ent.name() << "}";
        return out;
    }

    virtual ~Property() {}

};

} // namespace nix

#endif // NIX_PROPERTY_H
<commit_msg>Property: Add ctor with rvalue ref. for shared_ptr<IProperty><commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#ifndef NIX_PROPERTY_H
#define NIX_PROPERTY_H

#include <stdexcept>

#include <nix/base/NamedEntity.hpp>
#include <nix/base/IProperty.hpp>
#include <nix/Value.hpp>

#include <nix/Platform.hpp>

namespace nix {

class NIXAPI Property : virtual public base::IProperty, public base::NamedEntity<base::IProperty> {

public:

    Property()
        : NamedEntity()
    {
    }

    Property(const Property &other)
        : NamedEntity(other.impl())
    {
    }

    Property(const std::shared_ptr<base::IProperty> &p_impl)
        : NamedEntity(p_impl)
    {
    }

    Property(std::shared_ptr<base::IProperty> &&ptr)
        : NamedEntity(std::move(ptr))
    {
    }

    //--------------------------------------------------
    // Attribute getter and setter
    //--------------------------------------------------

    /**
     * Set the mapping information for this Property. The mapping defines how
     * this Property should be treated in a mapping procedure. The mapping is provided
     * in form of an url pointing to the definition of a section into which this
     * property should be mapped
     * (e.g. http:// ... /preparation/preparation.xml#preparation:BathSolution
     *
     * @param mapping string the mapping information.
     *
     */
    void mapping(const std::string &mapping) {
        backend()->mapping(mapping);
    }

    /**
     * Getter for the mapping information stored in this Property.
     * The result may be not initialized, check on true before
     * dereferencing.
     *
     * @returns boost::optional<String> the mapping
     */
    boost::optional<std::string> mapping() const {
        return backend()->mapping();
    }

    /**
     * Deletes the mapping information.
     *
     * @param boost::none_t
     */
    void mapping(const boost::none_t t) {
        backend()->mapping(t);
    }

    /**
     * Returns the dataType of the stored Values. Returned value may be
     * not initialized if no value present, check on true before dereferencing.
     *
     * @param boost::optional<nix::DataType> the value DataType
     *
     */
    boost::optional<DataType> dataType() const {
        return backend()->dataType();
    }

    /**
     * Set the unit of the stored values. Note: all values
     * have the same unit.
     *
     * @param std::string the unit
     */
    void unit(const std::string &unit) {
        if (backend()->valueCount() > 0 && backend()->unit()) {
            throw std::runtime_error("Cannot change unit of a not-empty property!");
        }
        if (!(util::isSIUnit(unit) || util::isCompoundSIUnit(unit))) {
            throw InvalidUnit("Unit is not SI or composite of SI units.", "Property::unit(const string &unit)");
        }
        backend()->unit(unit);
    }

    /**
     * Returns the unit. Return value may be uninitialized,
     * check for true before dereferencing.
     *
     * @return boost::optional<String> the unit
     *
     */
    boost::optional<std::string> unit() const {
        return backend()->unit();
    }

    /**
     * Deletes the unit information.
     *
     * @param boost::none_t
     */
    void unit(const boost::none_t t) {
        return backend()->unit(t);
    }

    //--------------------------------------------------
    // Methods for Value access
    //--------------------------------------------------

    /**
     * Deletes all values of this Property.
     *
     */
    void deleteValues() {
        backend()->deleteValues();
    }

    /**
     * Returns the number of values stored in this Property.
     *
     * @return size_t the count
     */
    size_t valueCount() const {
        return backend()->valueCount();
    }

    /**
     * Set the values of this Property. Replaces all existing Values.
     *
     * @param std::vector<Value> the new values.
     */
    void values(const std::vector<Value> &values) {
        backend()->values(values);
    }

    /**
     * Returns the values stored in this Property. Returned vector may
     * be empty.
     *
     * @return std::vector<Value> the values.
     */
    std::vector<Value> values(void) const {
        return backend()->values();
    }

    /**
     * Deletes the values stored in this Property.
     *
     * @param boost::none_t
     */
    void values(const boost::none_t t) {
        backend()->values(t);
    }

    //------------------------------------------------------
    // Operators and other functions
    //------------------------------------------------------

    virtual Property &operator=(none_t) {
        nullify();
        return *this;
    }

    /**
     * Output operator
     */
    friend std::ostream& operator<<(std::ostream &out, const Property &ent) {
        out << "Property: {name = " << ent.name() << "}";
        return out;
    }

    virtual ~Property() {}

};

} // namespace nix

#endif // NIX_PROPERTY_H
<|endoftext|>


<commit_before>//===- lib/Driver/GnuLdInputGraph.cpp -------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Driver/GnuLdInputGraph.h"
#include "lld/ReaderWriter/LinkerScript.h"

using namespace lld;

/// \brief Parse the input file to lld::File.
error_code ELFFileNode::parse(const LinkingContext &ctx,
                              raw_ostream &diagnostics) {
  ErrorOr<StringRef> filePath = getPath(ctx);
  if (error_code ec = filePath.getError())
    return ec;

  if (error_code ec = getBuffer(*filePath))
    return ec;

  if (ctx.logInputFiles())
    diagnostics << *filePath << "\n";

  if (_attributes._isWholeArchive) {
    std::vector<std::unique_ptr<File>> parsedFiles;
    error_code ec = ctx.registry().parseFile(_buffer, parsedFiles);
    if (ec)
      return ec;
    assert(parsedFiles.size() == 1);
    std::unique_ptr<File> f(parsedFiles[0].release());
    if (auto archive = reinterpret_cast<const ArchiveLibraryFile *>(f.get())) {
      // Have this node own the FileArchive object.
      _archiveFile.reset(archive);
      f.release();
      // Add all members to _files vector
      return archive->parseAllMembers(_files);
    }
    // if --whole-archive is around non-archive, just use it as normal.
    _files.push_back(std::move(f));
    return error_code::success();
  }
  return ctx.registry().parseFile(_buffer, _files);
}

/// \brief Parse the GnuLD Script
error_code GNULdScript::parse(const LinkingContext &ctx,
                              raw_ostream &diagnostics) {
  ErrorOr<StringRef> filePath = getPath(ctx);
  if (error_code ec = filePath.getError())
    return ec;

  if (error_code ec = getBuffer(*filePath))
    return ec;

  if (ctx.logInputFiles())
    diagnostics << *filePath << "\n";

  _lexer.reset(new script::Lexer(std::move(_buffer)));
  _parser.reset(new script::Parser(*_lexer.get()));

  _linkerScript = _parser->parse();

  if (!_linkerScript)
    return LinkerScriptReaderError::parse_error;

  return error_code::success();
}

/// \brief Handle GnuLD script for ELF.
error_code ELFGNULdScript::parse(const LinkingContext &ctx,
                                 raw_ostream &diagnostics) {
  ELFFileNode::Attributes attributes;
  if (error_code ec = GNULdScript::parse(ctx, diagnostics))
    return ec;
  for (const script::Command *c : _linkerScript->_commands) {
    if (auto group = dyn_cast<script::Group>(c)) {
      std::unique_ptr<Group> groupStart(new Group());
      for (const script::Path &path : group->getPaths()) {
        // TODO : Propagate Set WholeArchive/dashlPrefix
        attributes.setAsNeeded(path._asNeeded);
        auto inputNode = new ELFFileNode(
            _elfLinkingContext, _elfLinkingContext.allocateString(path._path),
            attributes);
        std::unique_ptr<InputElement> inputFile(inputNode);
        cast<Group>(groupStart.get())->addFile(
            std::move(inputFile));
      }
      _expandElements.push_back(std::move(groupStart));
    }
  }
  return error_code::success();
}
<commit_msg>Early continue to reduce nesting.<commit_after>//===- lib/Driver/GnuLdInputGraph.cpp -------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Driver/GnuLdInputGraph.h"
#include "lld/ReaderWriter/LinkerScript.h"

using namespace lld;

/// \brief Parse the input file to lld::File.
error_code ELFFileNode::parse(const LinkingContext &ctx,
                              raw_ostream &diagnostics) {
  ErrorOr<StringRef> filePath = getPath(ctx);
  if (error_code ec = filePath.getError())
    return ec;

  if (error_code ec = getBuffer(*filePath))
    return ec;

  if (ctx.logInputFiles())
    diagnostics << *filePath << "\n";

  if (_attributes._isWholeArchive) {
    std::vector<std::unique_ptr<File>> parsedFiles;
    error_code ec = ctx.registry().parseFile(_buffer, parsedFiles);
    if (ec)
      return ec;
    assert(parsedFiles.size() == 1);
    std::unique_ptr<File> f(parsedFiles[0].release());
    if (auto archive = reinterpret_cast<const ArchiveLibraryFile *>(f.get())) {
      // Have this node own the FileArchive object.
      _archiveFile.reset(archive);
      f.release();
      // Add all members to _files vector
      return archive->parseAllMembers(_files);
    }
    // if --whole-archive is around non-archive, just use it as normal.
    _files.push_back(std::move(f));
    return error_code::success();
  }
  return ctx.registry().parseFile(_buffer, _files);
}

/// \brief Parse the GnuLD Script
error_code GNULdScript::parse(const LinkingContext &ctx,
                              raw_ostream &diagnostics) {
  ErrorOr<StringRef> filePath = getPath(ctx);
  if (error_code ec = filePath.getError())
    return ec;

  if (error_code ec = getBuffer(*filePath))
    return ec;

  if (ctx.logInputFiles())
    diagnostics << *filePath << "\n";

  _lexer.reset(new script::Lexer(std::move(_buffer)));
  _parser.reset(new script::Parser(*_lexer.get()));

  _linkerScript = _parser->parse();

  if (!_linkerScript)
    return LinkerScriptReaderError::parse_error;

  return error_code::success();
}

/// \brief Handle GnuLD script for ELF.
error_code ELFGNULdScript::parse(const LinkingContext &ctx,
                                 raw_ostream &diagnostics) {
  ELFFileNode::Attributes attributes;
  if (error_code ec = GNULdScript::parse(ctx, diagnostics))
    return ec;
  for (const script::Command *c : _linkerScript->_commands) {
    auto *group = dyn_cast<script::Group>(c);
    if (!group)
      continue;
    std::unique_ptr<Group> groupStart(new Group());
    for (const script::Path &path : group->getPaths()) {
      // TODO : Propagate Set WholeArchive/dashlPrefix
      attributes.setAsNeeded(path._asNeeded);
      auto inputNode = new ELFFileNode(
          _elfLinkingContext, _elfLinkingContext.allocateString(path._path),
          attributes);
      std::unique_ptr<InputElement> inputFile(inputNode);
      cast<Group>(groupStart.get())->addFile(std::move(inputFile));
    }
    _expandElements.push_back(std::move(groupStart));
  }
  return error_code::success();
}
<|endoftext|>


<commit_before>
#include <QDateTime>

#include "datetime.h"

QString DateTime::defaultFormat = "yyyy-MM-dd hh:mm::ss";

QString DateTime::getTime()
{
    return getTime(defaultFormat);
}
QString DateTime::getTime(QString format)
{
    if(format.isEmpty()){
        format = defaultFormat;
    }
    QString timeStr = QDateTime::currentDateTime().toString(format);
    return timeStr;
}

<commit_msg>去掉标准时间格式中分数、秒数之间重复的冒号<commit_after>
#include <QDateTime>

#include "datetime.h"

QString DateTime::defaultFormat = "yyyy-MM-dd hh:mm:ss";

QString DateTime::getTime()
{
    return getTime(defaultFormat);
}
QString DateTime::getTime(QString format)
{
    if(format.isEmpty()){
        format = defaultFormat;
    }
    QString timeStr = QDateTime::currentDateTime().toString(format);
    return timeStr;
}

<|endoftext|>


<commit_before><commit_msg>bug in randomgenerator for 64bit int<commit_after><|endoftext|>


<commit_before>//===--- ConstraintLocator.cpp - Constraint Locator -----------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements the \c ConstraintLocator class and its related types,
// which is used by the constraint-based type checker to describe how
// a particular constraint was derived.
//
//===----------------------------------------------------------------------===//
#include "ConstraintLocator.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Types.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"

using namespace swift;
using namespace constraints;

void ConstraintLocator::Profile(llvm::FoldingSetNodeID &id, Expr *anchor,
                                ArrayRef<PathElement> path) {
  id.AddPointer(anchor);
  id.AddInteger(path.size());
  for (auto elt : path) {
    id.AddInteger(elt.getKind());
    unsigned numValues = numNumericValuesInPathElement(elt.getKind());
    if (numValues > 0) {
      id.AddInteger(elt.getValue());
      if (numValues > 1)
        id.AddInteger(elt.getValue2());
    }
    else if (elt.getKind() == ConstraintLocator::Archetype)
      id.AddPointer(elt.getArchetype()->getCanonicalType().getPointer());
  }
}

void ConstraintLocator::dump(SourceManager *sm) {
  dump(sm, llvm::errs());
}

void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
  out << "locator@" << (void*) this << " [";

  if (anchor) {
    out << Expr::getKindName(anchor->getKind());
    if (sm) {
      out << '@';
      anchor->getLoc().print(out, *sm);
    }
  }

  for (auto elt : getPath()) {
    out << " -> ";
    switch (elt.getKind()) {
    case AddressOf:
      out << "address of";
      break;

    case ArrayElementType:
      out << "array element";
      break;

    case Archetype:
      out << "archetype '" << elt.getArchetype()->getString() << "'";
      break;

    case AssociatedType:
      out << "associated type '"
          << elt.getAssociatedType()->getNameStr() << "'";
      break;

    case ApplyArgument:
      out << "apply argument";
      break;

    case ApplyFunction:
      out << "apply function";
      break;

    case ApplyArgToParam:
      out << "comparing call argument #" << llvm::utostr(elt.getValue())
          << " to parameter #" << llvm::utostr(elt.getValue2());
      break;

    case AssignDest:
      out << "assignment destination";
      break;

    case AssignSource:
      out << "assignment source";
      break;

    case CheckedCastOperand:
      out << "checked cast operand";
      break;

    case ClosureResult:
      out << "closure result";
      break;

    case ConstructorMember:
      out << "constructor member";
      break;

    case FunctionArgument:
      out << "function argument";
      break;

    case FunctionResult:
      out << "function result";
      break;

    case GeneratorElementType:
      out << "generator element type";
      break;

    case GenericArgument:
      out << "generic argument #" << llvm::utostr(elt.getValue());
      break;

    case IfElse:
      out << "'else' branch of ternary" ;
      break;

    case IfThen:
      out << "'then' branch of ternary" ;
      break;

    case InstanceType:
      out << "instance type";
      break;

    case InterpolationArgument:
      out << "interpolation argument #" << llvm::utostr(elt.getValue());
      break;

    case Load:
      out << "load";
      break;

    case LvalueObjectType:
      out << "lvalue object type";
      break;

    case Member:
      out << "member";
      break;

    case MemberRefBase:
      out << "member reference base";
      break;

    case NamedTupleElement:
      out << "named tuple element #" << llvm::utostr(elt.getValue());
      break;

    case UnresolvedMember:
      out << "unresolved member";
      break;

    case ParentType:
      out << "parent type";
      break;

    case RvalueAdjustment:
      out << "rvalue adjustment";
      break;

    case ScalarToTuple:
      out << "scalar to tuple";
      break;

    case SequenceGeneratorType:
      out << "sequence generator type";
      break;

    case SubscriptIndex:
      out << "subscript index";
      break;

    case SubscriptMember:
      out << "subscript member";
      break;

    case SubscriptResult:
      out << "subscript result";
      break;

    case TupleElement:
      out << "tuple element #" << llvm::utostr(elt.getValue());
      break;

    case Witness:
      out << "witness ";
      elt.getWitness()->dumpRef(out);
      break;
    }
  }

  out << ']';
}

<commit_msg>Update ConstraintLocator profiling for witnesses and associated types.<commit_after>//===--- ConstraintLocator.cpp - Constraint Locator -----------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements the \c ConstraintLocator class and its related types,
// which is used by the constraint-based type checker to describe how
// a particular constraint was derived.
//
//===----------------------------------------------------------------------===//
#include "ConstraintLocator.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Types.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"

using namespace swift;
using namespace constraints;

void ConstraintLocator::Profile(llvm::FoldingSetNodeID &id, Expr *anchor,
                                ArrayRef<PathElement> path) {
  id.AddPointer(anchor);
  id.AddInteger(path.size());
  for (auto elt : path) {
    id.AddInteger(elt.getKind());
    switch (elt.getKind()) {
    case Archetype:
      id.AddPointer(elt.getArchetype()->getCanonicalType().getPointer());
      break;

    case Witness:
      id.AddPointer(elt.getWitness());
      break;

    case AssociatedType:
      id.AddPointer(elt.getAssociatedType());
      break;

    case ApplyArgument:
    case ApplyFunction:
    case FunctionArgument:
    case FunctionResult:
    case Member:
    case MemberRefBase:
    case UnresolvedMember:
    case SubscriptIndex:
    case SubscriptMember:
    case SubscriptResult:
    case ConstructorMember:
    case AddressOf:
    case RvalueAdjustment:
    case ClosureResult:
    case ParentType:
    case InstanceType:
    case SequenceGeneratorType:
    case GeneratorElementType:
    case ArrayElementType:
    case LvalueObjectType:
    case ScalarToTuple:
    case Load:
    case IfThen:
    case IfElse:
    case AssignSource:
    case AssignDest:
    case CheckedCastOperand:
    case GenericArgument:
    case InterpolationArgument:
    case NamedTupleElement:
    case TupleElement:
    case ApplyArgToParam:
      if (unsigned numValues = numNumericValuesInPathElement(elt.getKind())) {
        id.AddInteger(elt.getValue());
        if (numValues > 1)
          id.AddInteger(elt.getValue2());
      }
      break;
    }
  }
}

void ConstraintLocator::dump(SourceManager *sm) {
  dump(sm, llvm::errs());
}

void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) {
  out << "locator@" << (void*) this << " [";

  if (anchor) {
    out << Expr::getKindName(anchor->getKind());
    if (sm) {
      out << '@';
      anchor->getLoc().print(out, *sm);
    }
  }

  for (auto elt : getPath()) {
    out << " -> ";
    switch (elt.getKind()) {
    case AddressOf:
      out << "address of";
      break;

    case ArrayElementType:
      out << "array element";
      break;

    case Archetype:
      out << "archetype '" << elt.getArchetype()->getString() << "'";
      break;

    case AssociatedType:
      out << "associated type '"
          << elt.getAssociatedType()->getNameStr() << "'";
      break;

    case ApplyArgument:
      out << "apply argument";
      break;

    case ApplyFunction:
      out << "apply function";
      break;

    case ApplyArgToParam:
      out << "comparing call argument #" << llvm::utostr(elt.getValue())
          << " to parameter #" << llvm::utostr(elt.getValue2());
      break;

    case AssignDest:
      out << "assignment destination";
      break;

    case AssignSource:
      out << "assignment source";
      break;

    case CheckedCastOperand:
      out << "checked cast operand";
      break;

    case ClosureResult:
      out << "closure result";
      break;

    case ConstructorMember:
      out << "constructor member";
      break;

    case FunctionArgument:
      out << "function argument";
      break;

    case FunctionResult:
      out << "function result";
      break;

    case GeneratorElementType:
      out << "generator element type";
      break;

    case GenericArgument:
      out << "generic argument #" << llvm::utostr(elt.getValue());
      break;

    case IfElse:
      out << "'else' branch of ternary" ;
      break;

    case IfThen:
      out << "'then' branch of ternary" ;
      break;

    case InstanceType:
      out << "instance type";
      break;

    case InterpolationArgument:
      out << "interpolation argument #" << llvm::utostr(elt.getValue());
      break;

    case Load:
      out << "load";
      break;

    case LvalueObjectType:
      out << "lvalue object type";
      break;

    case Member:
      out << "member";
      break;

    case MemberRefBase:
      out << "member reference base";
      break;

    case NamedTupleElement:
      out << "named tuple element #" << llvm::utostr(elt.getValue());
      break;

    case UnresolvedMember:
      out << "unresolved member";
      break;

    case ParentType:
      out << "parent type";
      break;

    case RvalueAdjustment:
      out << "rvalue adjustment";
      break;

    case ScalarToTuple:
      out << "scalar to tuple";
      break;

    case SequenceGeneratorType:
      out << "sequence generator type";
      break;

    case SubscriptIndex:
      out << "subscript index";
      break;

    case SubscriptMember:
      out << "subscript member";
      break;

    case SubscriptResult:
      out << "subscript result";
      break;

    case TupleElement:
      out << "tuple element #" << llvm::utostr(elt.getValue());
      break;

    case Witness:
      out << "witness ";
      elt.getWitness()->dumpRef(out);
      break;
    }
  }

  out << ']';
}

<|endoftext|>