No longer hide the compiler detail.

The partial desugaring (part of normalization) now strips a typedef
even when it original from std and points to compiler details (__gnu_cxx, etc.).

The cost of this convenience was the fact the same entity could have different
'name' and thus different class even-though they were supposed to be strictly
equivalent. i.e. depending on the way to get to the class it could be name
vector<int*>::iterator or __gnu_cxx::iterator<int*> or std::iterator<int*>.

This different from the case where we have a strictly bidirectional equivalent
between the class and its unique typedef (yes, we are talking about you std::string).

This also different from the case where there is a semantic difference between
the two possible name.  I.e. where an opaque typedef is used.  For example,
vector<Double32_t> and vector<double> and where the 'way' to get to the type[name]
is relevant.
This commit is contained in:
Philippe Canal 2014-03-20 18:27:54 -05:00 committed by sftnight
parent 3115300308
commit 45895aec23
2 changed files with 6 additions and 79 deletions

View File

@ -602,31 +602,6 @@ namespace utils {
return false;
}
static bool IsCompilerDetails(const TagType *tagTy)
{
// Return true if the TagType is a 'details' of the std implementation.
// (For now it means declared in __gnu_cxx or starting with underscore).
const TagDecl *decl = tagTy->getDecl();
assert(decl);
IdentifierInfo *info = decl->getDeclName().getAsIdentifierInfo();
if (info && info->getNameStart()[0] == '_') {
// We have a name starting by _, this is reserve for compiler
// implementation, so let's not desugar to it.
return true;
}
// And let's check if it is in one of the know compiler implementation
// namespace.
const NamedDecl *outer =dyn_cast_or_null<NamedDecl>(decl->getDeclContext());
while (outer && outer->getName().size() ) {
if (outer->getName().compare("__gnu_cxx") == 0) {
return true;
}
outer = dyn_cast_or_null<NamedDecl>(outer->getDeclContext());
}
return false;
}
unsigned int
Transform::Config::DropDefaultArg(clang::TemplateDecl &Template) const
{
@ -658,41 +633,7 @@ namespace utils {
{
// Return true, if we should keep this typedef rather than desugaring it.
if ( 0 != TypesToSkip.count(QT.getTypePtr()) )
return true;
const TypedefType* typedeftype =
dyn_cast_or_null<TypedefType>(QT.getTypePtr());
const TypedefNameDecl* decl = typedeftype ? typedeftype->getDecl() : 0;
if (decl) {
const NamedDecl* outer
= dyn_cast_or_null<NamedDecl>(decl->getDeclContext());
// We want to keep the typedef that are defined within std and
// are pointing to something also declared in std (usually an
// implementation details like std::basic_string or __gnu_cxx::iterator.
while ( outer && outer->getName().size() ) {
// NOTE: Net is being cast too widely, replace by a lookup.
// or by using Sema::getStdNamespace
if (outer->getDeclContext()->isTranslationUnit()
&& outer->getName().compare("std") == 0) {
// And now let's check that the target is also within std.
const Type *underlyingType
= decl->getUnderlyingType().getSplitDesugaredType().Ty;
const ElaboratedType *elTy = dyn_cast<ElaboratedType>(underlyingType);
if (elTy) {
underlyingType = elTy->getNamedType().getTypePtr();
}
const TagType *tagTy = underlyingType->getAs<TagType>();
if (tagTy) {
bool details = IsCompilerDetails(tagTy);
if (details) return true;
}
}
outer = dyn_cast_or_null<NamedDecl>(outer->getDeclContext());
}
}
return false;
return 0 != TypesToSkip.count(QT.getTypePtr());
}
static bool SingleStepPartiallyDesugarTypeImpl(QualType& QT)

View File

@ -36,7 +36,7 @@ template <typename T, typename U> class C {};
typedef C<A<B<Double32_t, Int_t> >, Double32_t > CTD;
typedef C<A<B<const Double32_t, const Int_t> >, Double32_t > CTDConst;
template <typename key, typename value, typename compare_operation = std::less<key>, typename alloc = std::allocator<std::pair<const key, value> > > class cmap { key fKey; const value fValue; alloc fAlloc; };
template <typename key, typename value, typename compare_operation = std::less<key>, typename alloc = std::allocator<std::pair<const key, value> > > class cmap { key fKey; const value fValue; alloc fAlloc; public: cmap() : fValue(0) {} };
// : public std::map<key, value, compare_operation, alloc> {
template <typename key, typename value = const key> class mypair { public: key fKey; value fValue; };
@ -108,10 +108,10 @@ public:
Embedded_objects::EmbeddedClasses::Embedded5 m_emb5;
Embedded_objects::EmbeddedTypedef::Embedded6 m_emb6;
typedef std::vector<int> vecint;
vecint::iterator m_iter;
vecint* m_iter;
const Eenum m_enum;
typedef vector<int> vecint2;
vecint2::iterator m_iter2;
vecint2* m_iter2;
};
namespace NS1 {
@ -141,7 +141,6 @@ transConfig.m_toSkip.insert(lookup.findType("string", diags).getTypePtr());
transConfig.m_toSkip.insert(lookup.findType("std::string", diags).getTypePtr());
const clang::Type* t = 0;
const clang::TypedefType *td = 0;
clang::QualType QT;
using namespace cling::utils;
@ -318,19 +317,6 @@ QT = clang::QualType(t, 0);
Transform::GetPartiallyDesugaredType(Ctx, QT, transConfig).getAsString().c_str()
// CHECK: ({{const char [*]|const_pointer}}) "Details::Impl"
lookup.findScope("vector<Details::Impl>::iterator", diags, &t);
QT = clang::QualType(t, 0);
Transform::GetPartiallyDesugaredType(Ctx, QT, transConfig).getAsString().c_str()
// CHECK: ({{const char [*]|const_pointer}}) "std::vector<Details::Impl>::iterator"
lookup.findScope("vector<Details::Impl>::const_iterator", diags, &t);
QT = clang::QualType(t, 0);
td = QT->getAs<clang::TypedefType>();
clang::TypedefNameDecl *tdDecl = td->getDecl();
QT = Ctx.getTypedefType(tdDecl);
Transform::GetPartiallyDesugaredType(Ctx, QT, transConfig, true).getAsString().c_str()
// CHECK: ({{const char [*]|const_pointer}}) "std::vector<Details::Impl, std::allocator<Details::Impl> >::const_iterator"
const clang::Decl*decl=lookup.findScope("Embedded_objects", diags,&t);
if (decl) {
const clang::CXXRecordDecl *cxxdecl
@ -356,9 +342,9 @@ if (decl) {
// CHECK: Embedded_objects::EmbeddedClasses::Embedded4
// CHECK: Embedded_objects::EmbeddedClasses::Embedded5
// CHECK: Embedded_objects::EmbeddedClasses::Embedded6
// CHECK: std::vector<int>::iterator
// CHECK: std::vector<int> *
// CHECK: const Embedded_objects::Eenum
// CHECK: std::vector<int>::iterator
// CHECK: std::vector<int> *
// In the partial desugaring add support for the case where we have a type
// that point to an already completely desugared template instantiation in