DefinitionShadower: allow shadowing of non-user-defined declarations (#6571)
* [cling] DefinitionShadower: allow shadowing of non-user-defined declarations These changes allow the DefinitionShadower to shadow declarations whose first definition was possibly in a system header. This solves the problem of declaring a variable 'data' that might conflict with 'std::data' (by allowing std::data to be shadowed). * [cling] DefinitionShadower: fix handling of variable templates
This commit is contained in:
parent
d0d29079a5
commit
e84dc544fc
@ -46,6 +46,18 @@ namespace cling {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \brief Returns whether the given declaration is a template instantiation
|
||||
/// or specialization.
|
||||
static bool isInstantiationOrSpecialization(const Decl *D) {
|
||||
if (auto FD = dyn_cast<FunctionDecl>(D))
|
||||
return FD->isTemplateInstantiation() || FD->isFunctionTemplateSpecialization();
|
||||
if (auto CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
|
||||
return CTSD->getSpecializationKind() != TSK_Undeclared;
|
||||
if (auto VTSD = dyn_cast<VarTemplateSpecializationDecl>(D))
|
||||
return VTSD->getSpecializationKind() != TSK_Undeclared;
|
||||
return false;
|
||||
}
|
||||
|
||||
DefinitionShadower::DefinitionShadower(Sema& S, Interpreter& I)
|
||||
: ASTTransformer(&S), m_Context(S.getASTContext()), m_Interp(I),
|
||||
m_TU(S.getASTContext().getTranslationUnitDecl())
|
||||
@ -57,9 +69,6 @@ namespace cling {
|
||||
}
|
||||
|
||||
void DefinitionShadower::hideDecl(clang::NamedDecl *D) const {
|
||||
assert(isClingShadowNamespace(D->getDeclContext())
|
||||
&& "D not in a __cling_N5xxx namespace?");
|
||||
|
||||
// FIXME: this hides a decl from SemaLookup (there is no unloading). For
|
||||
// (large) L-values, this might be a memory leak. Should this be fixed?
|
||||
if (Scope* S = m_Sema->getScopeForContext(m_TU)) {
|
||||
@ -83,8 +92,6 @@ namespace cling {
|
||||
for (auto Prev : Previous) {
|
||||
if (Prev == D)
|
||||
continue;
|
||||
if (!isClingShadowNamespace(Prev->getDeclContext()))
|
||||
continue;
|
||||
if (isDefinition(Prev) && !isDefinition(D))
|
||||
continue;
|
||||
// If the found declaration is a function overload, do not invalidate it.
|
||||
@ -148,15 +155,19 @@ namespace cling {
|
||||
|
||||
ASTTransformer::Result DefinitionShadower::Transform(Decl* D) {
|
||||
Transaction *T = getTransaction();
|
||||
const CompilationOptions &CO = T->getCompilationOpts();
|
||||
// Global declarations whose origin is the Cling prompt are subject to be
|
||||
// nested in a `__cling_N5' namespace.
|
||||
if (!CO.EnableShadowing
|
||||
|| D->getLexicalDeclContext() != m_TU || D->isInvalidDecl()
|
||||
|| isa<UsingDirectiveDecl>(D) || isa<UsingDecl>(D)
|
||||
// FIXME: NamespaceDecl requires additional processing (TBD)
|
||||
|| isa<NamespaceDecl>(D)
|
||||
|| (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isTemplateInstantiation())
|
||||
if (!T->getCompilationOpts().EnableShadowing)
|
||||
return Result(D, true);
|
||||
|
||||
// For variable templates, Transform() is invoked with a VarDecl; get the
|
||||
// corresponding VarTemplateDecl.
|
||||
if (auto VD = dyn_cast<VarDecl>(D))
|
||||
if (auto VTD = VD->getDescribedVarTemplate())
|
||||
D = VTD;
|
||||
|
||||
// Disable definition shadowing for some specific cases.
|
||||
if (D->getLexicalDeclContext() != m_TU || D->isInvalidDecl()
|
||||
|| isa<UsingDirectiveDecl>(D) || isa<UsingDecl>(D) || isa<NamespaceDecl>(D)
|
||||
|| isInstantiationOrSpecialization(D)
|
||||
|| !typedInClingPrompt(FullSourceLoc{D->getLocation(),
|
||||
m_Context.getSourceManager()}))
|
||||
return Result(D, true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user