|
@@ -5146,6 +5146,27 @@ bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const {
|
|
!VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit();
|
|
!VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ASTContext::InlineVariableDefinitionKind
|
|
|
|
+ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const {
|
|
|
|
+ if (!VD->isInline())
|
|
|
|
+ return InlineVariableDefinitionKind::None;
|
|
|
|
+
|
|
|
|
+ // In almost all cases, it's a weak definition.
|
|
|
|
+ auto *First = VD->getFirstDecl();
|
|
|
|
+ if (!First->isConstexpr() || First->isInlineSpecified() ||
|
|
|
|
+ !VD->isStaticDataMember())
|
|
|
|
+ return InlineVariableDefinitionKind::Weak;
|
|
|
|
+
|
|
|
|
+ // If there's a file-context declaration in this translation unit, it's a
|
|
|
|
+ // non-discardable definition.
|
|
|
|
+ for (auto *D : VD->redecls())
|
|
|
|
+ if (D->getLexicalDeclContext()->isFileContext())
|
|
|
|
+ return InlineVariableDefinitionKind::Strong;
|
|
|
|
+
|
|
|
|
+ // If we've not seen one yet, we don't know.
|
|
|
|
+ return InlineVariableDefinitionKind::WeakUnknown;
|
|
|
|
+}
|
|
|
|
+
|
|
static inline
|
|
static inline
|
|
std::string charUnitsToString(const CharUnits &CU) {
|
|
std::string charUnitsToString(const CharUnits &CU) {
|
|
return llvm::itostr(CU.getQuantity());
|
|
return llvm::itostr(CU.getQuantity());
|
|
@@ -8494,9 +8515,21 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
|
|
if (Context.isMSStaticDataMemberInlineDefinition(VD))
|
|
if (Context.isMSStaticDataMemberInlineDefinition(VD))
|
|
return GVA_DiscardableODR;
|
|
return GVA_DiscardableODR;
|
|
|
|
|
|
- GVALinkage StrongLinkage = GVA_StrongExternal;
|
|
|
|
- if (VD->isInline())
|
|
|
|
|
|
+ // Most non-template variables have strong linkage; inline variables are
|
|
|
|
+ // linkonce_odr or (occasionally, for compatibility) weak_odr.
|
|
|
|
+ GVALinkage StrongLinkage;
|
|
|
|
+ switch (Context.getInlineVariableDefinitionKind(VD)) {
|
|
|
|
+ case ASTContext::InlineVariableDefinitionKind::None:
|
|
|
|
+ StrongLinkage = GVA_StrongExternal;
|
|
|
|
+ break;
|
|
|
|
+ case ASTContext::InlineVariableDefinitionKind::Weak:
|
|
|
|
+ case ASTContext::InlineVariableDefinitionKind::WeakUnknown:
|
|
StrongLinkage = GVA_DiscardableODR;
|
|
StrongLinkage = GVA_DiscardableODR;
|
|
|
|
+ break;
|
|
|
|
+ case ASTContext::InlineVariableDefinitionKind::Strong:
|
|
|
|
+ StrongLinkage = GVA_StrongODR;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
|
|
switch (VD->getTemplateSpecializationKind()) {
|
|
switch (VD->getTemplateSpecializationKind()) {
|
|
case TSK_Undeclared:
|
|
case TSK_Undeclared:
|