[cfe-commits] r85499 - in /cfe/trunk: include/clang/AST/DeclTemplate.h include/clang/AST/TemplateBase.h lib/AST/CMakeLists.txt lib/AST/DeclTemplate.cpp lib/AST/TemplateBase.cpp

John McCall rjmccall at apple.com
Thu Oct 29 00:48:15 PDT 2009


Author: rjmccall
Date: Thu Oct 29 02:48:15 2009
New Revision: 85499

URL: http://llvm.org/viewvc/llvm-project?rev=85499&view=rev
Log:
Extract TemplateArgument into a new header just for common template
classes.  Move its implementation into a new module.

This will seem marginally more justified in a bit.


Added:
    cfe/trunk/include/clang/AST/TemplateBase.h
    cfe/trunk/lib/AST/TemplateBase.cpp
Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/CMakeLists.txt
    cfe/trunk/lib/AST/DeclTemplate.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=85499&r1=85498&r2=85499&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Thu Oct 29 02:48:15 2009
@@ -15,8 +15,7 @@
 #define LLVM_CLANG_AST_DECLTEMPLATE_H
 
 #include "clang/AST/DeclCXX.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/FoldingSet.h"
+#include "clang/AST/TemplateBase.h"
 #include "llvm/ADT/PointerUnion.h"
 #include <limits>
 
@@ -107,251 +106,6 @@
   }
 };
 
-/// \brief Represents a template argument within a class template
-/// specialization.
-class TemplateArgument {
-  union {
-    uintptr_t TypeOrValue;
-    struct {
-      char Value[sizeof(llvm::APSInt)];
-      void *Type;
-    } Integer;
-    struct {
-      TemplateArgument *Args;
-      unsigned NumArgs;
-      bool CopyArgs;
-    } Args;
-  };
-
-  /// \brief Location of the beginning of this template argument.
-  SourceLocation StartLoc;
-
-public:
-  /// \brief The type of template argument we're storing.
-  enum ArgKind {
-    Null = 0,
-    /// The template argument is a type. Its value is stored in the
-    /// TypeOrValue field.
-    Type = 1,
-    /// The template argument is a declaration
-    Declaration = 2,
-    /// The template argument is an integral value stored in an llvm::APSInt.
-    Integral = 3,
-    /// The template argument is a value- or type-dependent expression
-    /// stored in an Expr*.
-    Expression = 4,
-
-    /// The template argument is actually a parameter pack. Arguments are stored
-    /// in the Args struct.
-    Pack = 5
-  } Kind;
-
-  /// \brief Construct an empty, invalid template argument.
-  TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
-
-  /// \brief Construct a template type argument.
-  TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
-    TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
-    StartLoc = Loc;
-  }
-
-  /// \brief Construct a template argument that refers to a
-  /// declaration, which is either an external declaration or a
-  /// template declaration.
-  TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
-    // FIXME: Need to be sure we have the "canonical" declaration!
-    TypeOrValue = reinterpret_cast<uintptr_t>(D);
-    StartLoc = Loc;
-  }
-
-  /// \brief Construct an integral constant template argument.
-  TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
-                   QualType Type)
-  : Kind(Integral) {
-    new (Integer.Value) llvm::APSInt(Value);
-    Integer.Type = Type.getAsOpaquePtr();
-    StartLoc = Loc;
-  }
-
-  /// \brief Construct a template argument that is an expression.
-  ///
-  /// This form of template argument only occurs in template argument
-  /// lists used for dependent types and for expression; it will not
-  /// occur in a non-dependent, canonical template argument list.
-  TemplateArgument(Expr *E);
-
-  /// \brief Copy constructor for a template argument.
-  TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
-    if (Kind == Integral) {
-      new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
-      Integer.Type = Other.Integer.Type;
-    } else if (Kind == Pack) {
-      Args.NumArgs = Other.Args.NumArgs;
-      Args.Args = new TemplateArgument[Args.NumArgs];
-      for (unsigned I = 0; I != Args.NumArgs; ++I)
-        Args.Args[I] = Other.Args.Args[I];
-    }
-    else
-      TypeOrValue = Other.TypeOrValue;
-    StartLoc = Other.StartLoc;
-  }
-
-  TemplateArgument& operator=(const TemplateArgument& Other) {
-    // FIXME: Does not provide the strong guarantee for exception
-    // safety.
-    using llvm::APSInt;
-
-    // FIXME: Handle Packs
-    assert(Kind != Pack && "FIXME: Handle packs");
-    assert(Other.Kind != Pack && "FIXME: Handle packs");
-
-    if (Kind == Other.Kind && Kind == Integral) {
-      // Copy integral values.
-      *this->getAsIntegral() = *Other.getAsIntegral();
-      Integer.Type = Other.Integer.Type;
-    } else {
-      // Destroy the current integral value, if that's what we're holding.
-      if (Kind == Integral)
-        getAsIntegral()->~APSInt();
-
-      Kind = Other.Kind;
-
-      if (Other.Kind == Integral) {
-        new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
-        Integer.Type = Other.Integer.Type;
-      } else
-        TypeOrValue = Other.TypeOrValue;
-    }
-    StartLoc = Other.StartLoc;
-
-    return *this;
-  }
-
-  ~TemplateArgument() {
-    using llvm::APSInt;
-
-    if (Kind == Integral)
-      getAsIntegral()->~APSInt();
-    else if (Kind == Pack && Args.CopyArgs)
-      delete[] Args.Args;
-  }
-
-  /// \brief Return the kind of stored template argument.
-  ArgKind getKind() const { return Kind; }
-
-  /// \brief Determine whether this template argument has no value.
-  bool isNull() const { return Kind == Null; }
-
-  /// \brief Retrieve the template argument as a type.
-  QualType getAsType() const {
-    if (Kind != Type)
-      return QualType();
-
-    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
-  }
-
-  /// \brief Retrieve the template argument as a declaration.
-  Decl *getAsDecl() const {
-    if (Kind != Declaration)
-      return 0;
-    return reinterpret_cast<Decl *>(TypeOrValue);
-  }
-
-  /// \brief Retrieve the template argument as an integral value.
-  llvm::APSInt *getAsIntegral() {
-    if (Kind != Integral)
-      return 0;
-    return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
-  }
-
-  const llvm::APSInt *getAsIntegral() const {
-    return const_cast<TemplateArgument*>(this)->getAsIntegral();
-  }
-
-  /// \brief Retrieve the type of the integral value.
-  QualType getIntegralType() const {
-    if (Kind != Integral)
-      return QualType();
-
-    return QualType::getFromOpaquePtr(Integer.Type);
-  }
-
-  void setIntegralType(QualType T) {
-    assert(Kind == Integral &&
-           "Cannot set the integral type of a non-integral template argument");
-    Integer.Type = T.getAsOpaquePtr();
-  };
-
-  /// \brief Retrieve the template argument as an expression.
-  Expr *getAsExpr() const {
-    if (Kind != Expression)
-      return 0;
-
-    return reinterpret_cast<Expr *>(TypeOrValue);
-  }
-
-  /// \brief Iterator that traverses the elements of a template argument pack.
-  typedef const TemplateArgument * pack_iterator;
-
-  /// \brief Iterator referencing the first argument of a template argument
-  /// pack.
-  pack_iterator pack_begin() const {
-    assert(Kind == Pack);
-    return Args.Args;
-  }
-
-  /// \brief Iterator referencing one past the last argument of a template
-  /// argument pack.
-  pack_iterator pack_end() const {
-    assert(Kind == Pack);
-    return Args.Args + Args.NumArgs;
-  }
-
-  /// \brief The number of template arguments in the given template argument
-  /// pack.
-  unsigned pack_size() const {
-    assert(Kind == Pack);
-    return Args.NumArgs;
-  }
-
-  /// \brief Retrieve the location where the template argument starts.
-  SourceLocation getLocation() const { return StartLoc; }
-
-  /// \brief Construct a template argument pack.
-  void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
-
-  /// \brief Used to insert TemplateArguments into FoldingSets.
-  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const {
-    ID.AddInteger(Kind);
-    switch (Kind) {
-      case Null:
-        break;
-
-      case Type:
-        getAsType().Profile(ID);
-        break;
-
-      case Declaration:
-        ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
-        break;
-
-      case Integral:
-        getAsIntegral()->Profile(ID);
-        getIntegralType().Profile(ID);
-        break;
-
-      case Expression:
-        getAsExpr()->Profile(ID, Context, true);
-        break;
-
-      case Pack:
-        ID.AddInteger(Args.NumArgs);
-        for (unsigned I = 0; I != Args.NumArgs; ++I)
-          Args.Args[I].Profile(ID, Context);
-    }
-  }
-};
-
 /// \brief A helper class for making template argument lists.
 class TemplateArgumentListBuilder {
   TemplateArgument *StructuredArgs;

Added: cfe/trunk/include/clang/AST/TemplateBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=85499&view=auto

==============================================================================
--- cfe/trunk/include/clang/AST/TemplateBase.h (added)
+++ cfe/trunk/include/clang/AST/TemplateBase.h Thu Oct 29 02:48:15 2009
@@ -0,0 +1,249 @@
+//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides definitions which are common for all kinds of
+//  template representation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
+#define LLVM_CLANG_AST_TEMPLATEBASE_H
+
+#include "llvm/ADT/APSInt.h"
+#include "clang/AST/Type.h"
+
+namespace llvm {
+  class FoldingSetNodeID;
+}
+
+namespace clang {
+
+class Decl;
+class Expr;
+
+/// \brief Represents a template argument within a class template
+/// specialization.
+class TemplateArgument {
+  union {
+    uintptr_t TypeOrValue;
+    struct {
+      char Value[sizeof(llvm::APSInt)];
+      void *Type;
+    } Integer;
+    struct {
+      TemplateArgument *Args;
+      unsigned NumArgs;
+      bool CopyArgs;
+    } Args;
+  };
+
+  /// \brief Location of the beginning of this template argument.
+  SourceLocation StartLoc;
+
+public:
+  /// \brief The type of template argument we're storing.
+  enum ArgKind {
+    Null = 0,
+    /// The template argument is a type. Its value is stored in the
+    /// TypeOrValue field.
+    Type = 1,
+    /// The template argument is a declaration
+    Declaration = 2,
+    /// The template argument is an integral value stored in an llvm::APSInt.
+    Integral = 3,
+    /// The template argument is a value- or type-dependent expression
+    /// stored in an Expr*.
+    Expression = 4,
+
+    /// The template argument is actually a parameter pack. Arguments are stored
+    /// in the Args struct.
+    Pack = 5
+  } Kind;
+
+  /// \brief Construct an empty, invalid template argument.
+  TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
+
+  /// \brief Construct a template type argument.
+  TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
+    TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+    StartLoc = Loc;
+  }
+
+  /// \brief Construct a template argument that refers to a
+  /// declaration, which is either an external declaration or a
+  /// template declaration.
+  TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
+    // FIXME: Need to be sure we have the "canonical" declaration!
+    TypeOrValue = reinterpret_cast<uintptr_t>(D);
+    StartLoc = Loc;
+  }
+
+  /// \brief Construct an integral constant template argument.
+  TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
+                   QualType Type)
+  : Kind(Integral) {
+    new (Integer.Value) llvm::APSInt(Value);
+    Integer.Type = Type.getAsOpaquePtr();
+    StartLoc = Loc;
+  }
+
+  /// \brief Construct a template argument that is an expression.
+  ///
+  /// This form of template argument only occurs in template argument
+  /// lists used for dependent types and for expression; it will not
+  /// occur in a non-dependent, canonical template argument list.
+  TemplateArgument(Expr *E);
+
+  /// \brief Copy constructor for a template argument.
+  TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
+    if (Kind == Integral) {
+      new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+      Integer.Type = Other.Integer.Type;
+    } else if (Kind == Pack) {
+      Args.NumArgs = Other.Args.NumArgs;
+      Args.Args = new TemplateArgument[Args.NumArgs];
+      for (unsigned I = 0; I != Args.NumArgs; ++I)
+        Args.Args[I] = Other.Args.Args[I];
+    }
+    else
+      TypeOrValue = Other.TypeOrValue;
+    StartLoc = Other.StartLoc;
+  }
+
+  TemplateArgument& operator=(const TemplateArgument& Other) {
+    // FIXME: Does not provide the strong guarantee for exception
+    // safety.
+    using llvm::APSInt;
+
+    // FIXME: Handle Packs
+    assert(Kind != Pack && "FIXME: Handle packs");
+    assert(Other.Kind != Pack && "FIXME: Handle packs");
+
+    if (Kind == Other.Kind && Kind == Integral) {
+      // Copy integral values.
+      *this->getAsIntegral() = *Other.getAsIntegral();
+      Integer.Type = Other.Integer.Type;
+    } else {
+      // Destroy the current integral value, if that's what we're holding.
+      if (Kind == Integral)
+        getAsIntegral()->~APSInt();
+
+      Kind = Other.Kind;
+
+      if (Other.Kind == Integral) {
+        new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+        Integer.Type = Other.Integer.Type;
+      } else
+        TypeOrValue = Other.TypeOrValue;
+    }
+    StartLoc = Other.StartLoc;
+
+    return *this;
+  }
+
+  ~TemplateArgument() {
+    using llvm::APSInt;
+
+    if (Kind == Integral)
+      getAsIntegral()->~APSInt();
+    else if (Kind == Pack && Args.CopyArgs)
+      delete[] Args.Args;
+  }
+
+  /// \brief Return the kind of stored template argument.
+  ArgKind getKind() const { return Kind; }
+
+  /// \brief Determine whether this template argument has no value.
+  bool isNull() const { return Kind == Null; }
+
+  /// \brief Retrieve the template argument as a type.
+  QualType getAsType() const {
+    if (Kind != Type)
+      return QualType();
+
+    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
+  }
+
+  /// \brief Retrieve the template argument as a declaration.
+  Decl *getAsDecl() const {
+    if (Kind != Declaration)
+      return 0;
+    return reinterpret_cast<Decl *>(TypeOrValue);
+  }
+
+  /// \brief Retrieve the template argument as an integral value.
+  llvm::APSInt *getAsIntegral() {
+    if (Kind != Integral)
+      return 0;
+    return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
+  }
+
+  const llvm::APSInt *getAsIntegral() const {
+    return const_cast<TemplateArgument*>(this)->getAsIntegral();
+  }
+
+  /// \brief Retrieve the type of the integral value.
+  QualType getIntegralType() const {
+    if (Kind != Integral)
+      return QualType();
+
+    return QualType::getFromOpaquePtr(Integer.Type);
+  }
+
+  void setIntegralType(QualType T) {
+    assert(Kind == Integral &&
+           "Cannot set the integral type of a non-integral template argument");
+    Integer.Type = T.getAsOpaquePtr();
+  };
+
+  /// \brief Retrieve the template argument as an expression.
+  Expr *getAsExpr() const {
+    if (Kind != Expression)
+      return 0;
+
+    return reinterpret_cast<Expr *>(TypeOrValue);
+  }
+
+  /// \brief Iterator that traverses the elements of a template argument pack.
+  typedef const TemplateArgument * pack_iterator;
+
+  /// \brief Iterator referencing the first argument of a template argument
+  /// pack.
+  pack_iterator pack_begin() const {
+    assert(Kind == Pack);
+    return Args.Args;
+  }
+
+  /// \brief Iterator referencing one past the last argument of a template
+  /// argument pack.
+  pack_iterator pack_end() const {
+    assert(Kind == Pack);
+    return Args.Args + Args.NumArgs;
+  }
+
+  /// \brief The number of template arguments in the given template argument
+  /// pack.
+  unsigned pack_size() const {
+    assert(Kind == Pack);
+    return Args.NumArgs;
+  }
+
+  /// \brief Retrieve the location where the template argument starts.
+  SourceLocation getLocation() const { return StartLoc; }
+
+  /// \brief Construct a template argument pack.
+  void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
+
+  /// \brief Used to insert TemplateArguments into FoldingSets.
+  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const;
+};
+
+}
+
+#endif

Modified: cfe/trunk/lib/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=85499&r1=85498&r2=85499&view=diff

==============================================================================
--- cfe/trunk/lib/AST/CMakeLists.txt (original)
+++ cfe/trunk/lib/AST/CMakeLists.txt Thu Oct 29 02:48:15 2009
@@ -26,6 +26,7 @@
   StmtPrinter.cpp
   StmtProfile.cpp
   StmtViz.cpp
+  TemplateBase.cpp
   TemplateName.cpp
   Type.cpp
   TypeLoc.cpp

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=85499&r1=85498&r2=85499&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Thu Oct 29 02:48:15 2009
@@ -287,34 +287,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// TemplateArgument Implementation
-//===----------------------------------------------------------------------===//
-
-TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
-  TypeOrValue = reinterpret_cast<uintptr_t>(E);
-  StartLoc = E->getSourceRange().getBegin();
-}
-
-/// \brief Construct a template argument pack.
-void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
-                                       bool CopyArgs) {
-  assert(isNull() && "Must call setArgumentPack on a null argument");
-
-  Kind = Pack;
-  Args.NumArgs = NumArgs;
-  Args.CopyArgs = CopyArgs;
-  if (!Args.CopyArgs) {
-    Args.Args = args;
-    return;
-  }
-
-  // FIXME: Allocate in ASTContext
-  Args.Args = new TemplateArgument[NumArgs];
-  for (unsigned I = 0; I != Args.NumArgs; ++I)
-    Args.Args[I] = args[I];
-}
-
-//===----------------------------------------------------------------------===//
 // TemplateArgumentListBuilder Implementation
 //===----------------------------------------------------------------------===//
 

Added: cfe/trunk/lib/AST/TemplateBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=85499&view=auto

==============================================================================
--- cfe/trunk/lib/AST/TemplateBase.cpp (added)
+++ cfe/trunk/lib/AST/TemplateBase.cpp Thu Oct 29 02:48:15 2009
@@ -0,0 +1,79 @@
+//===--- TemplateBase.cpp - Common template AST class implementation ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements common classes used throughout C++ template
+// representations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/FoldingSet.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/Expr.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// TemplateArgument Implementation
+//===----------------------------------------------------------------------===//
+
+TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
+  TypeOrValue = reinterpret_cast<uintptr_t>(E);
+  StartLoc = E->getSourceRange().getBegin();
+}
+
+/// \brief Construct a template argument pack.
+void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
+                                       bool CopyArgs) {
+  assert(isNull() && "Must call setArgumentPack on a null argument");
+
+  Kind = Pack;
+  Args.NumArgs = NumArgs;
+  Args.CopyArgs = CopyArgs;
+  if (!Args.CopyArgs) {
+    Args.Args = args;
+    return;
+  }
+
+  // FIXME: Allocate in ASTContext
+  Args.Args = new TemplateArgument[NumArgs];
+  for (unsigned I = 0; I != Args.NumArgs; ++I)
+    Args.Args[I] = args[I];
+}
+
+void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
+                               ASTContext &Context) const {
+  ID.AddInteger(Kind);
+  switch (Kind) {
+  case Null:
+    break;
+
+  case Type:
+    getAsType().Profile(ID);
+    break;
+
+  case Declaration:
+    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
+    break;
+
+  case Integral:
+    getAsIntegral()->Profile(ID);
+    getIntegralType().Profile(ID);
+    break;
+
+  case Expression:
+    getAsExpr()->Profile(ID, Context, true);
+    break;
+
+  case Pack:
+    ID.AddInteger(Args.NumArgs);
+    for (unsigned I = 0; I != Args.NumArgs; ++I)
+      Args.Args[I].Profile(ID, Context);
+  }
+}





More information about the cfe-commits mailing list