[cfe-commits] r39265 - in /cfe/cfe/trunk: AST/SemaDecl.cpp Sema/SemaDecl.cpp

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:42:10 PDT 2007


Author: sabre
Date: Wed Jul 11 11:42:10 2007
New Revision: 39265

URL: http://llvm.org/viewvc/llvm-project?rev=39265&view=rev
Log:
Make name lookup properly obey C namespaces, simplify decl construction by
eliminating the 'next' pointer from the ctor, and add initial support for
parsing struct/union tags.

Modified:
    cfe/cfe/trunk/AST/SemaDecl.cpp
    cfe/cfe/trunk/Sema/SemaDecl.cpp

Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39265&r1=39264&r2=39265&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:42:10 2007
@@ -62,15 +62,27 @@
   return 0;
 }
 
+/// LookupScopedDecl - Look up the inner-most declaration in the specified
+/// namespace.
+static Decl *LookupScopedDecl(IdentifierInfo *II, Decl::IdentifierNamespace NS){
+  if (II == 0) return 0;
+  
+  // Scan up the scope chain looking for a decl that matches this identifier
+  // that is in the appropriate namespace.  This search should not take long, as
+  // shadowing of names is uncommon, and deep shadowing is extremely uncommon.
+  for (Decl *D = II->getFETokenInfo<Decl>(); D; D = D->getNext())
+    if (D->getIdentifierNamespace() == NS)
+      return D;
+  return 0;
+}
+
+
 Action::DeclTy *
 Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init, 
                       DeclTy *LastInGroup) {
   IdentifierInfo *II = D.getIdentifier();
-  Decl *PrevDecl = 0;
   
-  if (II)
-    PrevDecl = II->getFETokenInfo<Decl>();
-  if (PrevDecl) {
+  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
     // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
     if (S->isDeclScope(PrevDecl)) {
       // TODO: This is totally simplistic.  It should handle merging functions
@@ -82,20 +94,18 @@
   
   Decl *New;
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
-    New = ParseTypedefDecl(S, D, PrevDecl);
+    New = ParseTypedefDecl(S, D);
   else if (D.isFunctionDeclarator())
-    New = new FunctionDecl(D.getIdentifierLoc(), II, GetTypeForDeclarator(D, S),
-                           PrevDecl);
+    New = new FunctionDecl(D.getIdentifierLoc(), II, GetTypeForDeclarator(D,S));
   else
-    New = new VarDecl(D.getIdentifierLoc(), II, GetTypeForDeclarator(D, S),
-                      PrevDecl);
+    New = new VarDecl(D.getIdentifierLoc(), II, GetTypeForDeclarator(D, S));
   
   if (!New) return 0;
   
   
   // If this has an identifier, add it to the scope stack.
   if (II) {
-    // If PrevDecl includes conflicting name here, emit a diagnostic.
+    New->setNext(II->getFETokenInfo<Decl>());
     II->setFETokenInfo(New);
     S->AddDecl(New);
   }
@@ -114,21 +124,17 @@
   const DeclaratorChunk::ParamInfo &PI = FTI.Fun.ArgInfo[ArgNo];
 
   IdentifierInfo *II = PI.Ident;
-  Decl *PrevDecl = 0;
   
-  if (II)
-    PrevDecl = II->getFETokenInfo<Decl>();
-  if (PrevDecl) {
+  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
     
     // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
   }
   
-  VarDecl *New = new VarDecl(PI.IdentLoc, II, static_cast<Type*>(PI.TypeInfo),
-                             PrevDecl);
+  VarDecl *New = new VarDecl(PI.IdentLoc, II, static_cast<Type*>(PI.TypeInfo));
   
   // If this has an identifier, add it to the scope stack.
   if (II) {
-    // If PrevDecl includes conflicting name here, emit a diagnostic.
+    New->setNext(II->getFETokenInfo<Decl>());
     II->setFETokenInfo(New);
     FnScope->AddDecl(New);
   }
@@ -228,12 +234,44 @@
 }
 
 
-Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, Decl *PrevDecl) {
+Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
   assert(D.getIdentifier() && "Wrong callback for declspec withotu declarator");
   
   TypeRef T = GetTypeForDeclarator(D, S);
   if (T.isNull()) return 0;
   
-  return new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), T, PrevDecl);
+  // Scope manipulation handled by caller.
+  return new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), T);
 }
 
+
+/// ParseStructUnionTag - This is invoked when we see 'struct foo' or
+/// 'struct {'.  In the former case, Name will be non-null.  In the later case,
+/// Name will be null.  isUnion indicates whether this is a union or struct tag.
+Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion,
+                                        SourceLocation KWLoc, 
+                                        IdentifierInfo *Name,
+                                        SourceLocation NameLoc) {
+  // If this is a named struct, check to see if there was a previous forward
+  // declaration or definition.
+  if (Decl *PrevDecl = LookupScopedDecl(Name, Decl::IDNS_Tag)) {
+    // TODO: verify it's struct/union, etc.
+  }
+  
+  // If there is an identifier, use the location of the identifier as the
+  // location of the decl, otherwise use the location of the struct/union
+  // keyword.
+  SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
+  
+  // Otherwise, if this is the first time we've seen this tag, create the decl.
+  Decl *New = new RecordDecl(isUnion ? Decl::Union : Decl::Struct, Loc, Name);
+  
+  // If this has an identifier, add it to the scope stack.
+  if (Name) {
+    New->setNext(Name->getFETokenInfo<Decl>());
+    Name->setFETokenInfo(New);
+    S->AddDecl(New);
+  }
+  
+  return New;
+}

Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39265&r1=39264&r2=39265&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:42:10 2007
@@ -62,15 +62,27 @@
   return 0;
 }
 
+/// LookupScopedDecl - Look up the inner-most declaration in the specified
+/// namespace.
+static Decl *LookupScopedDecl(IdentifierInfo *II, Decl::IdentifierNamespace NS){
+  if (II == 0) return 0;
+  
+  // Scan up the scope chain looking for a decl that matches this identifier
+  // that is in the appropriate namespace.  This search should not take long, as
+  // shadowing of names is uncommon, and deep shadowing is extremely uncommon.
+  for (Decl *D = II->getFETokenInfo<Decl>(); D; D = D->getNext())
+    if (D->getIdentifierNamespace() == NS)
+      return D;
+  return 0;
+}
+
+
 Action::DeclTy *
 Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init, 
                       DeclTy *LastInGroup) {
   IdentifierInfo *II = D.getIdentifier();
-  Decl *PrevDecl = 0;
   
-  if (II)
-    PrevDecl = II->getFETokenInfo<Decl>();
-  if (PrevDecl) {
+  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
     // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
     if (S->isDeclScope(PrevDecl)) {
       // TODO: This is totally simplistic.  It should handle merging functions
@@ -82,20 +94,18 @@
   
   Decl *New;
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
-    New = ParseTypedefDecl(S, D, PrevDecl);
+    New = ParseTypedefDecl(S, D);
   else if (D.isFunctionDeclarator())
-    New = new FunctionDecl(D.getIdentifierLoc(), II, GetTypeForDeclarator(D, S),
-                           PrevDecl);
+    New = new FunctionDecl(D.getIdentifierLoc(), II, GetTypeForDeclarator(D,S));
   else
-    New = new VarDecl(D.getIdentifierLoc(), II, GetTypeForDeclarator(D, S),
-                      PrevDecl);
+    New = new VarDecl(D.getIdentifierLoc(), II, GetTypeForDeclarator(D, S));
   
   if (!New) return 0;
   
   
   // If this has an identifier, add it to the scope stack.
   if (II) {
-    // If PrevDecl includes conflicting name here, emit a diagnostic.
+    New->setNext(II->getFETokenInfo<Decl>());
     II->setFETokenInfo(New);
     S->AddDecl(New);
   }
@@ -114,21 +124,17 @@
   const DeclaratorChunk::ParamInfo &PI = FTI.Fun.ArgInfo[ArgNo];
 
   IdentifierInfo *II = PI.Ident;
-  Decl *PrevDecl = 0;
   
-  if (II)
-    PrevDecl = II->getFETokenInfo<Decl>();
-  if (PrevDecl) {
+  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
     
     // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
   }
   
-  VarDecl *New = new VarDecl(PI.IdentLoc, II, static_cast<Type*>(PI.TypeInfo),
-                             PrevDecl);
+  VarDecl *New = new VarDecl(PI.IdentLoc, II, static_cast<Type*>(PI.TypeInfo));
   
   // If this has an identifier, add it to the scope stack.
   if (II) {
-    // If PrevDecl includes conflicting name here, emit a diagnostic.
+    New->setNext(II->getFETokenInfo<Decl>());
     II->setFETokenInfo(New);
     FnScope->AddDecl(New);
   }
@@ -228,12 +234,44 @@
 }
 
 
-Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, Decl *PrevDecl) {
+Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
   assert(D.getIdentifier() && "Wrong callback for declspec withotu declarator");
   
   TypeRef T = GetTypeForDeclarator(D, S);
   if (T.isNull()) return 0;
   
-  return new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), T, PrevDecl);
+  // Scope manipulation handled by caller.
+  return new TypedefDecl(D.getIdentifierLoc(), D.getIdentifier(), T);
 }
 
+
+/// ParseStructUnionTag - This is invoked when we see 'struct foo' or
+/// 'struct {'.  In the former case, Name will be non-null.  In the later case,
+/// Name will be null.  isUnion indicates whether this is a union or struct tag.
+Sema::DeclTy *Sema::ParseStructUnionTag(Scope *S, bool isUnion,
+                                        SourceLocation KWLoc, 
+                                        IdentifierInfo *Name,
+                                        SourceLocation NameLoc) {
+  // If this is a named struct, check to see if there was a previous forward
+  // declaration or definition.
+  if (Decl *PrevDecl = LookupScopedDecl(Name, Decl::IDNS_Tag)) {
+    // TODO: verify it's struct/union, etc.
+  }
+  
+  // If there is an identifier, use the location of the identifier as the
+  // location of the decl, otherwise use the location of the struct/union
+  // keyword.
+  SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
+  
+  // Otherwise, if this is the first time we've seen this tag, create the decl.
+  Decl *New = new RecordDecl(isUnion ? Decl::Union : Decl::Struct, Loc, Name);
+  
+  // If this has an identifier, add it to the scope stack.
+  if (Name) {
+    New->setNext(Name->getFETokenInfo<Decl>());
+    Name->setFETokenInfo(New);
+    S->AddDecl(New);
+  }
+  
+  return New;
+}





More information about the cfe-commits mailing list