[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