[cfe-commits] r39496 - in /cfe/cfe/trunk: AST/ASTContext.cpp AST/Type.cpp Parse/ParseDecl.cpp Sema/SemaType.cpp include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Parse/DeclSpec.h

bwendlin at cs.uiuc.edu bwendlin at cs.uiuc.edu
Wed Jul 11 09:44:59 PDT 2007


Author: bwendlin
Date: Wed Jul 11 11:44:59 2007
New Revision: 39496

URL: http://llvm.org/viewvc/llvm-project?rev=39496&view=rev
Log:
Bug #:
Submitted by: Bill Wendling
Reviewed by: Chris Lattner

- Initial support for C++ references. Adding to the AST and Parser.
  Skeletal support added in the semantic analysis portion. Full semantic
  analysis is to be done soon.

Modified:
    cfe/cfe/trunk/AST/ASTContext.cpp
    cfe/cfe/trunk/AST/Type.cpp
    cfe/cfe/trunk/Parse/ParseDecl.cpp
    cfe/cfe/trunk/Sema/SemaType.cpp
    cfe/cfe/trunk/include/clang/AST/ASTContext.h
    cfe/cfe/trunk/include/clang/AST/Type.h
    cfe/cfe/trunk/include/clang/Parse/DeclSpec.h

Modified: cfe/cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/ASTContext.cpp?rev=39496&r1=39495&r2=39496&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/cfe/trunk/AST/ASTContext.cpp Wed Jul 11 11:44:59 2007
@@ -42,7 +42,7 @@
   fprintf(stderr, "*** AST Context Stats:\n");
   fprintf(stderr, "  %d types total.\n", (int)Types.size());
   unsigned NumBuiltin = 0, NumPointer = 0, NumArray = 0, NumFunctionP = 0;
-  unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0;
+  unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0, NumReference = 0;
   
   unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
   
@@ -52,6 +52,8 @@
       ++NumBuiltin;
     else if (isa<PointerType>(T))
       ++NumPointer;
+    else if (isa<ReferenceType>(T))
+      ++NumReference;
     else if (isa<ArrayType>(T))
       ++NumArray;
     else if (isa<FunctionTypeNoProto>(T))
@@ -76,6 +78,7 @@
 
   fprintf(stderr, "    %d builtin types\n", NumBuiltin);
   fprintf(stderr, "    %d pointer types\n", NumPointer);
+  fprintf(stderr, "    %d reference types\n", NumReference);
   fprintf(stderr, "    %d array types\n", NumArray);
   fprintf(stderr, "    %d function types with proto\n", NumFunctionP);
   fprintf(stderr, "    %d function types with no proto\n", NumFunctionNP);
@@ -161,6 +164,35 @@
   return QualType(New, 0);
 }
 
+/// getReferenceType - Return the uniqued reference to the type for a reference
+/// to the specified type.
+QualType ASTContext::getReferenceType(QualType T) {
+  // Unique pointers, to guarantee there is only one pointer of a particular
+  // structure.
+  FoldingSetNodeID ID;
+  ReferenceType::Profile(ID, T);
+
+  void *InsertPos = 0;
+  if (ReferenceType *RT = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(RT, 0);
+  
+  // If the referencee type isn't canonical, this won't be a canonical type
+  // either, so fill in the canonical type field.
+  QualType Canonical;
+  if (!T->isCanonical()) {
+    Canonical = getReferenceType(T.getCanonicalType());
+   
+    // Get the new insert position for the node we care about.
+    ReferenceType *NewIP = ReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!");
+  }
+
+  ReferenceType *New = new ReferenceType(T, Canonical);
+  Types.push_back(New);
+  ReferenceTypes.InsertNode(New, InsertPos);
+  return QualType(New, 0);
+}
+
 /// getArrayType - Return the unique reference to the type for an array of the
 /// specified element type.
 QualType ASTContext::getArrayType(QualType EltTy,ArrayType::ArraySizeModifier ASM,

Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39496&r1=39495&r2=39496&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:44:59 2007
@@ -15,8 +15,7 @@
 #include "clang/AST/Type.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
-
-#include <iostream>
+#include "llvm/Support/Streams.h"
 
 using namespace llvm;
 using namespace clang;
@@ -40,8 +39,8 @@
 }
 
 bool Type::isDerivedType() const {
-  return isPointerType() || isArrayType() || isFunctionType() ||
-         isStructureType() || isUnionType();
+  return isPointerType() || isReferenceType() || isArrayType() ||
+         isFunctionType() || isStructureType() || isUnionType();
 }
 
 bool Type::isFunctionType() const {
@@ -52,6 +51,10 @@
   return isa<PointerType>(CanonicalType);
 }
 
+bool Type::isReferenceType() const {
+  return isa<ReferenceType>(CanonicalType);
+}
+
 bool Type::isArrayType() const {
   return isa<ArrayType>(CanonicalType);
 }
@@ -379,9 +382,9 @@
   std::string R = "foo";
   getAsStringInternal(R);
   if (msg)
-    std::cerr << msg << ": " << R << "\n";
+    cerr << msg << ": " << R << "\n";
   else
-    std::cerr << R << "\n";
+    cerr << R << "\n";
 }
 
 static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
@@ -435,6 +438,17 @@
   PointeeType.getAsStringInternal(S);
 }
 
+void ReferenceType::getAsStringInternal(std::string &S) const {
+  S = '&' + S;
+  
+  // Handle things like 'int (&A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(ReferenceeType.getTypePtr()))
+    S = '(' + S + ')';
+  
+  ReferenceeType.getAsStringInternal(S);
+}
+
 void ArrayType::getAsStringInternal(std::string &S) const {
   S += '[';
   

Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39496&r1=39495&r2=39496&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:44:59 2007
@@ -837,27 +837,45 @@
 /// ParseDeclaratorInternal
 ///       declarator: [C99 6.7.5]
 ///         pointer[opt] direct-declarator
+/// [C++]   reference direct-declarator [C++ 8p4, dcl.decl]
 ///
 ///       pointer: [C99 6.7.5]
 ///         '*' type-qualifier-list[opt]
 ///         '*' type-qualifier-list[opt] pointer
 ///
+///       reference: [C++ 8p4, dcl.decl]
+/// [C++]   '&' declarator
+///
 void Parser::ParseDeclaratorInternal(Declarator &D) {
-  if (Tok.getKind() != tok::star)
+  tok::TokenKind Kind = Tok.getKind();
+
+  // Not a pointer or C++ reference.
+  if (Kind != tok::star && !(Kind == tok::amp && getLang().CPlusPlus))
     return ParseDirectDeclarator(D);
   
-  // Otherwise, '*' -> pointer.
-  SourceLocation Loc = ConsumeToken();  // Eat the *.
-  DeclSpec DS;
-  ParseTypeQualifierListOpt(DS);
+  // Otherwise, '*' -> pointer or '&' -> reference.
+  SourceLocation Loc = ConsumeToken();  // Eat the * or &.
+
+  if (Kind == tok::star) {
+    // Is a pointer
+    DeclSpec DS;
+    ParseTypeQualifierListOpt(DS);
   
-  // Recursively parse the declarator.
-  ParseDeclaratorInternal(D);
+    // Recursively parse the declarator.
+    ParseDeclaratorInternal(D);
 
-  // Remember that we parsed a pointer type, and remember the type-quals.
-  D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc));
-}
+    // Remember that we parsed a pointer type, and remember the type-quals.
+    D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc));
+  } else {
+    // Is a reference
+
+    // Recursively parse the declarator.
+    ParseDeclaratorInternal(D);
 
+    // Remember that we parsed a reference type. It doesn't have type-quals.
+    D.AddTypeInfo(DeclaratorChunk::getReference(Loc));
+  }
+}
 
 /// ParseDirectDeclarator
 ///       direct-declarator: [C99 6.7.5]

Modified: cfe/cfe/trunk/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaType.cpp?rev=39496&r1=39495&r2=39496&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaType.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaType.cpp Wed Jul 11 11:44:59 2007
@@ -121,6 +121,9 @@
       // Apply the pointer typequals to the pointer object.
       T = T.getQualifiedType(DeclType.Ptr.TypeQuals);
       break;
+    case DeclaratorChunk::Reference:
+      T = Context.getReferenceType(T);
+      break;
     case DeclaratorChunk::Array: {
       const DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
       ArrayType::ArraySizeModifier ASM;

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 11 11:44:59 2007
@@ -28,6 +28,7 @@
 class ASTContext {
   std::vector<Type*> Types;
   FoldingSet<PointerType> PointerTypes;
+  FoldingSet<ReferenceType> ReferenceTypes;
   FoldingSet<ArrayType> ArrayTypes;
   FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
   FoldingSet<FunctionTypeProto> FunctionTypeProtos;
@@ -57,6 +58,10 @@
   /// the specified type.
   QualType getPointerType(QualType T);
   
+  /// getReferenceType - Return the uniqued reference to the type for a
+  /// reference to the specified type.
+  QualType getReferenceType(QualType T);
+  
   /// getArrayType - Return the unique reference to the type for an array of the
   /// specified element type.
   QualType getArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM,

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:44:59 2007
@@ -96,7 +96,7 @@
   bool isRestrictQualified() const {
     return ThePtr & Restrict;
   }
-  
+
   QualType getQualifiedType(unsigned TQs) const {
     return QualType(getTypePtr(), TQs);
   }
@@ -172,7 +172,8 @@
 class Type {
 public:
   enum TypeClass {
-    Builtin, Pointer, Array, FunctionNoProto, FunctionProto, TypeName, Tagged
+    Builtin, Pointer, Reference, Array, FunctionNoProto, FunctionProto,
+    TypeName, Tagged
   };
 private:
   QualType CanonicalType;
@@ -221,6 +222,7 @@
   /// Derived types (C99 6.2.5p20). isFunctionType() is also a derived type.
   bool isDerivedType() const;
   bool isPointerType() const;
+  bool isReferenceType() const;
   bool isArrayType() const;
   bool isStructureType() const;   
   bool isUnionType() const;
@@ -302,7 +304,31 @@
   static bool classof(const PointerType *) { return true; }
 };
 
-/// PointerType - C99 6.7.5.2 - Array Declarators.
+/// ReferenceType - C++ 8.3.2 - Reference Declarators.
+///
+class ReferenceType : public Type, public FoldingSetNode {
+  QualType ReferenceeType;
+  ReferenceType(QualType Referencee, QualType CanonicalRef) :
+    Type(Reference, CanonicalRef), ReferenceeType(Referencee) {
+  }
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  virtual void getAsStringInternal(std::string &InnerString) const;
+
+  QualType getReferenceeType() const { return ReferenceeType; }
+
+  void Profile(FoldingSetNodeID &ID) {
+    Profile(ID, getReferenceeType());
+  }
+  static void Profile(FoldingSetNodeID &ID, QualType Referencee) {
+    ID.AddPointer(Referencee.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Reference; }
+  static bool classof(const ReferenceType *) { return true; }
+};
+
+/// ArrayType - C99 6.7.5.2 - Array Declarators.
 ///
 class ArrayType : public Type, public FoldingSetNode {
 public:

Modified: cfe/cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=39496&r1=39495&r2=39496&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jul 11 11:44:59 2007
@@ -240,7 +240,7 @@
 /// This is intended to be a small value object.
 struct DeclaratorChunk {
   enum {
-    Pointer, Array, Function
+    Pointer, Reference, Array, Function
   } Kind;
   
   /// Loc - The place where this type was defined.
@@ -251,6 +251,11 @@
     unsigned TypeQuals : 3;
     void destroy() {}
   };
+
+  struct ReferenceTypeInfo {
+    void destroy() {}
+  };
+
   struct ArrayTypeInfo {
     /// The type qualifiers for the array: const/volatile/restrict.
     unsigned TypeQuals : 3;
@@ -310,9 +315,10 @@
   };
   
   union {
-    PointerTypeInfo Ptr;
-    ArrayTypeInfo Arr;
-    FunctionTypeInfo Fun;
+    PointerTypeInfo   Ptr;
+    ReferenceTypeInfo Ref;
+    ArrayTypeInfo     Arr;
+    FunctionTypeInfo  Fun;
   };
   
   
@@ -326,6 +332,15 @@
     return I;
   }
   
+  /// getReference - Return a DeclaratorChunk for a reference.
+  ///
+  static DeclaratorChunk getReference(SourceLocation Loc) {
+    DeclaratorChunk I;
+    I.Kind          = Reference;
+    I.Loc           = Loc;
+    return I;
+  }
+  
   /// getArray - Return a DeclaratorChunk for an array.
   ///
   static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic,
@@ -424,6 +439,8 @@
         DeclTypeInfo[i].Fun.destroy();
       else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Pointer)
         DeclTypeInfo[i].Ptr.destroy();
+      else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Reference)
+        DeclTypeInfo[i].Ref.destroy();
       else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Array)
         DeclTypeInfo[i].Arr.destroy();
       else





More information about the cfe-commits mailing list