@@ -36,8 +36,17 @@ static void OrderedTraversal(const ContainerType &Data, BinaryFunction Visit,
3636
3737constexpr int32_t SOURCE_LANG_LITERAL_MD_IS_NOT_PRESENT = -1 ;
3838
39- inline int32_t getSourceLangLiteralMDValue (const llvm::Module &module ) {
40- auto sourceLangLiteral = module .getModuleFlag (" Source Lang Literal" );
39+ //
40+ // Flag "Source Lang Literal" contains sourceLanguage.
41+ //
42+ // Example:
43+ // !llvm.module.flags = !{..., !3, ...}
44+ // ...
45+ // !3 = !{i32 2, !"Source Lang Literal", 33}
46+ // ...
47+ //
48+ inline int32_t getSourceLangLiteralMDValueLegacy (const llvm::Module *module ) {
49+ auto sourceLangLiteral = module ->getModuleFlag (" Source Lang Literal" );
4150 if (!sourceLangLiteral) {
4251 return SOURCE_LANG_LITERAL_MD_IS_NOT_PRESENT;
4352 }
@@ -47,9 +56,52 @@ inline int32_t getSourceLangLiteralMDValue(const llvm::Module &module) {
4756 llvm::cast<llvm::ConstantInt>(constant->getValue ())->getZExtValue ());
4857}
4958
50- inline uint16_t getSourceLanguage (llvm::DICompileUnit *compileUnit,
59+ //
60+ // Flag "Source Lang Literal" contains a list (MDTuple) of pairs (MDTuple):
61+ // (compileUnit, sourceLanguage)
62+ //
63+ // Example:
64+ // !llvm.module.flags = !{..., !3, ...}
65+ // ...
66+ // !3 = !{i32 2, !"Source Lang Literal", !4}
67+ // !4 = !{!5, !1834, ...}
68+ // !5 = !{!6, i32 33}
69+ // !6 = !DICompileUnit(...
70+ // ...
71+ // !1834 = !{!1835, i32 33}
72+ // !1835 = !DICompileUnit(...
73+ // ...
74+ //
75+ inline int32_t
76+ getSourceLangLiteralMDValue (const llvm::DICompileUnit *compileUnit,
77+ const llvm::Module *module ) {
78+ const auto flagName = " Source Lang Literal" ;
79+
80+ if (!module ->getModuleFlag (flagName)) {
81+ return SOURCE_LANG_LITERAL_MD_IS_NOT_PRESENT;
82+ }
83+
84+ auto node = llvm::dyn_cast<llvm::MDTuple>(module ->getModuleFlag (flagName));
85+ if (!node) {
86+ return getSourceLangLiteralMDValueLegacy (module );
87+ }
88+
89+ for (auto &op : node->operands ()) {
90+ auto entry = llvm::cast<llvm::MDTuple>(op);
91+ if (llvm::cast<llvm::DICompileUnit>(entry->getOperand (0 )) == compileUnit) {
92+ auto constant =
93+ llvm::cast<llvm::ConstantAsMetadata>(entry->getOperand (1 ));
94+ return int32_t (
95+ llvm::cast<llvm::ConstantInt>(constant->getValue ())->getZExtValue ());
96+ }
97+ }
98+
99+ return SOURCE_LANG_LITERAL_MD_IS_NOT_PRESENT;
100+ }
101+
102+ inline uint16_t getSourceLanguage (const llvm::DICompileUnit *compileUnit,
51103 const llvm::Module *module ) {
52- int32_t sourceLanguage = getSourceLangLiteralMDValue (* module );
104+ int32_t sourceLanguage = getSourceLangLiteralMDValue (compileUnit, module );
53105 if (sourceLanguage == SOURCE_LANG_LITERAL_MD_IS_NOT_PRESENT) {
54106 sourceLanguage = compileUnit->getSourceLanguage ();
55107 }
0 commit comments