[cfe-commits] r101088 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaType.cpp test/SemaCXX/conversion-function.cpp

Douglas Gregor dgregor at apple.com
Mon Apr 12 16:19:01 PDT 2010


Author: dgregor
Date: Mon Apr 12 18:19:01 2010
New Revision: 101088

URL: http://llvm.org/viewvc/llvm-project?rev=101088&view=rev
Log:
Improve source-location information for C++ conversion functions, by
copying the type location information from the conversion-type-id into
the type location information for the function type. Do something
similar for constructors and destructors, by giving their "void"
return type source-location information.

In all of these cases, we previously left this type-source information
uninitialized, which led to various unfortunate crashes.

We still aren't tracking good source-location information for the
actual names. That's PR6357.

John, please check my sanity on this.

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaCXX/conversion-function.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=101088&r1=101087&r2=101088&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Apr 12 18:19:01 2010
@@ -704,7 +704,8 @@
   QualType GetTypeForDeclarator(Declarator &D, Scope *S,
                                 TypeSourceInfo **TInfo = 0,
                                 TagDecl **OwnedDecl = 0);
-  TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T);
+  TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
+                                               TypeSourceInfo *ReturnTypeInfo);
   /// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
   QualType CreateLocInfoType(QualType T, TypeSourceInfo *TInfo);
   DeclarationName GetNameForDeclarator(Declarator &D);

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=101088&r1=101087&r2=101088&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Apr 12 18:19:01 2010
@@ -922,7 +922,8 @@
   // Determine the type of the declarator. Not all forms of declarator
   // have a type.
   QualType T;
-
+  TypeSourceInfo *ReturnTypeInfo = 0;
+  
   llvm::SmallVector<DelayedAttribute,4> FnAttrsFromDeclSpec;
 
   switch (D.getName().getKind()) {
@@ -948,12 +949,20 @@
     // Constructors and destructors don't have return types. Use
     // "void" instead. 
     T = Context.VoidTy;
+      
+    // FIXME: Keep track of source location information within the constructor
+    // or destructor name.
+    if (TInfo)
+      ReturnTypeInfo = Context.getTrivialTypeSourceInfo(T, 
+                                                    D.getName().StartLocation);
     break;
 
   case UnqualifiedId::IK_ConversionFunctionId:
     // The result type of a conversion function is the type that it
     // converts to.
-    T = GetTypeFromParser(D.getName().ConversionFunctionId);
+    // FIXME: Keep track of the location of the 'operator' keyword?
+    T = GetTypeFromParser(D.getName().ConversionFunctionId, 
+                          TInfo? &ReturnTypeInfo : 0);
     break;
   }
   
@@ -1356,7 +1365,7 @@
     if (D.isInvalidType())
       *TInfo = 0;
     else
-      *TInfo = GetTypeSourceInfoForDeclarator(D, T);
+      *TInfo = GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo);
   }
 
   return T;
@@ -1541,8 +1550,14 @@
 /// \brief Create and instantiate a TypeSourceInfo with type source information.
 ///
 /// \param T QualType referring to the type as written in source code.
+///
+/// \param ReturnTypeInfo For declarators whose return type does not show
+/// up in the normal place in the declaration specifiers (such as a C++
+/// conversion function), this pointer will refer to a type source information
+/// for that return type.
 TypeSourceInfo *
-Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T) {
+Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
+                                     TypeSourceInfo *ReturnTypeInfo) {
   TypeSourceInfo *TInfo = Context.CreateTypeSourceInfo(T);
   UnqualTypeLoc CurrTL = TInfo->getTypeLoc().getUnqualifiedLoc();
 
@@ -1552,7 +1567,18 @@
   }
   
   TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
-
+  
+  // We have source information for the return type that was not in the
+  // declaration specifiers; copy that information into the current type
+  // location so that it will be retained. This occurs, for example, with 
+  // a C++ conversion function, where the return type occurs within the
+  // declarator-id rather than in the declaration specifiers.
+  if (ReturnTypeInfo && D.getDeclSpec().getTypeSpecType() == TST_unspecified) {
+    TypeLoc TL = ReturnTypeInfo->getTypeLoc();
+    assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
+    memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());
+  }
+      
   return TInfo;
 }
 

Modified: cfe/trunk/test/SemaCXX/conversion-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion-function.cpp?rev=101088&r1=101087&r2=101088&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conversion-function.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion-function.cpp Mon Apr 12 18:19:01 2010
@@ -131,3 +131,37 @@
 A1 f() {
   return "Hello"; // expected-error{{invokes deleted copy constructor}}
 }
+
+namespace source_locations {
+  template<typename T>
+  struct sneaky_int {
+    typedef int type;
+  };
+
+  template<typename T, typename U>
+  struct A { };
+
+  template<typename T>
+  struct A<T, T> : A<T, int> { };
+
+  struct E {
+    template<typename T>
+    operator A<T, typename sneaky_int<T>::type>&() const; // expected-note{{candidate function}}
+  };
+
+  void f() {
+    A<float, float> &af = E(); // expected-error{{no viable conversion}}
+    A<float, int> &af2 = E();
+    const A<float, int> &caf2 = E();
+  }
+
+  // Check 
+  template<typename T>
+  struct E2 {
+    operator T
+    * // expected-error{{pointer to a reference}}
+    () const;
+  };
+
+  E2<int&> e2i; // expected-note{{in instantiation}}
+}





More information about the cfe-commits mailing list