I've tried to incorporate both Chris and your suggestions.

Kevin

Eli Friedman wrote:
On Mon, Feb 25, 2008 at 11:32 AM, Kevin Tew <[EMAIL PROTECTED]> wrote:
I've gotten serious and have written some code.

 Following the clang web page's advice, I've tried to start implementing
 c++ namespaces.
 Currently, I'm trying to figure out how to add namespace members to my
 NamespaceDecl.

Hmm, not a bad start.  A couple of comments from reading your patch.
First, make sure you don't go over 80 characters per line.  Second, I
don't think that making NamespaceDecl a subclass of RecordDecl really
makes sense: a namespace doesn't have members in the same sense that a
class or struct does.  Maybe make it a direct subclass of ScopedDecl?
Also, a few more tests might be appropriate.

Doesn't necessarily need to be done in this patch, but it would be
nice if the places that print out namespaced identifiers (like dump()
and related) would print out the associated namespace, so that things
don't get so confusing.

Also, here's a testcase which I'm not sure your patch handles:
namespace a { double i; }
int i;
namespace a {double* j = &i;}
should not print a warning with -pedantic.

I can't really come up with any other tests that have to do with
namespaces in particular... namespaces are pretty simple without
"using" and the :: operator.

-Eli

Index: test/Parser/cxx-namespace.cpp
===================================================================
--- test/Parser/cxx-namespace.cpp	(revision 0)
+++ test/Parser/cxx-namespace.cpp	(revision 0)
@@ -0,0 +1,13 @@
+// RUN: clang -fsyntax-only -verify %s
+int intone;
+namespace one {
+  namespace two {
+    namespace three {
+      int intone;
+    }
+  }
+}
+
+namespace a { double i; }
+int i;
+namespace a {double* j = &i;}
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h	(revision 47574)
+++ include/clang/AST/Decl.h	(working copy)
@@ -60,6 +60,7 @@
     //           RecordDecl,
                    Struct,
                    Union,
+                   Namespace,
                    Class,
     //       ValueDecl
                EnumConstant,
@@ -771,6 +772,19 @@
   friend Decl* Decl::Create(llvm::Deserializer& D);
 };
 
+/// NamespaceDecl - Represents a cxx namespace .  For example:
+//.   namespace X { };
+/// This decl will be marked invalid if *any* members are invalid.
+///
+class NamespaceDecl : public ScopedDecl {
+
+public:
+  NamespaceDecl(SourceLocation L, IdentifierInfo *Id, ScopedDecl*PrevDecl)
+    : ScopedDecl(Decl::Namespace, L, Id, PrevDecl) {
+    assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
+  }
+};
+
 class FileScopeAsmDecl : public Decl {
   StringLiteral *AsmString;
 public:
Index: include/clang/Parse/Action.h
===================================================================
--- include/clang/Parse/Action.h	(revision 47574)
+++ include/clang/Parse/Action.h	(working copy)
@@ -122,6 +122,16 @@
   virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
     return Group;
   }
+  
+  virtual DeclTy *ActOnStartOfNamespace(Scope *NamespaceScope, 
+                                        SourceLocation NameLoc, 
+                                        IdentifierInfo *Name, DeclTy *Attr) {
+    return 0;
+  }
+  
+  virtual DeclTy *ActOnFinishNamespace(DeclTy *Decl) {
+    return Decl;
+  }
 
   /// ActOnStartOfFunctionDef - This is called at the start of a function
   /// definition, instead of calling ActOnDeclarator.  The Declarator includes
@@ -303,7 +313,7 @@
     return 0;
   }
   virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
-                                  bool IsSimple,                                  
+                                  bool IsSimple,
                                   bool IsVolatile,
                                   unsigned NumOutputs,
                                   unsigned NumInputs,
Index: Sema/Sema.h
===================================================================
--- Sema/Sema.h	(revision 47574)
+++ Sema/Sema.h	(working copy)
@@ -195,6 +195,9 @@
 
   virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
   virtual void ObjCActOnStartOfMethodDef(Scope *S, DeclTy *D);
+  virtual DeclTy *ActOnStartOfNamespace(Scope *NamespaceScope, 
+                                        SourceLocation NameLoc,
+                                        IdentifierInfo *Name, DeclTy *Attr);
   
   virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtTy *Body);
   virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
@@ -256,7 +259,7 @@
   /// The raw attribute contains 1 argument, the id of the address space 
   /// for the type.
   QualType HandleAddressSpaceTypeAttribute(QualType curType, 
-                                           AttributeList *rawAttr);                                
+                                           AttributeList *rawAttr);
 
   // HandleVectorTypeAttribute - this attribute is only applicable to 
   // integral and float scalars, although arrays, pointers, and function
@@ -775,7 +778,7 @@
   // returns true if the cast is invalid
   bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty);
   
-  // returns true if there were any incompatible arguments.                           
+  // returns true if there were any incompatible arguments.
   bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
                                  ObjCMethodDecl *Method);
                     
Index: Sema/SemaDecl.cpp
===================================================================
--- Sema/SemaDecl.cpp	(revision 47574)
+++ Sema/SemaDecl.cpp	(working copy)
@@ -1972,3 +1972,11 @@
 
   d->addAttr(new AlignedAttr(Align));
 }
+
+Sema::DeclTy *Sema::ActOnStartOfNamespace(Scope *NamespaceScope, 
+                                          SourceLocation NameLoc, 
+                                          IdentifierInfo *Name, DeclTy *Attr) {
+  NamespaceDecl* ND = new NamespaceDecl(NameLoc, Name, 0);
+  return ND;
+}
+
Index: AST/Decl.cpp
===================================================================
--- AST/Decl.cpp	(revision 47574)
+++ AST/Decl.cpp	(working copy)
@@ -28,6 +28,7 @@
 static unsigned nEnumConst = 0;
 static unsigned nEnumDecls = 0;
 static unsigned nTypedef = 0;
+static unsigned nNamespace = 0;
 static unsigned nFieldDecls = 0;
 static unsigned nInterfaceDecls = 0;
 static unsigned nClassDecls = 0;
@@ -186,6 +187,9 @@
 
 void Decl::addDeclKind(const Kind k) {
   switch (k) {
+    case Namespace:
+      nNamespace++;
+      break;
     case Typedef:
       nTypedef++;
       break;
Index: Driver/ASTConsumers.cpp
===================================================================
--- Driver/ASTConsumers.cpp	(revision 47574)
+++ Driver/ASTConsumers.cpp	(working copy)
@@ -40,6 +40,7 @@
     void PrintDecl(Decl *D);
     void PrintFunctionDeclStart(FunctionDecl *FD);    
     void PrintTypeDefDecl(TypedefDecl *TD);    
+    void PrintNamespaceDecl(NamespaceDecl *ND);    
     void PrintLinkageSpec(LinkageSpecDecl *LS);
     void PrintObjCMethodDecl(ObjCMethodDecl *OMD);    
     void PrintObjCImplementationDecl(ObjCImplementationDecl *OID);
@@ -92,6 +93,9 @@
     PrintObjCCompatibleAliasDecl(OID);
   } else if (isa<ObjCClassDecl>(D)) {
     Out << "@class [printing todo]\n";
+  } else if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D)) {
+    Out << "Read top-level tag decl: '" << ND->getName() << "'\n";
+    PrintNamespaceDecl(ND);
   } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
     Out << "Read top-level tag decl: '" << TD->getName() << "'\n";
   } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
@@ -160,6 +164,12 @@
   Out << "typedef " << S << ";\n";
 }
 
+void DeclPrinter::PrintNamespaceDecl(NamespaceDecl *ND) {
+  std::string S = ND->getName();
+  //ND->getUnderlyingType().getAsStringInternal(S);
+  Out << "namespace " << S << ";\n";
+}
+
 void DeclPrinter::PrintLinkageSpec(LinkageSpecDecl *LS) {
   const char *l;
   if (LS->getLanguage() == LinkageSpecDecl::lang_c)
Index: Parse/ParseDeclCXX.cpp
===================================================================
--- Parse/ParseDeclCXX.cpp	(revision 47574)
+++ Parse/ParseDeclCXX.cpp	(working copy)
@@ -62,6 +62,9 @@
     // FIXME: parse this.
   } else if (Tok.is(tok::l_brace)) {
     SourceLocation LBrace = ConsumeBrace();
+    EnterScope(Scope::DeclScope);
+    DeclTy *Res = Actions.ActOnStartOfNamespace(CurScope, IdentLoc, Ident,
+                                                AttrList);
     // FIXME: push a scope, push a namespace decl.
     
     while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
@@ -70,8 +73,11 @@
     }
     
     SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
-    
+    ExitScope();
+   
     // FIXME: act on this.
+    Actions.ActOnFinishNamespace(Res);
+    return Res;
   } else {
     unsigned D = Ident ? diag::err_expected_lbrace : 
                          diag::err_expected_ident_lbrace;
_______________________________________________
cfe-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

Reply via email to