Skip to content

Commit d5d15b4

Browse files
committed
[clang][AST] Refactoring ASTNameGenerator to use pimpl pattern (NFC).
The original pimpl pattern used between CodegenNameGenerator and CodegenNameGeneratorImpl did a good job of hiding DataLayout making it so that users of CodegenNameGenerator did not need to link with llvm core. This is an NFC change to neatly wrap ASTNameGenerator in a pimpl. Differential Revision: https://reviews.llvm.org/D63584 llvm-svn: 363908
1 parent b4ea645 commit d5d15b4

File tree

2 files changed

+171
-155
lines changed

2 files changed

+171
-155
lines changed

clang/include/clang/AST/Mangle.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "clang/AST/Type.h"
1818
#include "clang/Basic/ABI.h"
1919
#include "llvm/ADT/DenseMap.h"
20-
#include "llvm/IR/DataLayout.h"
2120
#include "llvm/Support/Casting.h"
2221

2322
namespace llvm {
@@ -246,21 +245,16 @@ class MicrosoftMangleContext : public MangleContext {
246245
};
247246

248247
class ASTNameGenerator {
249-
std::unique_ptr<MangleContext> MC;
250-
llvm::DataLayout DL;
251-
252248
public:
253249
explicit ASTNameGenerator(ASTContext &Ctx);
250+
~ASTNameGenerator();
254251
bool writeName(const Decl *D, raw_ostream &OS);
255252
std::string getName(const Decl *D);
256253
std::vector<std::string> getAllManglings(const Decl *D);
257254

258255
private:
259-
std::vector<std::string> getAllManglings(const ObjCContainerDecl *OCD);
260-
bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS);
261-
void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS);
262-
std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType);
263-
std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T);
256+
class Implementation;
257+
std::unique_ptr<Implementation> Impl;
264258
};
265259
}
266260

clang/lib/AST/Mangle.cpp

Lines changed: 168 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "clang/Basic/SourceManager.h"
2323
#include "clang/Basic/TargetInfo.h"
2424
#include "llvm/ADT/StringExtras.h"
25+
#include "llvm/IR/DataLayout.h"
2526
#include "llvm/IR/Mangler.h"
2627
#include "llvm/Support/ErrorHandling.h"
2728
#include "llvm/Support/raw_ostream.h"
@@ -283,183 +284,204 @@ void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
283284
Out << OS.str().size() << OS.str();
284285
}
285286

286-
ASTNameGenerator::ASTNameGenerator(ASTContext &Ctx)
287-
: MC(Ctx.createMangleContext()), DL(Ctx.getTargetInfo().getDataLayout()) {}
287+
class ASTNameGenerator::Implementation {
288+
std::unique_ptr<MangleContext> MC;
289+
llvm::DataLayout DL;
288290

289-
bool ASTNameGenerator::writeName(const Decl *D, raw_ostream &OS) {
290-
// First apply frontend mangling.
291-
SmallString<128> FrontendBuf;
292-
llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
293-
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
294-
if (FD->isDependentContext())
295-
return true;
296-
if (writeFuncOrVarName(FD, FrontendBufOS))
297-
return true;
298-
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
299-
if (writeFuncOrVarName(VD, FrontendBufOS))
291+
public:
292+
explicit Implementation(ASTContext &Ctx)
293+
: MC(Ctx.createMangleContext()), DL(Ctx.getTargetInfo().getDataLayout()) {
294+
}
295+
296+
bool writeName(const Decl *D, raw_ostream &OS) {
297+
// First apply frontend mangling.
298+
SmallString<128> FrontendBuf;
299+
llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
300+
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
301+
if (FD->isDependentContext())
302+
return true;
303+
if (writeFuncOrVarName(FD, FrontendBufOS))
304+
return true;
305+
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
306+
if (writeFuncOrVarName(VD, FrontendBufOS))
307+
return true;
308+
} else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
309+
MC->mangleObjCMethodNameWithoutSize(MD, OS);
310+
return false;
311+
} else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
312+
writeObjCClassName(ID, FrontendBufOS);
313+
} else {
300314
return true;
301-
} else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
302-
MC->mangleObjCMethodNameWithoutSize(MD, OS);
315+
}
316+
317+
// Now apply backend mangling.
318+
llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
303319
return false;
304-
} else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
305-
writeObjCClassName(ID, FrontendBufOS);
306-
} else {
307-
return true;
308320
}
309321

310-
// Now apply backend mangling.
311-
llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
312-
return false;
313-
}
314-
315-
std::string ASTNameGenerator::getName(const Decl *D) {
316-
std::string Name;
317-
{
318-
llvm::raw_string_ostream OS(Name);
319-
writeName(D, OS);
322+
std::string getName(const Decl *D) {
323+
std::string Name;
324+
{
325+
llvm::raw_string_ostream OS(Name);
326+
writeName(D, OS);
327+
}
328+
return Name;
320329
}
321-
return Name;
322-
}
323330

324-
enum ObjCKind {
325-
ObjCClass,
326-
ObjCMetaclass,
327-
};
331+
enum ObjCKind {
332+
ObjCClass,
333+
ObjCMetaclass,
334+
};
328335

329-
static StringRef getClassSymbolPrefix(ObjCKind Kind,
330-
const ASTContext &Context) {
331-
if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
332-
return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_";
333-
return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_";
334-
}
336+
static StringRef getClassSymbolPrefix(ObjCKind Kind,
337+
const ASTContext &Context) {
338+
if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
339+
return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_";
340+
return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_";
341+
}
335342

336-
std::vector<std::string>
337-
ASTNameGenerator::getAllManglings(const ObjCContainerDecl *OCD) {
338-
StringRef ClassName;
339-
if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
340-
ClassName = OID->getObjCRuntimeNameAsString();
341-
else if (const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
342-
ClassName = OID->getObjCRuntimeNameAsString();
343-
344-
if (ClassName.empty())
345-
return {};
346-
347-
auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string {
348-
SmallString<40> Mangled;
349-
auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext());
350-
llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
351-
return Mangled.str();
352-
};
343+
std::vector<std::string> getAllManglings(const ObjCContainerDecl *OCD) {
344+
StringRef ClassName;
345+
if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
346+
ClassName = OID->getObjCRuntimeNameAsString();
347+
else if (const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
348+
ClassName = OID->getObjCRuntimeNameAsString();
349+
350+
if (ClassName.empty())
351+
return {};
352+
353+
auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string {
354+
SmallString<40> Mangled;
355+
auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext());
356+
llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
357+
return Mangled.str();
358+
};
359+
360+
return {
361+
Mangle(ObjCClass, ClassName),
362+
Mangle(ObjCMetaclass, ClassName),
363+
};
364+
}
353365

354-
return {
355-
Mangle(ObjCClass, ClassName),
356-
Mangle(ObjCMetaclass, ClassName),
357-
};
358-
}
366+
std::vector<std::string> getAllManglings(const Decl *D) {
367+
if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
368+
return getAllManglings(OCD);
359369

360-
std::vector<std::string> ASTNameGenerator::getAllManglings(const Decl *D) {
361-
if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
362-
return getAllManglings(OCD);
370+
if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
371+
return {};
363372

364-
if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
365-
return {};
373+
const NamedDecl *ND = cast<NamedDecl>(D);
366374

367-
const NamedDecl *ND = cast<NamedDecl>(D);
375+
ASTContext &Ctx = ND->getASTContext();
376+
std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
368377

369-
ASTContext &Ctx = ND->getASTContext();
370-
std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
378+
std::vector<std::string> Manglings;
371379

372-
std::vector<std::string> Manglings;
380+
auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
381+
auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
382+
/*IsCSSMethod=*/true);
383+
auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
384+
return CC == DefaultCC;
385+
};
373386

374-
auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
375-
auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
376-
/*IsCSSMethod=*/true);
377-
auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
378-
return CC == DefaultCC;
379-
};
387+
if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
388+
Manglings.emplace_back(getMangledStructor(CD, Ctor_Base));
389+
390+
if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
391+
if (!CD->getParent()->isAbstract())
392+
Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete));
380393

381-
if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
382-
Manglings.emplace_back(getMangledStructor(CD, Ctor_Base));
383-
384-
if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
385-
if (!CD->getParent()->isAbstract())
386-
Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete));
387-
388-
if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
389-
if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
390-
if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
391-
Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure));
392-
} else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
393-
Manglings.emplace_back(getMangledStructor(DD, Dtor_Base));
394-
if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
395-
Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete));
396-
if (DD->isVirtual())
397-
Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting));
394+
if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
395+
if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
396+
if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
397+
Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure));
398+
} else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
399+
Manglings.emplace_back(getMangledStructor(DD, Dtor_Base));
400+
if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
401+
Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete));
402+
if (DD->isVirtual())
403+
Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting));
404+
}
405+
} else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
406+
Manglings.emplace_back(getName(ND));
407+
if (MD->isVirtual())
408+
if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
409+
for (const auto &T : *TIV)
410+
Manglings.emplace_back(getMangledThunk(MD, T));
398411
}
399-
} else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
400-
Manglings.emplace_back(getName(ND));
401-
if (MD->isVirtual())
402-
if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
403-
for (const auto &T : *TIV)
404-
Manglings.emplace_back(getMangledThunk(MD, T));
412+
413+
return Manglings;
405414
}
406415

407-
return Manglings;
408-
}
416+
private:
417+
bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) {
418+
if (MC->shouldMangleDeclName(D)) {
419+
if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
420+
MC->mangleCXXCtor(CtorD, Ctor_Complete, OS);
421+
else if (const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
422+
MC->mangleCXXDtor(DtorD, Dtor_Complete, OS);
423+
else
424+
MC->mangleName(D, OS);
425+
return false;
426+
} else {
427+
IdentifierInfo *II = D->getIdentifier();
428+
if (!II)
429+
return true;
430+
OS << II->getName();
431+
return false;
432+
}
433+
}
409434

410-
bool ASTNameGenerator::writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) {
411-
if (MC->shouldMangleDeclName(D)) {
412-
if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
413-
MC->mangleCXXCtor(CtorD, Ctor_Complete, OS);
414-
else if (const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
415-
MC->mangleCXXDtor(DtorD, Dtor_Complete, OS);
416-
else
417-
MC->mangleName(D, OS);
418-
return false;
419-
} else {
420-
IdentifierInfo *II = D->getIdentifier();
421-
if (!II)
422-
return true;
423-
OS << II->getName();
424-
return false;
435+
void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) {
436+
OS << getClassSymbolPrefix(ObjCClass, D->getASTContext());
437+
OS << D->getObjCRuntimeNameAsString();
425438
}
426-
}
427439

428-
void ASTNameGenerator::writeObjCClassName(const ObjCInterfaceDecl *D,
429-
raw_ostream &OS) {
430-
OS << getClassSymbolPrefix(ObjCClass, D->getASTContext());
431-
OS << D->getObjCRuntimeNameAsString();
432-
}
440+
std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) {
441+
std::string FrontendBuf;
442+
llvm::raw_string_ostream FOS(FrontendBuf);
443+
444+
if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
445+
MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
446+
else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
447+
MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
433448

434-
std::string ASTNameGenerator::getMangledStructor(const NamedDecl *ND,
435-
unsigned StructorType) {
436-
std::string FrontendBuf;
437-
llvm::raw_string_ostream FOS(FrontendBuf);
449+
std::string BackendBuf;
450+
llvm::raw_string_ostream BOS(BackendBuf);
438451

439-
if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
440-
MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
441-
else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
442-
MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
452+
llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
443453

444-
std::string BackendBuf;
445-
llvm::raw_string_ostream BOS(BackendBuf);
454+
return BOS.str();
455+
}
446456

447-
llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
457+
std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T) {
458+
std::string FrontendBuf;
459+
llvm::raw_string_ostream FOS(FrontendBuf);
448460

449-
return BOS.str();
450-
}
461+
MC->mangleThunk(MD, T, FOS);
451462

452-
std::string ASTNameGenerator::getMangledThunk(const CXXMethodDecl *MD,
453-
const ThunkInfo &T) {
454-
std::string FrontendBuf;
455-
llvm::raw_string_ostream FOS(FrontendBuf);
463+
std::string BackendBuf;
464+
llvm::raw_string_ostream BOS(BackendBuf);
456465

457-
MC->mangleThunk(MD, T, FOS);
466+
llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
458467

459-
std::string BackendBuf;
460-
llvm::raw_string_ostream BOS(BackendBuf);
468+
return BOS.str();
469+
}
470+
};
461471

462-
llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
472+
ASTNameGenerator::ASTNameGenerator(ASTContext &Ctx)
473+
: Impl(llvm::make_unique<Implementation>(Ctx)) {}
474+
475+
ASTNameGenerator::~ASTNameGenerator() {}
463476

464-
return BOS.str();
477+
bool ASTNameGenerator::writeName(const Decl *D, raw_ostream &OS) {
478+
return Impl->writeName(D, OS);
479+
}
480+
481+
std::string ASTNameGenerator::getName(const Decl *D) {
482+
return Impl->getName(D);
483+
}
484+
485+
std::vector<std::string> ASTNameGenerator::getAllManglings(const Decl *D) {
486+
return Impl->getAllManglings(D);
465487
}

0 commit comments

Comments
 (0)