[cfe-commits] r72599 - /cfe/trunk/lib/AST/StmtPrinter.cpp

Eli Friedman eli.friedman at gmail.com
Fri May 29 17:19:57 PDT 2009


Author: efriedma
Date: Fri May 29 19:19:54 2009
New Revision: 72599

URL: http://llvm.org/viewvc/llvm-project?rev=72599&view=rev
Log:
Some enhancements to DeclStmt printing.  Some of this should 
move to DeclPrinter.cpp, but I haven't quite worked out how best to do 
that.


Modified:
    cfe/trunk/lib/AST/StmtPrinter.cpp

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

==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Fri May 29 19:19:54 2009
@@ -56,11 +56,15 @@
       }
       IndentLevel -= SubIndent;
     }
-    
+
+    QualType GetBaseType(QualType T);
+    void PrintBaseType(QualType T, TagDecl* TD);
+    void PrintDeclIdentifier(NamedDecl* ND);
     void PrintRawCompoundStmt(CompoundStmt *S);
     void PrintRawDecl(Decl *D);
     void PrintRawDeclStmt(DeclStmt *S);
     void PrintFieldDecl(FieldDecl *FD);
+    void PrintEnumConstantDecl(EnumConstantDecl *ECD);
     void PrintRawIfStmt(IfStmt *If);
     void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
     
@@ -112,6 +116,57 @@
   Indent() << "}";
 }
 
+QualType StmtPrinter::GetBaseType(QualType T) {
+  // FIXME: This should be on the Type class!
+  QualType BaseType = T;
+  while (!BaseType->isSpecifierType()) {
+    if (isa<TypedefType>(BaseType))
+      break;
+    else if (const PointerType* PTy = BaseType->getAsPointerType())
+      BaseType = PTy->getPointeeType();
+    else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
+      BaseType = ATy->getElementType();
+    else if (const FunctionType* FTy = BaseType->getAsFunctionType())
+      BaseType = FTy->getResultType();
+    else
+      assert(0 && "Unknown declarator!");
+  }
+  return BaseType;
+}
+
+void StmtPrinter::PrintBaseType(QualType BaseType, TagDecl* TD) {
+  std::string BaseString;
+  if (TD && TD->isDefinition()) {
+    // FIXME: This is an ugly hack; perhaps we can expose something better
+    // from Type.h?
+    if (BaseType.isConstQualified())
+      OS << "const ";
+    PrintRawDecl(TD);
+    OS << " ";
+  } else {
+    BaseType.getAsStringInternal(BaseString, Policy);
+    OS << BaseString << " ";
+  }
+}
+
+void StmtPrinter::PrintDeclIdentifier(NamedDecl* ND) {
+  std::string Name = ND->getNameAsString();
+
+  QualType Ty;
+  if (TypedefDecl* TDD = dyn_cast<TypedefDecl>(ND)) {
+    Ty = TDD->getUnderlyingType();
+  } else if (ValueDecl* VD = dyn_cast<ValueDecl>(ND)) {
+    Ty = VD->getType();
+  } else {
+    assert(0 && "Unexpected decl");
+  }
+
+  PrintingPolicy SubPolicy(Policy);
+  SubPolicy.SuppressTypeSpecifiers = true;
+  Ty.getAsStringInternal(Name, SubPolicy);
+  OS << Name;
+}
+
 void StmtPrinter::PrintRawDecl(Decl *D) {
   // FIXME: Need to complete/beautify this... this code simply shows the
   // nodes are where they need to be.
@@ -143,16 +198,28 @@
     OS << " ";
     if (const IdentifierInfo *II = TD->getIdentifier())
       OS << II->getName();
-    if (RecordDecl *RD = dyn_cast<RecordDecl>(TD)) {
-      OS << "{\n";
-      IndentLevel += 1;
-      // FIXME: The context passed to field_begin/field_end should
-      // never be NULL!
-      ASTContext *Context = 0;
-      for (RecordDecl::field_iterator i = RD->field_begin(*Context);
-           i != RD->field_end(*Context); ++i) {
-        PrintFieldDecl(*i);
-      IndentLevel -= 1;
+    if (TD->isDefinition()) {
+      if (RecordDecl *RD = dyn_cast<RecordDecl>(TD)) {
+        OS << "{\n";
+        IndentLevel += 1;
+        // FIXME: The context passed to field_begin/field_end should
+        // never be NULL!
+        ASTContext *Context = 0;
+        for (RecordDecl::field_iterator i = RD->field_begin(*Context);
+             i != RD->field_end(*Context); ++i)
+          PrintFieldDecl(*i);
+        IndentLevel -= 1;
+        Indent() << "}";
+      } else if (EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
+        OS << "{\n";
+        IndentLevel += 1;
+        // FIXME: The context shouldn't be NULL!
+        ASTContext *Context = 0;
+        for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(*Context);
+             i != ED->enumerator_end(*Context); ++i)
+          PrintEnumConstantDecl(*i);
+        IndentLevel -= 1;
+        Indent() << "}";
       }
     }
   } else {
@@ -161,19 +228,72 @@
 }
 
 void StmtPrinter::PrintFieldDecl(FieldDecl *FD) {
-  Indent() << FD->getNameAsString() << "\n";
+  Indent();
+  QualType BaseType = GetBaseType(FD->getType());
+  PrintBaseType(BaseType, 0);
+  PrintDeclIdentifier(FD);
+  if (FD->isBitField()) {
+    OS << " : ";
+    PrintExpr(FD->getBitWidth());
+  }
+  OS << ";\n";
+}
+
+void StmtPrinter::PrintEnumConstantDecl(EnumConstantDecl *ECD) {
+  Indent() << ECD->getNameAsString();
+  if (ECD->getInitExpr()) {
+    OS << " = ";
+    PrintExpr(ECD->getInitExpr());
+  }
+  OS << ",\n";
 }
 
 void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
+  DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
+
+  TagDecl* TD = dyn_cast<TagDecl>(*Begin);
+  if (TD)
+    ++Begin;
+
+  if (isa<TypedefDecl>(*Begin))
+    OS << "typedef ";
+  else if (VarDecl *V = dyn_cast<VarDecl>(*Begin)) {
+    switch (V->getStorageClass()) {
+    default: assert(0 && "Unknown storage class!");
+    case VarDecl::None:          break;
+    case VarDecl::Auto:          OS << "auto "; break;
+    case VarDecl::Register:      OS << "register "; break;
+    case VarDecl::Extern:        OS << "extern "; break;
+    case VarDecl::Static:        OS << "static "; break; 
+    case VarDecl::PrivateExtern: OS << "__private_extern__ "; break; 
+    }
+  } else if (FunctionDecl *V = dyn_cast<FunctionDecl>(*Begin)) {
+    switch (V->getStorageClass()) {
+    default: assert(0 && "Unknown storage class!");
+    case FunctionDecl::None:          break;
+    case FunctionDecl::Extern:        OS << "extern "; break;
+    case FunctionDecl::Static:        OS << "static "; break; 
+    case FunctionDecl::PrivateExtern: OS << "__private_extern__ "; break; 
+    }
+  } else {
+    assert(0 && "Unhandled decl");
+  }
+
+  QualType BaseType;
+  if (ValueDecl* VD = dyn_cast<ValueDecl>(*Begin)) {
+    BaseType = VD->getType();
+  } else {
+    BaseType = cast<TypedefDecl>(*Begin)->getUnderlyingType();
+  }
+  BaseType = GetBaseType(BaseType);
+  PrintBaseType(BaseType, TD);
+
   bool isFirst = true;
-  
-  for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
-       I != E; ++I) {
-    
+  for ( ; Begin != End; ++Begin) {
     if (!isFirst) OS << ", ";
     else isFirst = false;
-    
-    PrintRawDecl(*I);
+
+    PrintDeclIdentifier(cast<NamedDecl>(*Begin));
   }
 }
 
@@ -182,12 +302,9 @@
 }
 
 void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
-  for (DeclStmt::decl_iterator I = Node->decl_begin(), E = Node->decl_end();
-       I!=E; ++I) {    
-    Indent();
-    PrintRawDecl(*I);
-    OS << ";\n";
-  }
+  Indent();
+  PrintRawDeclStmt(Node);
+  OS << ";\n";
 }
 
 void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {





More information about the cfe-commits mailing list