Commit 6f126055 by Nicolas Capens Committed by Nicolas Capens

Fix -Wundefined-var-template warnings

This warning, which we treat as an error, occurs when a static member of an implicitly instatiated template class is referenced, but there is no definition available in the current translation unit. Note that with a non-template class this isn't a problem, since there can only be one definition, which is expected to be resolved at link time. But with a template class each instantiation can have a different static member variable definition. This warning typically occurs when the definition is available in another translation unit, so it may be tempting to move that definition into the header file to make it available to any translation unit where the static member may be referenced. However, this typically leads to multiple-definition errors. Like all multiple-definition errors, we can address that by declaring, not defining, the variable in the header, and leaving the definition in one translation unit. In the case of a non-template class the declaration in the class definition suffices since it's fully instantiated, but for a template class we need to re-declare the static member for the explicit instantiation. Concretely, in this case Subzero has a template class for x86 instructions, with a static member for the Opcode string. This string is different for each instantiation of the instruction template, so we need to forward-declare each instantiated class's static member in the header. There's already a macro for the definitions, which is repurposed for declaring the instantiated members in the header. Note that the C++ reference states that "An explicit specialization of a static data member of a template is a definition if the declaration includes an initializer; otherwise, it is a declaration." (https://en.cppreference.com/w/cpp/language/template_specialization) But Visual Studio treats them as definitions anyway, leading to multiple-definition errors. Note that we can't add 'extern' to explicitly make it a declaration only, because storage-class specifiers are not valid for class members. So we just omit the declaration for compilers other than Clang, which don't have this warning enabled anyway. Bug: chromium:604888 Change-Id: I63b58ecdf956ff264e6d25738684b513f05b268b Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/55208 Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 07fd995b
......@@ -474,7 +474,6 @@ else()
"-Wno-unneeded-internal-declaration" # function 'X' is not needed and will not be emitted
"-Wno-unused-private-field" # private field 'offset' is not used - TODO: Consider enabling this once Vulkan is further implemented.
"-Wno-comment" # multi-line comment
"-Wno-undefined-var-template" # instantiation of variable 'X' required here, but no definition is available
"-Wno-extra-semi" # extra ';' after member function definition
"-Wno-unused-parameter" # unused parameter 'X'
......
......@@ -34,4 +34,6 @@
#include "IceOperand.h"
#include "IceTargetLoweringX8632Traits.h"
X86INSTS_DECLARE_STATIC_DATA(X8632, X8632::Traits)
#endif // SUBZERO_SRC_ICEINSTX8632_H
......@@ -32,4 +32,6 @@
#include "IceOperand.h"
#include "IceTargetLoweringX8664Traits.h"
X86INSTS_DECLARE_STATIC_DATA(X8664, X8664::Traits)
#endif // SUBZERO_SRC_ICEINSTX8664_H
......@@ -80,6 +80,33 @@ private:
}
};
// The -Wundefined-var-template warning requires to forward-declare static
// members of template class specializations. Note that "An explicit
// specialization of a static data member of a template is a definition if the
// declaration includes an initializer; otherwise, it is a declaration."
// Visual Studio has a bug which treats these declarations as definitions,
// leading to multiple definition errors. Since we only enable
// -Wundefined-var-template for Clang, omit these declarations on other
// compilers.
#if defined(__clang__)
template <>
std::array<SmallBitVector, RCX86_NUM>
TargetX86Base<X8632::Traits>::TypeToRegisterSet;
template <>
std::array<SmallBitVector, RCX86_NUM>
TargetX86Base<X8632::Traits>::TypeToRegisterSetUnfiltered;
template <>
std::array<SmallBitVector,
TargetX86Base<X8632::Traits>::Traits::RegisterSet::Reg_NUM>
TargetX86Base<X8632::Traits>::RegisterAliases;
template <> FixupKind TargetX86Base<X8632::Traits>::PcRelFixup;
template <> FixupKind TargetX86Base<X8632::Traits>::AbsFixup;
#endif // defined(__clang__)
} // end of namespace X8632
} // end of namespace Ice
......
......@@ -85,6 +85,33 @@ private:
}
};
// The -Wundefined-var-template warning requires to forward-declare static
// members of template class specializations. Note that "An explicit
// specialization of a static data member of a template is a definition if the
// declaration includes an initializer; otherwise, it is a declaration."
// Visual Studio has a bug which treats these declarations as definitions,
// leading to multiple definition errors. Since we only enable
// -Wundefined-var-template for Clang, omit these declarations on other
// compilers.
#if defined(__clang__)
template <>
std::array<SmallBitVector, RCX86_NUM>
TargetX86Base<X8664::Traits>::TypeToRegisterSet;
template <>
std::array<SmallBitVector, RCX86_NUM>
TargetX86Base<X8664::Traits>::TypeToRegisterSetUnfiltered;
template <>
std::array<SmallBitVector,
TargetX86Base<X8664::Traits>::Traits::RegisterSet::Reg_NUM>
TargetX86Base<X8664::Traits>::RegisterAliases;
template <> FixupKind TargetX86Base<X8664::Traits>::PcRelFixup;
template <> FixupKind TargetX86Base<X8664::Traits>::AbsFixup;
#endif
} // end of namespace X8664
} // end of namespace Ice
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment