[cfe-commits] r68974 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/Frontend/PCHBitCodes.h include/clang/Frontend/PCHReader.h include/clang/Frontend/PCHWriter.h lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp test/PCH/enum.c test/PCH/enum.h

Douglas Gregor dgregor at apple.com
Mon Apr 13 11:14:40 PDT 2009


Author: dgregor
Date: Mon Apr 13 13:14:40 2009
New Revision: 68974

URL: http://llvm.org/viewvc/llvm-project?rev=68974&view=rev
Log:
Add PCH support for enumerations and enumerators.

Added:
    cfe/trunk/test/PCH/enum.c
    cfe/trunk/test/PCH/enum.h
Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/include/clang/Frontend/PCHReader.h
    cfe/trunk/include/clang/Frontend/PCHWriter.h
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Apr 13 13:14:40 2009
@@ -992,6 +992,8 @@
     return TagKind(TagDeclKind);
   }
 
+  void setTagKind(TagKind TK) { TagDeclKind = TK; }
+
   bool isStruct() const { return getTagKind() == TK_struct; }
   bool isClass()  const { return getTagKind() == TK_class; }
   bool isUnion()  const { return getTagKind() == TK_union; }
@@ -1013,7 +1015,6 @@
     return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
   }
 
-protected:
   void setDefinition(bool V) { IsDefinition = V; }
 };
 
@@ -1059,7 +1060,10 @@
   /// getIntegerType - Return the integer type this enum decl corresponds to.
   /// This returns a null qualtype for an enum forward definition.
   QualType getIntegerType() const { return IntegerType; }
-    
+
+  /// \brief Set the underlying integer type.
+  void setIntegerType(QualType T) { IntegerType = T; }
+
   static bool classof(const Decl *D) { return D->getKind() == Enum; }
   static bool classof(const EnumDecl *D) { return true; }
   

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=68974&r1=68973&r2=68974&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Mon Apr 13 13:14:40 2009
@@ -314,6 +314,10 @@
       DECL_TRANSLATION_UNIT = 1,
       /// \brief A TypedefDecl record.
       DECL_TYPEDEF,
+      /// \brief An EnumDecl record.
+      DECL_ENUM,
+      /// \brief An EnumConstantDecl record.
+      DECL_ENUM_CONSTANT,
       /// \brief A VarDecl record.
       DECL_VAR,
       /// \brief A record that stores the set of declarations that are

Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=68974&r1=68973&r2=68974&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHReader.h Mon Apr 13 13:14:40 2009
@@ -18,6 +18,8 @@
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
@@ -201,6 +203,12 @@
     return DecodeIdentifierInfo(Record[Idx++]);
   }
   DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read an integral value
+  llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a signed integral value
+  llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
 };
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=68974&r1=68973&r2=68974&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Mon Apr 13 13:14:40 2009
@@ -112,6 +112,9 @@
   /// \brief Emit an integral value.
   void AddAPInt(const llvm::APInt &Value, RecordData &Record);
 
+  /// \brief Emit a signed integral value.
+  void AddAPSInt(const llvm::APSInt &Value, RecordData &Record);
+
   /// \brief Emit a reference to an identifier
   void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record);
 

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=68974&r1=68973&r2=68974&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Mon Apr 13 13:14:40 2009
@@ -48,7 +48,10 @@
     void VisitNamedDecl(NamedDecl *ND);
     void VisitTypeDecl(TypeDecl *TD);
     void VisitTypedefDecl(TypedefDecl *TD);
+    void VisitTagDecl(TagDecl *TD);
+    void VisitEnumDecl(EnumDecl *ED);
     void VisitValueDecl(ValueDecl *VD);
+    void VisitEnumConstantDecl(EnumConstantDecl *ECD);
     void VisitVarDecl(VarDecl *VD);
 
     std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
@@ -86,11 +89,30 @@
   TD->setUnderlyingType(Reader.GetType(Record[Idx++]));
 }
 
+void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
+  VisitTypeDecl(TD);
+  TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
+  TD->setDefinition(Record[Idx++]);
+  TD->setTypedefForAnonDecl(
+                    cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {
+  VisitTagDecl(ED);
+  ED->setIntegerType(Reader.GetType(Record[Idx++]));
+}
+
 void PCHDeclReader::VisitValueDecl(ValueDecl *VD) {
   VisitNamedDecl(VD);
   VD->setType(Reader.GetType(Record[Idx++]));
 }
 
+void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
+  VisitValueDecl(ECD);
+  // FIXME: initialization expression
+  ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
+}
+
 void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
   VisitValueDecl(VD);
   VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]);
@@ -795,6 +817,10 @@
     return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr());
   }
 
+  case pch::TYPE_ENUM:
+    assert(Record.size() == 1 && "Incorrect encoding of enum type");
+    return Context.getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));
+
     // FIXME: Several other kinds of types to deserialize here!
   default:
     assert(false && "Unable to deserialize this type");
@@ -842,6 +868,25 @@
     break;
   }
 
+  case pch::DECL_ENUM: {
+    EnumDecl *Enum = EnumDecl::Create(Context, 0, SourceLocation(), 0, 0);
+    LoadedDecl(Index, Enum);
+    Reader.VisitEnumDecl(Enum);
+    D = Enum;
+    break;
+  }
+
+  case pch::DECL_ENUM_CONSTANT: {
+    EnumConstantDecl *ECD = EnumConstantDecl::Create(Context, 0, 
+                                                     SourceLocation(), 0,
+                                                     QualType(), 0,
+                                                     llvm::APSInt());
+    LoadedDecl(Index, ECD);
+    Reader.VisitEnumConstantDecl(ECD);
+    D = ECD;
+    break;
+  }
+
   case pch::DECL_VAR: {
     VarDecl *Var = VarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
                                    VarDecl::None, SourceLocation());
@@ -1064,6 +1109,21 @@
   return DeclarationName();
 }
 
+/// \brief Read an integral value
+llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
+  unsigned BitWidth = Record[Idx++];
+  unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
+  llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
+  Idx += NumWords;
+  return Result;
+}
+
+/// \brief Read a signed integral value
+llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
+  bool isUnsigned = Record[Idx++];
+  return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
+}
+
 DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
   return Diag(SourceLocation(), DiagID);
 }

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=68974&r1=68973&r2=68974&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Mon Apr 13 13:14:40 2009
@@ -252,9 +252,11 @@
     void VisitNamedDecl(NamedDecl *D);
     void VisitTypeDecl(TypeDecl *D);
     void VisitTypedefDecl(TypedefDecl *D);
+    void VisitTagDecl(TagDecl *D);
+    void VisitEnumDecl(EnumDecl *D);
     void VisitValueDecl(ValueDecl *D);
+    void VisitEnumConstantDecl(EnumConstantDecl *D);
     void VisitVarDecl(VarDecl *D);
-
     void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, 
                           uint64_t VisibleOffset);
   };
@@ -291,11 +293,31 @@
   Code = pch::DECL_TYPEDEF;
 }
 
+void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
+  VisitTypeDecl(D);
+  Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
+  Record.push_back(D->isDefinition());
+  Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);
+}
+
+void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) {
+  VisitTagDecl(D);
+  Writer.AddTypeRef(D->getIntegerType(), Record);
+  Code = pch::DECL_ENUM;
+}
+
 void PCHDeclWriter::VisitValueDecl(ValueDecl *D) {
   VisitNamedDecl(D);
   Writer.AddTypeRef(D->getType(), Record);
 }
 
+void PCHDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
+  VisitValueDecl(D);
+  // FIXME: Writer.AddExprRef(D->getInitExpr());
+  Writer.AddAPSInt(D->getInitVal(), Record);
+  Code = pch::DECL_ENUM_CONSTANT;
+}
+
 void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
   VisitValueDecl(D);
   Record.push_back(D->getStorageClass());
@@ -935,6 +957,11 @@
     Record.push_back(Words[I]);
 }
 
+void PCHWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) {
+  Record.push_back(Value.isUnsigned());
+  AddAPInt(Value, Record);
+}
+
 void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
   if (II == 0) {
     Record.push_back(0);

Added: cfe/trunk/test/PCH/enum.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/enum.c?rev=68974&view=auto

==============================================================================
--- cfe/trunk/test/PCH/enum.c (added)
+++ cfe/trunk/test/PCH/enum.c Mon Apr 13 13:14:40 2009
@@ -0,0 +1,15 @@
+// Test this without pch.
+// RUN: clang-cc -triple=i686-apple-darwin9 -include %S/enum.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: clang-cc -emit-pch -triple=i686-apple-darwin9 -o %t %S/enum.h &&
+// RUN: clang-cc -triple=i686-apple-darwin9 -include-pch %t -fsyntax-only -verify %s 
+
+int i = Red;
+
+int return_enum_constant() {
+  int result = aRoundShape;
+  return result;
+}
+
+enum Shape s = Triangle;

Added: cfe/trunk/test/PCH/enum.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/enum.h?rev=68974&view=auto

==============================================================================
--- cfe/trunk/test/PCH/enum.h (added)
+++ cfe/trunk/test/PCH/enum.h Mon Apr 13 13:14:40 2009
@@ -0,0 +1,16 @@
+/* Used in enum.c test */
+
+enum Color {
+  Red,
+  Green,
+  Blue
+};
+
+enum Shape {
+  Square,
+  Triangle,
+  Rhombus,
+  Circle
+};
+
+enum Shape aRoundShape = Circle;





More information about the cfe-commits mailing list