Skip to content

Commit d026b49

Browse files
committed
[cling] Also fwd decl underlying type of using decls:
Before, only the using decl itself was forward declared, causing undeclared identifiers in forward declaration code, as witnessed in #8499 Given the similarity of using and typedef, merge both into a single function, making sure both have the same featureset, and through that fixing this issue as a side-effect.
1 parent e1da585 commit d026b49

File tree

2 files changed

+37
-23
lines changed

2 files changed

+37
-23
lines changed

interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ namespace cling {
298298
}
299299
}
300300

301-
void ForwardDeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
301+
void ForwardDeclPrinter::printTypedefOrAliasDecl(TypedefNameDecl *D) {
302302
QualType q = D->getTypeSourceInfo()->getType();
303303
Visit(q);
304304
if (m_SkipFlag) {
@@ -308,34 +308,45 @@ namespace cling {
308308

309309
std::string closeBraces = PrintEnclosingDeclContexts(Out(),
310310
D->getDeclContext());
311-
if (!m_Policy.SuppressSpecifiers)
312-
Out() << "typedef ";
313-
if (D->isModulePrivate())
314-
Out() << "__module_private__ ";
311+
auto printUnderying = [&]() {
312+
QualType qNoRestrict = q;
313+
if (qNoRestrict.isRestrictQualified())
314+
qNoRestrict.removeLocalRestrict();
315+
qNoRestrict.print(Out(), m_Policy);
316+
};
317+
auto printDeclName = [&]() {
318+
if (D->isModulePrivate())
319+
Out() << "__module_private__ ";
315320

316-
if (q.isRestrictQualified()){
317-
q.removeLocalRestrict();
318-
q.print(Out(), m_Policy, "");
319-
Out() << " __restrict " << D->getName(); //TODO: Find some policy that does this automatically
320-
}
321-
else {
322-
q.print(Out(), m_Policy, D->getName());
321+
if (q.isRestrictQualified()) {
322+
Out() << " __restrict "; // TODO: Find some policy that does this automatically
323+
}
324+
Out() << D->getName();
325+
prettyPrintAttributes(D);
326+
};
327+
328+
if (llvm::isa<TypedefDecl>(D)) {
329+
Out() << "typedef ";
330+
printUnderying();
331+
Out() << " ";
332+
printDeclName();
333+
} else if (llvm::isa<TypeAliasDecl>(D)) {
334+
Out() << "using ";
335+
printDeclName();
336+
Out() << " = ";
337+
printUnderying();
338+
} else {
339+
skipDecl(D, "Neither a typedef nor a type alias!");
323340
}
324-
prettyPrintAttributes(D);
325341
Out() << ';' << closeBraces << '\n';
342+
}
343+
344+
void ForwardDeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
345+
printTypedefOrAliasDecl(D);
326346
}
327347

328348
void ForwardDeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) {
329-
/*FIXME: Ugly Hack*/
330-
// if(!D->getLexicalDeclContext()->isNamespace()
331-
// && !D->getLexicalDeclContext()->isFileContext())
332-
// return;
333-
std::string closeBraces = PrintEnclosingDeclContexts(Out(),
334-
D->getDeclContext());
335-
Out() << "using " << *D;
336-
prettyPrintAttributes(D);
337-
Out() << " = " << D->getTypeSourceInfo()->getType().getAsString(m_Policy)
338-
<< ';' << closeBraces << '\n';
349+
printTypedefOrAliasDecl(D);
339350
}
340351

341352
void ForwardDeclPrinter::VisitEnumDecl(EnumDecl *D) {

interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ namespace clang {
7979
class TranslationUnitDecl;
8080
class TypeAliasDecl;
8181
class TypedefDecl;
82+
class TypedefNameDecl;
8283
class VarDecl;
8384
class UsingDirectiveDecl;
8485
}
@@ -109,6 +110,8 @@ namespace cling {
109110
std::set<const char*> m_BuiltinNames;
110111
IgnoreFilesFunc_t m_IgnoreFile; // Call back to ignore some top level files.
111112

113+
void printTypedefOrAliasDecl(clang::TypedefNameDecl* D);
114+
112115
public:
113116
ForwardDeclPrinter(llvm::raw_ostream& OutS,
114117
llvm::raw_ostream& LogS,

0 commit comments

Comments
 (0)