parent
df71846ee9
commit
5cf51d53dd
@ -408,6 +408,37 @@ namespace {
|
||||
removeSpecializationImpl(specs, spec);
|
||||
}
|
||||
};
|
||||
|
||||
// A template specialization is attached to the list of specialization of
|
||||
// the templated variable.
|
||||
//
|
||||
class VarTemplateDeclExt : public VarTemplateDecl {
|
||||
public:
|
||||
static void removeSpecialization(VarTemplateDecl* self,
|
||||
VarTemplateSpecializationDecl* spec) {
|
||||
assert(!isa<VarTemplatePartialSpecializationDecl>(spec) &&
|
||||
"Use removePartialSpecialization");
|
||||
assert(self && spec && "Cannot be null!");
|
||||
assert(spec == spec->getCanonicalDecl() &&
|
||||
"Not the canonical specialization!?");
|
||||
|
||||
auto* This = static_cast<VarTemplateDeclExt*>(self);
|
||||
auto& specs = This->getCommonPtr()->Specializations;
|
||||
removeSpecializationImpl(specs, spec);
|
||||
}
|
||||
|
||||
static void
|
||||
removePartialSpecialization(VarTemplateDecl* self,
|
||||
VarTemplatePartialSpecializationDecl* spec) {
|
||||
assert(self && spec && "Cannot be null!");
|
||||
assert(spec == spec->getCanonicalDecl() &&
|
||||
"Not the canonical specialization!?");
|
||||
|
||||
auto* This = static_cast<VarTemplateDeclExt*>(self);
|
||||
auto& specs = This->getPartialSpecializations();
|
||||
removeSpecializationImpl(specs, spec);
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace cling {
|
||||
@ -1017,4 +1048,41 @@ namespace cling {
|
||||
ClassTemplateSpecializationDecl* CTSD) {
|
||||
return VisitClassTemplateSpecializationDecl(CTSD, /*RemoveSpec=*/true);
|
||||
}
|
||||
|
||||
bool DeclUnloader::VisitVarTemplateDecl(VarTemplateDecl* VTD) {
|
||||
// VarTemplateDecl: TemplateDecl, Redeclarable
|
||||
bool Successful = true;
|
||||
// Remove specializations, but do not invalidate the iterator!
|
||||
for (VarTemplateDecl::spec_iterator I = VTD->loaded_spec_begin(),
|
||||
E = VTD->loaded_spec_end();
|
||||
I != E; ++I)
|
||||
Successful &=
|
||||
VisitVarTemplateSpecializationDecl(*I, /*RemoveSpec=*/false);
|
||||
|
||||
Successful &= VisitRedeclarableTemplateDecl(VTD);
|
||||
Successful &= Visit(VTD->getTemplatedDecl());
|
||||
return Successful;
|
||||
}
|
||||
|
||||
bool DeclUnloader::VisitVarTemplateSpecializationDecl(
|
||||
VarTemplateSpecializationDecl* VTSD, bool RemoveSpec) {
|
||||
// VarTemplateSpecializationDecl: VarDecl, FoldingSet
|
||||
bool Successful = VisitVarDecl(VTSD);
|
||||
if (RemoveSpec) {
|
||||
VarTemplateSpecializationDecl* CanonVTSD =
|
||||
static_cast<VarTemplateSpecializationDecl*>(VTSD->getCanonicalDecl());
|
||||
if (auto D = dyn_cast<VarTemplatePartialSpecializationDecl>(CanonVTSD))
|
||||
VarTemplateDeclExt::removePartialSpecialization(
|
||||
D->getSpecializedTemplate(), D);
|
||||
else
|
||||
VarTemplateDeclExt::removeSpecialization(VTSD->getSpecializedTemplate(),
|
||||
CanonVTSD);
|
||||
}
|
||||
return Successful;
|
||||
}
|
||||
|
||||
bool DeclUnloader::VisitVarTemplateSpecializationDecl(
|
||||
VarTemplateSpecializationDecl* VTSD) {
|
||||
return VisitVarTemplateSpecializationDecl(VTSD, /*RemoveSpec=*/true);
|
||||
}
|
||||
} // end namespace cling
|
||||
|
@ -258,6 +258,34 @@ namespace cling {
|
||||
bool VisitClassTemplateSpecializationDecl(
|
||||
clang::ClassTemplateSpecializationDecl* CTSD);
|
||||
|
||||
///\brief Removes a var template declaration from clang's internal
|
||||
/// structures.
|
||||
/// @param[in] VTD - The declaration to be removed.
|
||||
///
|
||||
///\returns true on success.
|
||||
///
|
||||
bool VisitVarTemplateDecl(clang::VarTemplateDecl* VTD);
|
||||
|
||||
///\brief Removes a var template specialization declaration from clang's
|
||||
/// internal structures.
|
||||
/// @param[in] CTSD - The declaration to be removed.
|
||||
/// @param[in] RemoveSpec - Whether to remove the specialization from its
|
||||
/// parent.
|
||||
///
|
||||
///\returns true on success.
|
||||
///
|
||||
bool VisitVarTemplateSpecializationDecl(
|
||||
clang::VarTemplateSpecializationDecl* VTSD, bool RemoveSpec);
|
||||
|
||||
///\brief Removes a var template specialization declaration from clang's
|
||||
/// internal structures.
|
||||
/// @param[in] CTSD - The declaration to be removed.
|
||||
///
|
||||
///\returns true on success.
|
||||
///
|
||||
bool VisitVarTemplateSpecializationDecl(
|
||||
clang::VarTemplateSpecializationDecl* VTSD);
|
||||
|
||||
///@}
|
||||
|
||||
void MaybeRemoveDeclFromModule(clang::GlobalDecl& GD) const;
|
||||
|
32
test/ErrorRecovery/IncompleteType.C
Normal file
32
test/ErrorRecovery/IncompleteType.C
Normal file
@ -0,0 +1,32 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// CLING - the C++ LLVM-based InterpreterG :)
|
||||
//
|
||||
// This file is dual-licensed: you can choose to license it under the University
|
||||
// of Illinois Open Source License or the GNU Lesser General Public License. See
|
||||
// LICENSE.TXT for details.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// RUN: cat %s | %cling 2>&1 | FileCheck %s
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
struct A { int v; };
|
||||
std::is_default_constructible_v<A>
|
||||
// CHECK: (const bool) true
|
||||
|
||||
struct B;
|
||||
std::is_default_constructible_v<B>
|
||||
// CHECK: incomplete type 'B'
|
||||
struct B { int v; };
|
||||
std::is_default_constructible_v<B>
|
||||
// CHECK: (const bool) true
|
||||
|
||||
template <typename T> struct C;
|
||||
template <> struct C<int>;
|
||||
std::is_default_constructible_v<C<int>>
|
||||
// CHECK: incomplete type 'C<int>'
|
||||
template <> struct C<int> { int v; };
|
||||
std::is_default_constructible_v<C<int>>
|
||||
// CHECK: (const bool) true
|
||||
|
||||
.q
|
Loading…
Reference in New Issue
Block a user