[cfe-commits] r99525 - in /cfe/trunk: include/clang/AST/DeclFriend.h include/clang/AST/DeclTemplate.h lib/Sema/SemaAccess.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp

John McCall rjmccall at apple.com
Thu Mar 25 11:04:52 PDT 2010


Author: rjmccall
Date: Thu Mar 25 13:04:51 2010
New Revision: 99525

URL: http://llvm.org/viewvc/llvm-project?rev=99525&view=rev
Log:
Preserve type-source information in friend declarations.


Modified:
    cfe/trunk/include/clang/AST/DeclFriend.h
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/Sema/SemaAccess.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclFriend.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclFriend.h?rev=99525&r1=99524&r2=99525&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclFriend.h (original)
+++ cfe/trunk/include/clang/AST/DeclFriend.h Thu Mar 25 13:04:51 2010
@@ -36,7 +36,7 @@
 /// The semantic context of a friend decl is its declaring class.
 class FriendDecl : public Decl {
 public:
-  typedef llvm::PointerUnion<NamedDecl*,Type*> FriendUnion;
+  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
 
 private:
   // The declaration that's a friend of this class.
@@ -73,8 +73,8 @@
   /// possibly dependent) type, return the type;  otherwise
   /// return null.  This is used only for C++0x's unelaborated
   /// friend type declarations.
-  Type *getFriendType() const {
-    return Friend.dyn_cast<Type*>();
+  TypeSourceInfo *getFriendType() const {
+    return Friend.dyn_cast<TypeSourceInfo*>();
   }
 
   /// If this friend declaration doesn't name an unelaborated

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=99525&r1=99524&r2=99525&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Thu Mar 25 13:04:51 2010
@@ -1238,7 +1238,7 @@
 ///   template <typename U> friend class Foo<T>::Nested; // friend template
 class FriendTemplateDecl : public Decl {
 public:
-  typedef llvm::PointerUnion<NamedDecl*,Type*> FriendUnion;
+  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
 
 private:
   // The number of template parameters;  always non-zero.
@@ -1277,8 +1277,8 @@
   /// If this friend declaration names a templated type (or
   /// a dependent member type of a templated type), return that
   /// type;  otherwise return null.
-  Type *getFriendType() const {
-    return Friend.dyn_cast<Type*>();
+  TypeSourceInfo *getFriendType() const {
+    return Friend.dyn_cast<TypeSourceInfo*>();
   }
 
   /// If this friend declaration names a templated function (or

Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=99525&r1=99524&r2=99525&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAccess.cpp Thu Mar 25 13:04:51 2010
@@ -330,8 +330,8 @@
 static Sema::AccessResult MatchesFriend(Sema &S,
                                         const EffectiveContext &EC,
                                         FriendDecl *FriendD) {
-  if (Type *T = FriendD->getFriendType())
-    return MatchesFriend(S, EC, T->getCanonicalTypeUnqualified());
+  if (TypeSourceInfo *T = FriendD->getFriendType())
+    return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
 
   NamedDecl *Friend
     = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=99525&r1=99524&r2=99525&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Mar 25 13:04:51 2010
@@ -5372,7 +5372,8 @@
   // friend templates because ActOnTag never produces a ClassTemplateDecl
   // for a TUK_Friend.
   Declarator TheDeclarator(DS, Declarator::MemberContext);
-  QualType T = GetTypeForDeclarator(TheDeclarator, S);
+  TypeSourceInfo *TSI;
+  QualType T = GetTypeForDeclarator(TheDeclarator, S, &TSI);
   if (TheDeclarator.isInvalidType())
     return DeclPtrTy();
 
@@ -5437,16 +5438,20 @@
   // deadline.  It's also a very silly restriction that seriously
   // affects inner classes and which nobody else seems to implement;
   // thus we never diagnose it, not even in -pedantic.
+  //
+  // But note that we could warn about it: it's always useless to
+  // friend one of your own members (it's not, however, worthless to
+  // friend a member of an arbitrary specialization of your template).
 
   Decl *D;
   if (TempParams.size())
     D = FriendTemplateDecl::Create(Context, CurContext, Loc,
                                    TempParams.size(),
                                  (TemplateParameterList**) TempParams.release(),
-                                   T.getTypePtr(),
+                                   TSI,
                                    DS.getFriendSpecLoc());
   else
-    D = FriendDecl::Create(Context, CurContext, Loc, T.getTypePtr(),
+    D = FriendDecl::Create(Context, CurContext, Loc, TSI,
                            DS.getFriendSpecLoc());
   D->setAccess(AS_public);
   CurContext->addDecl(D);

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=99525&r1=99524&r2=99525&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Mar 25 13:04:51 2010
@@ -3644,7 +3644,7 @@
   if (TUK == TUK_Friend) {
     FriendDecl *Friend = FriendDecl::Create(Context, CurContext,
                                             TemplateNameLoc,
-                                            WrittenTy->getType().getTypePtr(),
+                                            WrittenTy,
                                             /*FIXME:*/KWLoc);
     Friend->setAccess(AS_public);
     CurContext->addDecl(Friend);

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=99525&r1=99524&r2=99525&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Mar 25 13:04:51 2010
@@ -480,13 +480,17 @@
 
   // Handle friend type expressions by simply substituting template
   // parameters into the pattern type.
-  if (Type *Ty = D->getFriendType()) {
-    QualType T = SemaRef.SubstType(QualType(Ty,0), TemplateArgs,
-                                   D->getLocation(), DeclarationName());
-    if (T.isNull()) return 0;
+  if (TypeSourceInfo *Ty = D->getFriendType()) {
+    TypeSourceInfo *InstTy = 
+      SemaRef.SubstType(Ty, TemplateArgs,
+                        D->getLocation(), DeclarationName());
+    if (!InstTy) return 0;
+
+    // This assertion is valid because the source type was necessarily
+    // an elaborated-type-specifier with a record tag.
+    assert(getLangOptions().CPlusPlus0x || InstTy->getType()->isRecordType());
 
-    assert(getLangOptions().CPlusPlus0x || T->isRecordType());
-    FU = T.getTypePtr();
+    FU = InstTy;
 
   // Handle everything else by appropriate substitution.
   } else {





More information about the cfe-commits mailing list