[cfe-commits] r132332 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp test/SemaCXX/MicrosoftExtensions.cpp

Francois Pichet pichet2000 at gmail.com
Tue May 31 04:44:00 PDT 2011


Author: fpichet
Date: Tue May 31 06:44:00 2011
New Revision: 132332

URL: http://llvm.org/viewvc/llvm-project?rev=132332&view=rev
Log:
For compatibility with MSVC, a friend declaration also act as a forward declaration if the tag name is not already declared. The tag name is declared in the next outermost non record scope.
Example:

class A {
  friend class B;
  B* b;
};
B* global_b;

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=132332&r1=132331&r2=132332&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue May 31 06:44:00 2011
@@ -1084,6 +1084,11 @@
                  bool &OwnedDecl, bool &IsDependent, bool ScopedEnum,
                  bool ScopedEnumUsesClassTag, TypeResult UnderlyingType);
 
+  void InjectMicrosoftFriendForwardDeclaration(unsigned TagSpec,
+                                               SourceLocation KWLoc,
+                                               IdentifierInfo *Name,
+                                               SourceLocation NameLoc);
+
   Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
                                 unsigned TagSpec, SourceLocation TagLoc,
                                 CXXScopeSpec &SS,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=132332&r1=132331&r2=132332&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue May 31 06:44:00 2011
@@ -6631,6 +6631,40 @@
   return false;
 }
 
+/// InjectMicrosoftFriendForwardDeclaration - For compatibility with MSVC,
+/// a friend declaration also act as a forward declaration if the tag name
+/// is not already declared. The tag name is declared in the next outermost
+/// non record scope.
+/// Example:
+///
+/// class A {
+///   friend class B;
+///   B* b;
+///  };
+///  B* global_b;
+ 
+void Sema::InjectMicrosoftFriendForwardDeclaration(unsigned TagSpec,
+                                                   SourceLocation KWLoc,
+                                                   IdentifierInfo *Name,
+                                                   SourceLocation NameLoc) {
+  NamedDecl *N = LookupSingleName(getCurScope(), Name, NameLoc,
+                                  Sema::LookupTagName);
+  if (!N) {
+    DeclContext *ContextToAdd = CurContext;
+    while (ContextToAdd->isRecord())
+      ContextToAdd = ContextToAdd->getParent();
+
+    TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
+    TagDecl *New = CXXRecordDecl::Create(Context, Kind, ContextToAdd, KWLoc,
+                                         NameLoc, Name, 0);
+    if (getCurScope()->getFnParent())
+      PushOnScopeChains(New, getScopeForContext(ContextToAdd), true);
+    else
+      ContextToAdd->addDecl(New);
+  } 
+}
+
+
 /// ActOnTag - 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.
 /// TagSpec indicates what kind of tag this is. TUK indicates whether this is a
@@ -6648,6 +6682,9 @@
          "Nameless record must be a definition!");
   assert(TemplateParameterLists.size() == 0 || TUK != TUK_Reference);
 
+  if (getLangOptions().Microsoft && TUK == Sema::TUK_Friend)
+    InjectMicrosoftFriendForwardDeclaration(TagSpec, KWLoc, Name, NameLoc);
+
   OwnedDecl = false;
   TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
 

Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=132332&r1=132331&r2=132332&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Tue May 31 06:44:00 2011
@@ -226,4 +226,29 @@
   using B::f; // expected-warning {{using declaration refers to inaccessible member 'ms_using_declaration_bug::B::f', which refers to accessible member 'ms_using_declaration_bug::A::f', accepted for Microsoft compatibility}}
 };
 
+}
+
+
+
+namespace friend_as_a_forward_decl {
+
+class A {
+  class Nested {
+    friend class B;
+    B* b;
+  };
+  B* b;
+};
+B* global_b;
+
+
+void f()
+{
+  class Local {
+    friend class Z;
+    Z* b;
+  };
+  Z* b;
+}
+
 }
\ No newline at end of file





More information about the cfe-commits mailing list