Initial support for the Clang compiler and numerous warning fixes
This commit is contained in:
@@ -125,9 +125,20 @@ set (GCC_EXTRA_OPTIMIZATIONS "-ffast-math")
|
|||||||
if (LINUX)
|
if (LINUX)
|
||||||
set(CMAKE_SKIP_RPATH TRUE)
|
set(CMAKE_SKIP_RPATH TRUE)
|
||||||
|
|
||||||
|
add_definitions(
|
||||||
|
-DLL_LINUX=1
|
||||||
|
-D_REENTRANT
|
||||||
|
-fexceptions
|
||||||
|
-fno-math-errno
|
||||||
|
-fno-strict-aliasing
|
||||||
|
-fsigned-char
|
||||||
|
-g
|
||||||
|
-pthread
|
||||||
|
)
|
||||||
|
|
||||||
# Here's a giant hack for Fedora 8, where we can't use
|
# Here's a giant hack for Fedora 8, where we can't use
|
||||||
# _FORTIFY_SOURCE if we're using a compiler older than gcc 4.1.
|
# _FORTIFY_SOURCE if we're using a compiler older than gcc 4.1.
|
||||||
|
if(${CMAKE_C_COMPILER} MATCHES "gcc*")
|
||||||
find_program(GXX g++)
|
find_program(GXX g++)
|
||||||
mark_as_advanced(GXX)
|
mark_as_advanced(GXX)
|
||||||
|
|
||||||
@@ -166,7 +177,7 @@ if (LINUX)
|
|||||||
#Lets actually get a numerical version of gxx's version
|
#Lets actually get a numerical version of gxx's version
|
||||||
STRING(REGEX REPLACE ".* ([0-9])\\.([0-9])\\.([0-9]).*" "\\1\\2\\3" CXX_VERSION ${CXX_VERSION})
|
STRING(REGEX REPLACE ".* ([0-9])\\.([0-9])\\.([0-9]).*" "\\1\\2\\3" CXX_VERSION ${CXX_VERSION})
|
||||||
|
|
||||||
#gcc 4.3 and above don't like the LL boost
|
#gcc 4.3 and above doesn't like the LL boost
|
||||||
if(${CXX_VERSION} GREATER 429)
|
if(${CXX_VERSION} GREATER 429)
|
||||||
add_definitions(-Wno-parentheses)
|
add_definitions(-Wno-parentheses)
|
||||||
endif (${CXX_VERSION} GREATER 429)
|
endif (${CXX_VERSION} GREATER 429)
|
||||||
@@ -178,16 +189,8 @@ if (LINUX)
|
|||||||
|
|
||||||
# End of hacks.
|
# End of hacks.
|
||||||
|
|
||||||
add_definitions(
|
#GCC Specific
|
||||||
-DLL_LINUX=1
|
add_definitions(-DCC_GCC)
|
||||||
-D_REENTRANT
|
|
||||||
-fexceptions
|
|
||||||
-fno-math-errno
|
|
||||||
-fno-strict-aliasing
|
|
||||||
-fsigned-char
|
|
||||||
-g
|
|
||||||
-pthread
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
||||||
|
|
||||||
@@ -222,6 +225,52 @@ if (LINUX)
|
|||||||
set(CMAKE_C_FLAGS_RELEASESSE2 "-O3 ${CMAKE_C_FLAGS_RELEASESSE2}")
|
set(CMAKE_C_FLAGS_RELEASESSE2 "-O3 ${CMAKE_C_FLAGS_RELEASESSE2}")
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||||
|
|
||||||
|
elseif(${CMAKE_C_COMPILER} MATCHES "clang*")
|
||||||
|
|
||||||
|
find_program(CLANG clang++)
|
||||||
|
mark_as_advanced(CLANG)
|
||||||
|
|
||||||
|
add_definitions(
|
||||||
|
-DCC_CLANG
|
||||||
|
-D_FORTIFY_SOURCE=2
|
||||||
|
-Wno-gnu
|
||||||
|
-Wno-unused-function
|
||||||
|
-Wno-char-subscripts
|
||||||
|
-Wno-unused-variable
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
||||||
|
|
||||||
|
add_definitions(-DAPPID=secondlife)
|
||||||
|
add_definitions(-fvisibility=hidden)
|
||||||
|
# don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The viewer doesn't need to catch SIGCHLD anyway.
|
||||||
|
add_definitions(-DLL_IGNORE_SIGCHLD)
|
||||||
|
if (NOT STANDALONE)
|
||||||
|
# this stops us requiring a really recent glibc at runtime
|
||||||
|
add_definitions(-fno-stack-protector)
|
||||||
|
endif (NOT STANDALONE)
|
||||||
|
|
||||||
|
if (NOT STANDALONE)
|
||||||
|
set(MARCH_FLAG " -march=pentium4")
|
||||||
|
endif (NOT STANDALONE)
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse2")
|
||||||
|
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse2")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASESSE2 "${CMAKE_CXX_FLAGS_RELEASESSE2}${MARCH_FLAG} -msse2")
|
||||||
|
set(CMAKE_C_FLAGS_RELEASESSE2 "${CMAKE_C_FLAGS_RELEASESSE2}${MARCH_FLAG} -msse2")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2")
|
||||||
|
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2")
|
||||||
|
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "-O0 ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||||
|
set(CMAKE_C_FLAGS_DEBUG "-O0 ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "-O3 ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||||
|
set(CMAKE_C_FLAGS_RELEASE "-O3 ${CMAKE_C_FLAGS_RELEASE}")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASESSE2 "-O3 ${CMAKE_CXX_FLAGS_RELEASESSE2}")
|
||||||
|
set(CMAKE_C_FLAGS_RELEASESSE2 "-O3 ${CMAKE_C_FLAGS_RELEASESSE2}")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||||
|
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||||
|
endif()
|
||||||
endif (LINUX)
|
endif (LINUX)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <hash_map>
|
#include <hash_map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#elif LL_DARWIN || LL_LINUX
|
#elif LL_DARWIN || LL_LINUX
|
||||||
|
#if CC_GCC
|
||||||
# if GCC_VERSION >= 40300 // gcc 4.3 and up
|
# if GCC_VERSION >= 40300 // gcc 4.3 and up
|
||||||
# include <backward/hashtable.h>
|
# include <backward/hashtable.h>
|
||||||
# elif GCC_VERSION >= 30400 // gcc 3.4 and up
|
# elif GCC_VERSION >= 30400 // gcc 3.4 and up
|
||||||
@@ -48,6 +49,9 @@
|
|||||||
# else
|
# else
|
||||||
# include <hashtable.h>
|
# include <hashtable.h>
|
||||||
# endif
|
# endif
|
||||||
|
#elif CC_CLANG
|
||||||
|
# include <hashtable.h>
|
||||||
|
#endif
|
||||||
#elif LL_SOLARIS
|
#elif LL_SOLARIS
|
||||||
#include <ext/hashtable.h>
|
#include <ext/hashtable.h>
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ public:
|
|||||||
//is it here?
|
//is it here?
|
||||||
if (isInside(data->getPositionGroup()))
|
if (isInside(data->getPositionGroup()))
|
||||||
{
|
{
|
||||||
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
|
if (((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius())) ||
|
||||||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
|
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
|
||||||
{ //it belongs here
|
{ //it belongs here
|
||||||
#if LL_OCTREE_PARANOIA_CHECK
|
#if LL_OCTREE_PARANOIA_CHECK
|
||||||
|
|||||||
@@ -2097,7 +2097,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge
|
|||||||
|
|
||||||
generate();
|
generate();
|
||||||
|
|
||||||
if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE || mParams.getSculptType() == LL_SCULPT_TYPE_MESH)
|
if ((mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) || mParams.getSculptType() == LL_SCULPT_TYPE_MESH)
|
||||||
{
|
{
|
||||||
createVolumeFaces();
|
createVolumeFaces();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -688,7 +688,7 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
|
|||||||
|
|
||||||
// now, check to see if we've got a gap
|
// now, check to see if we've got a gap
|
||||||
U32 gap = 0;
|
U32 gap = 0;
|
||||||
if ((mPacketsInID == id))
|
if (mPacketsInID == id)
|
||||||
{
|
{
|
||||||
// nope! bump and wrap the counter, then return
|
// nope! bump and wrap the counter, then return
|
||||||
mPacketsInID++;
|
mPacketsInID++;
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ U32 LLXferManager::numActiveListEntries(LLXfer *list_head)
|
|||||||
|
|
||||||
while (list_head)
|
while (list_head)
|
||||||
{
|
{
|
||||||
if ((list_head->mStatus == e_LL_XFER_IN_PROGRESS))
|
if (list_head->mStatus == e_LL_XFER_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
num_entries++;
|
num_entries++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ bool LLDirIterator::Impl::next(std::string &fname)
|
|||||||
#else
|
#else
|
||||||
std::string name = mIter->path().filename();
|
std::string name = mIter->path().filename();
|
||||||
#endif
|
#endif
|
||||||
if (found = boost::regex_match(name, match, mFilterExp))
|
if ((found = boost::regex_match(name, match, mFilterExp)))
|
||||||
{
|
{
|
||||||
fname = name;
|
fname = name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2896,7 +2896,7 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self)
|
|||||||
BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position)
|
BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position)
|
||||||
{
|
{
|
||||||
// disallow pointing at attachments and avatars
|
// disallow pointing at attachments and avatars
|
||||||
if (object && (object->isAttachment() || object->isAvatar()) || gSavedSettings.getBOOL("DisablePointAtAndBeam"))
|
if ((object && (object->isAttachment() || object->isAvatar())) || gSavedSettings.getBOOL("DisablePointAtAndBeam"))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3428,7 +3428,7 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b
|
|||||||
|
|
||||||
//to cause appearance of the agent to be updated
|
//to cause appearance of the agent to be updated
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (result = gAgentWearables.moveWearable(item, closer_to_body))
|
if ((result = gAgentWearables.moveWearable(item, closer_to_body)))
|
||||||
{
|
{
|
||||||
gAgentAvatarp->wearableUpdated(item->getWearableType(), FALSE);
|
gAgentAvatarp->wearableUpdated(item->getWearableType(), FALSE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1436,7 +1436,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
|||||||
|
|
||||||
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
||||||
{
|
{
|
||||||
if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled())
|
if ((avatar->isSelf() && !gAgent.needsRenderAvatar()) || !gMeshRepo.meshRezEnabled())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
|
|||||||
if (mFilterOps.mFilterTypes == FILTERTYPE_UUID)
|
if (mFilterOps.mFilterTypes == FILTERTYPE_UUID)
|
||||||
{
|
{
|
||||||
mFilterOps.mFilterTypes &= ~FILTERTYPE_UUID;
|
mFilterOps.mFilterTypes &= ~FILTERTYPE_UUID;
|
||||||
mFilterOps.mFilterUUID == LLUUID::null;
|
//mFilterOps.mFilterUUID == LLUUID::null;
|
||||||
setModified(FILTER_RESTART);
|
setModified(FILTER_RESTART);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,8 +519,8 @@ void LLInventoryFilter::setHoursAgo(U32 hours)
|
|||||||
bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo;
|
bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo;
|
||||||
|
|
||||||
// *NOTE: need to cache last filter time, in case filter goes stale
|
// *NOTE: need to cache last filter time, in case filter goes stale
|
||||||
BOOL less_restrictive = (are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo)) || !hours);
|
BOOL less_restrictive = ((are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo))) || !hours);
|
||||||
BOOL more_restrictive = (are_date_limits_valid && (!is_increasing && hours) || is_increasing_from_zero);
|
BOOL more_restrictive = ((are_date_limits_valid && (!is_increasing && hours)) || is_increasing_from_zero);
|
||||||
|
|
||||||
mFilterOps.mHoursAgo = hours;
|
mFilterOps.mHoursAgo = hours;
|
||||||
mFilterOps.mMinDate = time_min();
|
mFilterOps.mMinDate = time_min();
|
||||||
|
|||||||
@@ -478,10 +478,10 @@ void LLPanelObject::getState( )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// can move or rotate only linked group with move permissions, or sub-object with move and modify perms
|
// can move or rotate only linked group with move permissions, or sub-object with move and modify perms
|
||||||
BOOL enable_move = objectp->permMove() && (!objectp->isAttachment() && objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
|
BOOL enable_move = objectp->permMove() && ((!objectp->isAttachment() && objectp->permModify()) || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||||
BOOL enable_scale = objectp->permMove() && objectp->permModify();
|
BOOL enable_scale = objectp->permMove() && objectp->permModify();
|
||||||
BOOL enable_rotate = objectp->permMove() && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
|
BOOL enable_rotate = objectp->permMove() && ((objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||||
BOOL enable_link = objectp->permMove() && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
|
BOOL enable_link = objectp->permMove() && ((!objectp->isAttachment() && objectp->permModify()) || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||||
childSetEnabled("build_math_constants",true);
|
childSetEnabled("build_math_constants",true);
|
||||||
S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
|
S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
|
||||||
BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
|
BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ void LLPreviewSound::playAmbient( void* userdata )
|
|||||||
|
|
||||||
if(item && gAudiop)
|
if(item && gAudiop)
|
||||||
{
|
{
|
||||||
int gain = 0.01f;
|
F32 gain = 0.01f;
|
||||||
for(int i = 0; i < 2; i++)
|
for(int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
gMessageSystem->newMessageFast(_PREHASH_SoundTrigger);
|
gMessageSystem->newMessageFast(_PREHASH_SoundTrigger);
|
||||||
|
|||||||
@@ -675,7 +675,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
|
|||||||
const LLPickInfo& pick = gViewerWindow->getHoverPick();
|
const LLPickInfo& pick = gViewerWindow->getHoverPick();
|
||||||
object = pick.getObject();
|
object = pick.getObject();
|
||||||
if ( (object) && (rlv_handler_t::isEnabled()) &&
|
if ( (object) && (rlv_handler_t::isEnabled()) &&
|
||||||
( ((gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH))) && (!gRlvHandler.canTouch(object, pick.mObjectOffset)) ||
|
( (((gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH))) && (!gRlvHandler.canTouch(object, pick.mObjectOffset))) ||
|
||||||
((gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) && (!object->isHUDAttachment())) ) )
|
((gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) && (!object->isHUDAttachment())) ) )
|
||||||
{
|
{
|
||||||
gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
|
gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
|
||||||
|
|||||||
@@ -5332,7 +5332,7 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
|
|||||||
if (object)
|
if (object)
|
||||||
{
|
{
|
||||||
LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation());
|
LLVector3 sit_spot = object->getPositionAgent() + (sitPosition * object->getRotation());
|
||||||
if (!use_autopilot || isAgentAvatarValid() && gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == object->getRoot())
|
if (!use_autopilot || (isAgentAvatarValid() && gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == object->getRoot()))
|
||||||
{
|
{
|
||||||
//we're already sitting on this object, so don't autopilot
|
//we're already sitting on this object, so don't autopilot
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -762,7 +762,7 @@ void LLViewerParcelMedia::filterMedia(LLParcel* parcel, U32 type)
|
|||||||
|
|
||||||
if (media_url.empty())
|
if (media_url.empty())
|
||||||
{
|
{
|
||||||
media_action == "allow";
|
media_action = "allow";
|
||||||
}
|
}
|
||||||
else if (!sMediaFilterListLoaded || sDeniedMedia.count(domain) || sDeniedMedia.count(ip))
|
else if (!sMediaFilterListLoaded || sDeniedMedia.count(domain) || sDeniedMedia.count(ip))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3430,7 +3430,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vobj->isMesh() &&
|
if (vobj->isMesh() &&
|
||||||
(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
|
((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -4152,7 +4152,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //resize pre-existing buffer
|
{ //resize pre-existing buffer
|
||||||
if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage ||
|
if ((LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage) ||
|
||||||
buffer->getTypeMask() != mask)
|
buffer->getTypeMask() != mask)
|
||||||
{
|
{
|
||||||
buffer = createVertexBuffer(mask, buffer_usage);
|
buffer = createVertexBuffer(mask, buffer_usage);
|
||||||
|
|||||||
Reference in New Issue
Block a user