@@ -14,7 +14,7 @@ namespace glu::sema {
1414class DuplicateFunctionChecker
1515 : public ast::ASTWalker<DuplicateFunctionChecker, void > {
1616 DiagnosticManager &_diagManager;
17- llvm::SmallVector<llvm::StringRef, 16 > _noManglingFunctionNames ;
17+ llvm::SmallVector<llvm::StringRef, 16 > _usedLinkageNames ;
1818
1919public:
2020 explicit DuplicateFunctionChecker (DiagnosticManager &diagManager)
@@ -28,28 +28,52 @@ class DuplicateFunctionChecker
2828 return ;
2929
3030 if (node->hasAttribute (ast::AttributeKind::NoManglingKind))
31- checkNoManglingDuplicate (node);
31+ checkLinkageNameDuplicate (node, node->getName (), " no_mangling" );
32+ else if (node->hasAttribute (ast::AttributeKind::LinkageNameKind))
33+ checkLinkageNameFromAttribute (node);
3234 else
3335 checkDuplicateFunction (node);
3436 }
3537
3638private:
37- void checkNoManglingDuplicate (ast::FunctionDecl *node)
39+ // / @brief Check for duplicate linkage names (used by both @no_mangling and
40+ // / @linkage_name)
41+ void checkLinkageNameDuplicate (
42+ ast::FunctionDecl *node, llvm::StringRef linkageName,
43+ llvm::StringRef attributeType
44+ )
3845 {
39- llvm::StringRef functionName = node->getName ();
40-
41- if (llvm::find (_noManglingFunctionNames, functionName)
42- != _noManglingFunctionNames.end ()) {
46+ if (llvm::find (_usedLinkageNames, linkageName)
47+ != _usedLinkageNames.end ()) {
4348 _diagManager.error (
4449 node->getLocation (),
45- " duplicate function with no_mangling attribute: "
46- + functionName .str ()
50+ " duplicate function with " + attributeType. str ()
51+ + " attribute ' " + linkageName .str () + " ' "
4752 );
4853 } else {
49- _noManglingFunctionNames .push_back (functionName );
54+ _usedLinkageNames .push_back (linkageName );
5055 }
5156 }
5257
58+ // / @brief Handle @linkage_name attribute specifically
59+ void checkLinkageNameFromAttribute (ast::FunctionDecl *node)
60+ {
61+ auto *linkageAttr
62+ = node->getAttribute (ast::AttributeKind::LinkageNameKind);
63+ if (!linkageAttr || !linkageAttr->getParameter ())
64+ return ;
65+
66+ auto *literal
67+ = llvm::dyn_cast<ast::LiteralExpr>(linkageAttr->getParameter ());
68+ if (!literal
69+ || !std::holds_alternative<llvm::StringRef>(literal->getValue ()))
70+ return ;
71+
72+ llvm::StringRef linkageName
73+ = std::get<llvm::StringRef>(literal->getValue ());
74+ checkLinkageNameDuplicate (node, linkageName, " linkage_name" );
75+ }
76+
5377 void checkDuplicateFunction (ast::FunctionDecl *node)
5478 {
5579 auto *module = node->getModule ();
0 commit comments