mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Allow some warnings during specialization
This commit is contained in:
parent
487ef16efd
commit
d593488591
5 changed files with 188 additions and 138 deletions
|
@ -173,6 +173,10 @@ namespace System
|
|||
// or the memory would already be registered with the GC
|
||||
}
|
||||
|
||||
public static mixin Mark<T>(T val)
|
||||
{
|
||||
}
|
||||
|
||||
public static mixin Mark<TSizedArray, T, Size>(TSizedArray val) where Size : const int where TSizedArray : SizedArray<T, Size>
|
||||
{
|
||||
#if BF_ENABLE_REALTIME_LEAK_CHECK
|
||||
|
|
|
@ -2844,65 +2844,9 @@ bool BfModule::IsSkippingExtraResolveChecks()
|
|||
return mCompiler->IsSkippingExtraResolveChecks();
|
||||
}
|
||||
|
||||
BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPersistent, bool deferError)
|
||||
bool BfModule::AddErrorContext(StringImpl& errorString, BfAstNode* refNode, bool& isWhileSpecializing)
|
||||
{
|
||||
BP_ZONE("BfModule::Fail");
|
||||
|
||||
if (mIgnoreErrors)
|
||||
{
|
||||
mHadIgnoredError = true;
|
||||
if (mAttributeState != NULL)
|
||||
mAttributeState->mFlags = (BfAttributeState::Flags)(mAttributeState->mFlags | BfAttributeState::Flag_HadError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!mReportErrors)
|
||||
{
|
||||
mCompiler->mPassInstance->SilentFail();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (refNode != NULL)
|
||||
refNode = BfNodeToNonTemporary(refNode);
|
||||
|
||||
//BF_ASSERT(refNode != NULL);
|
||||
|
||||
if (mIsComptimeModule)
|
||||
{
|
||||
if ((mCompiler->mCEMachine->mCurContext != NULL) && (mCompiler->mCEMachine->mCurContext->mCurTargetSrc != NULL))
|
||||
{
|
||||
BfError* bfError = mCompiler->mPassInstance->Fail("Comptime method generation had errors", mCompiler->mCEMachine->mCurContext->mCurTargetSrc);
|
||||
if (bfError != NULL)
|
||||
mCompiler->mPassInstance->MoreInfo(error, refNode);
|
||||
return bfError;
|
||||
}
|
||||
|
||||
mHadBuildError = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mCurMethodInstance != NULL)
|
||||
mCurMethodInstance->mHasFailed = true;
|
||||
|
||||
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
|
||||
return NULL;
|
||||
|
||||
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsOrInUnspecializedVariation()))
|
||||
return NULL; // Ignore errors on unspecialized variations, they are always dups
|
||||
if (!mHadBuildError)
|
||||
mHadBuildError = true;
|
||||
if (mParentModule != NULL)
|
||||
mParentModule->mHadBuildError = true;
|
||||
|
||||
if (mCurTypeInstance != NULL)
|
||||
AddFailType(mCurTypeInstance);
|
||||
|
||||
BfLogSysM("BfModule::Fail module %p type %p %s\n", this, mCurTypeInstance, error.c_str());
|
||||
|
||||
String errorString = error;
|
||||
bool isWhileSpecializing = false;
|
||||
bool isWhileSpecializingMethod = false;
|
||||
|
||||
if ((mIsSpecialModule) && (mModuleName == "vdata"))
|
||||
errorString += StrFormat("\n while generating vdata for project '%s'", mProject->mName.c_str());
|
||||
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend))
|
||||
|
@ -2975,7 +2919,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
|||
|
||||
hadMethodInstance = true;
|
||||
if (!_CheckMethodInstance(methodInstance))
|
||||
return NULL;
|
||||
return false;
|
||||
checkMethodState = checkMethodState->mPrevMethodState;
|
||||
}
|
||||
}
|
||||
|
@ -2983,21 +2927,83 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
|||
if ((!hadMethodInstance) && (mCurMethodInstance != NULL))
|
||||
{
|
||||
if (!_CheckMethodInstance(mCurMethodInstance))
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BfError* bfError = NULL;
|
||||
|
||||
if (isWhileSpecializing)
|
||||
deferError = true;
|
||||
|
||||
if ((!isWhileSpecializing) && (mCurTypeInstance != NULL) && ((mCurTypeInstance->IsGenericTypeInstance()) && (!mCurTypeInstance->IsUnspecializedType())))
|
||||
{
|
||||
errorString += StrFormat("\n while specializing type '%s'", TypeToString(mCurTypeInstance).c_str());
|
||||
isWhileSpecializing = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPersistent, bool deferError)
|
||||
{
|
||||
BP_ZONE("BfModule::Fail");
|
||||
|
||||
if (mIgnoreErrors)
|
||||
{
|
||||
mHadIgnoredError = true;
|
||||
if (mAttributeState != NULL)
|
||||
mAttributeState->mFlags = (BfAttributeState::Flags)(mAttributeState->mFlags | BfAttributeState::Flag_HadError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!mReportErrors)
|
||||
{
|
||||
mCompiler->mPassInstance->SilentFail();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (refNode != NULL)
|
||||
refNode = BfNodeToNonTemporary(refNode);
|
||||
|
||||
//BF_ASSERT(refNode != NULL);
|
||||
|
||||
if (mIsComptimeModule)
|
||||
{
|
||||
if ((mCompiler->mCEMachine->mCurContext != NULL) && (mCompiler->mCEMachine->mCurContext->mCurTargetSrc != NULL))
|
||||
{
|
||||
BfError* bfError = mCompiler->mPassInstance->Fail("Comptime method generation had errors", mCompiler->mCEMachine->mCurContext->mCurTargetSrc);
|
||||
if (bfError != NULL)
|
||||
mCompiler->mPassInstance->MoreInfo(error, refNode);
|
||||
return bfError;
|
||||
}
|
||||
|
||||
mHadBuildError = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mCurMethodInstance != NULL)
|
||||
mCurMethodInstance->mHasFailed = true;
|
||||
|
||||
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
|
||||
return NULL;
|
||||
|
||||
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsOrInUnspecializedVariation()))
|
||||
return NULL; // Ignore errors on unspecialized variations, they are always dups
|
||||
if (!mHadBuildError)
|
||||
mHadBuildError = true;
|
||||
if (mParentModule != NULL)
|
||||
mParentModule->mHadBuildError = true;
|
||||
|
||||
if (mCurTypeInstance != NULL)
|
||||
AddFailType(mCurTypeInstance);
|
||||
|
||||
BfLogSysM("BfModule::Fail module %p type %p %s\n", this, mCurTypeInstance, error.c_str());
|
||||
|
||||
String errorString = error;
|
||||
bool isWhileSpecializing = false;
|
||||
if (!AddErrorContext(errorString, refNode, isWhileSpecializing))
|
||||
return false;
|
||||
|
||||
BfError* bfError = NULL;
|
||||
if (isWhileSpecializing)
|
||||
deferError = true;
|
||||
|
||||
if (!mHadBuildError)
|
||||
mHadBuildError = true;
|
||||
|
||||
|
@ -3085,7 +3091,7 @@ BfError* BfModule::FailAfter(const StringImpl& error, BfAstNode* refNode)
|
|||
return bfError;
|
||||
}
|
||||
|
||||
BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode, bool isPersistent)
|
||||
BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode, bool isPersistent, bool showInSpecialized)
|
||||
{
|
||||
if (mIgnoreErrors || mIgnoreWarnings)
|
||||
return NULL;
|
||||
|
@ -3118,16 +3124,28 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re
|
|||
if (mCurMethodInstance != NULL)
|
||||
{
|
||||
if (mCurMethodInstance->IsSpecializedGenericMethodOrType())
|
||||
{
|
||||
if (!showInSpecialized)
|
||||
return NULL;
|
||||
}
|
||||
if (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend)
|
||||
return NULL; // No ctorCalcAppend warnings
|
||||
}
|
||||
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsSpecializedType()))
|
||||
{
|
||||
if (!showInSpecialized)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (refNode != NULL)
|
||||
refNode = BfNodeToNonTemporary(refNode);
|
||||
|
||||
String warningString = warning;
|
||||
bool isWhileSpecializing = false;
|
||||
if (!AddErrorContext(warningString, refNode, isWhileSpecializing))
|
||||
return false;
|
||||
bool deferWarning = isWhileSpecializing;
|
||||
|
||||
if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL))
|
||||
{
|
||||
// We used to bubble up warnings into the mixin injection site, BUT
|
||||
|
@ -3139,17 +3157,18 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re
|
|||
{
|
||||
BfError* bfError = mCompiler->mPassInstance->Warn(warningNum, "Emitted code had errors", mCurMethodState->mEmitRefNode);
|
||||
if (bfError != NULL)
|
||||
mCompiler->mPassInstance->MoreInfo(warning, refNode);
|
||||
mCompiler->mPassInstance->MoreInfo(warningString, refNode);
|
||||
return bfError;
|
||||
}
|
||||
|
||||
BfError* bfError;
|
||||
if (refNode != NULL)
|
||||
bfError = mCompiler->mPassInstance->WarnAt(warningNum, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
|
||||
bfError = mCompiler->mPassInstance->WarnAt(warningNum, warningString, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
|
||||
else
|
||||
bfError = mCompiler->mPassInstance->Warn(warningNum, warning);
|
||||
bfError = mCompiler->mPassInstance->Warn(warningNum, warningString);
|
||||
if (bfError != NULL)
|
||||
{
|
||||
bfError->mIsWhileSpecializing = isWhileSpecializing;
|
||||
bfError->mProject = mProject;
|
||||
AddFailType(mCurTypeInstance);
|
||||
|
||||
|
@ -3229,7 +3248,7 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan
|
|||
if (isError)
|
||||
error = Fail(err, targetSrc);
|
||||
else
|
||||
error = Warn(0, err, targetSrc);
|
||||
error = Warn(0, err, targetSrc, false, true);
|
||||
if (error != NULL)
|
||||
_AddDeclarationMoreInfo();
|
||||
}
|
||||
|
@ -3262,7 +3281,7 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan
|
|||
if (str != NULL)
|
||||
err += *str;
|
||||
err += "'";
|
||||
if (Warn(0, err, targetSrc) != NULL)
|
||||
if (Warn(0, err, targetSrc, false, true) != NULL)
|
||||
_AddDeclarationMoreInfo();
|
||||
}
|
||||
}
|
||||
|
@ -7590,7 +7609,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
|||
if (origCheckArgType->IsRef())
|
||||
origCheckArgType = origCheckArgType->GetUnderlyingType();
|
||||
|
||||
bool argMayBeReferenceType = false;
|
||||
bool argIsReferenceType = false;
|
||||
|
||||
int checkGenericParamFlags = 0;
|
||||
if (checkArgType->IsGenericParam())
|
||||
|
@ -7600,18 +7619,18 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
|||
if (checkGenericParamInst->mTypeConstraint != NULL)
|
||||
checkArgType = checkGenericParamInst->mTypeConstraint;
|
||||
|
||||
if ((checkGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0)
|
||||
{
|
||||
argMayBeReferenceType = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
argMayBeReferenceType = true;
|
||||
}
|
||||
// if ((checkGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0)
|
||||
// {
|
||||
// argMayBeReferenceType = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// argMayBeReferenceType = true;
|
||||
// }
|
||||
}
|
||||
|
||||
if (checkArgType->IsObjectOrInterface())
|
||||
argMayBeReferenceType = true;
|
||||
argIsReferenceType = true;
|
||||
|
||||
BfTypeInstance* typeConstraintInst = NULL;
|
||||
if (genericParamInst->mTypeConstraint != NULL)
|
||||
|
@ -7636,7 +7655,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
|||
}
|
||||
|
||||
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Class) &&
|
||||
((checkGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Var)) == 0) && (!argMayBeReferenceType))
|
||||
((checkGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Var)) == 0) && (!argIsReferenceType))
|
||||
{
|
||||
if ((!ignoreErrors) && (PreFail()))
|
||||
*errorOut = Fail(StrFormat("The type '%s' must be a reference type in order to use it as parameter '%s' for '%s'",
|
||||
|
|
|
@ -1517,10 +1517,11 @@ public:
|
|||
void SetFail();
|
||||
void VerifyOnDemandMethods();
|
||||
bool IsSkippingExtraResolveChecks();
|
||||
bool AddErrorContext(StringImpl& errorString, BfAstNode* refNode, bool& isWhileSpecializing);
|
||||
BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false, bool deferError = false);
|
||||
BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL);
|
||||
BfError* FailAfter(const StringImpl& error, BfAstNode* refNode);
|
||||
BfError* Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode = NULL, bool isPersistent = false);
|
||||
BfError* Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode = NULL, bool isPersistent = false, bool showInSpecialized = false);
|
||||
void CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstance* methodInstance, BfCustomAttributes* customAttributes, BfAstNode* targetSrc);
|
||||
void CheckRangeError(BfType* type, BfAstNode* refNode);
|
||||
bool CheckCircularDataError();
|
||||
|
|
|
@ -1589,7 +1589,7 @@ void BfPassInstance::SilentFail()
|
|||
mFailedIdx++;
|
||||
}
|
||||
|
||||
BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen)
|
||||
BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen, bool isDeferred)
|
||||
{
|
||||
mLastWasAdded = false;
|
||||
if ((int) mErrors.size() >= sMaxErrors)
|
||||
|
@ -1599,7 +1599,7 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
|
|||
if ((bfParser != NULL) && (warningNumber > 0) && (!bfParser->IsWarningEnabledAtSrcIndex(warningNumber, srcIdx)))
|
||||
return NULL;
|
||||
|
||||
if (!WantsRangeRecorded(bfParser, srcIdx, srcLen, true))
|
||||
if (!WantsRangeRecorded(bfParser, srcIdx, srcLen, true, isDeferred))
|
||||
return NULL;
|
||||
|
||||
mWarnIdx++;
|
||||
|
@ -1614,12 +1614,15 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
|
|||
errorVal->mError = warning;
|
||||
errorVal->mSrcStart = srcIdx;
|
||||
errorVal->mSrcEnd = srcIdx + srcLen;
|
||||
errorVal->mIsDeferred = isDeferred;
|
||||
FixSrcStartAndEnd(bfSource, errorVal->mSrcStart, errorVal->mSrcEnd);
|
||||
mErrorSet.Add(BfErrorEntry(errorVal));
|
||||
mErrors.push_back(errorVal);
|
||||
++mWarningCount;
|
||||
mLastWasAdded = true;
|
||||
|
||||
if (!isDeferred)
|
||||
{
|
||||
mLastWasDisplayed = WantsRangeDisplayed(bfParser, srcIdx, srcLen, true);
|
||||
if (mLastWasDisplayed)
|
||||
{
|
||||
|
@ -1630,6 +1633,7 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
|
|||
errorStart += StrFormat(": BF%04d", warningNumber);
|
||||
MessageAt(":warn", errorStart + ": " + warning, bfParser, srcIdx);
|
||||
}
|
||||
}
|
||||
return errorVal;
|
||||
}
|
||||
|
||||
|
@ -1645,7 +1649,7 @@ BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode)
|
||||
BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode, bool isDeferred)
|
||||
{
|
||||
BP_ZONE("BfPassInstance::Warn");
|
||||
|
||||
|
@ -1666,7 +1670,7 @@ BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAs
|
|||
}
|
||||
|
||||
if (refNode != NULL)
|
||||
return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
|
||||
return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength(), isDeferred);
|
||||
else
|
||||
return Warn(warningNumber, warning);
|
||||
}
|
||||
|
@ -1798,15 +1802,39 @@ void BfPassInstance::TryFlushDeferredError()
|
|||
// This can happen in the case of an internal compiler error, where we believe we've satisfied
|
||||
// generic constraints but we generate an error on the specialization but not the unspecialized version
|
||||
bool hasDisplayedError = false;
|
||||
bool hasDisplayedWarning = false;
|
||||
for (int pass = 0; pass < 2; pass++)
|
||||
{
|
||||
for (auto& error : mErrors)
|
||||
{
|
||||
if (!error->mIsWarning)
|
||||
if (error->mIsWarning)
|
||||
{
|
||||
if (!error->mIsDeferred)
|
||||
hasDisplayedWarning = true;
|
||||
else if ((pass == 1) && (!hasDisplayedWarning))
|
||||
{
|
||||
String errorText = "WARNING ";
|
||||
if (error->mWarningNumber > 0)
|
||||
errorText += StrFormat(": BF%04d", error->mWarningNumber);
|
||||
errorText += ": ";
|
||||
errorText += error->mError;
|
||||
|
||||
MessageAt(":warning", errorText, error->mSource, error->mSrcStart, error->mSrcEnd - error->mSrcStart);
|
||||
|
||||
for (auto moreInfo : error->mMoreInfo)
|
||||
{
|
||||
if (moreInfo->mSource != NULL)
|
||||
MessageAt(":warning", " > " + moreInfo->mInfo, moreInfo->mSource, moreInfo->mSrcStart, moreInfo->mSrcEnd - moreInfo->mSrcStart);
|
||||
else
|
||||
OutputLine(":warning " + moreInfo->mInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!error->mIsDeferred)
|
||||
hasDisplayedError = true;
|
||||
else if (pass == 1)
|
||||
else if ((pass == 1) && (!hasDisplayedError))
|
||||
{
|
||||
MessageAt(":error", "ERROR: " + error->mError, error->mSource, error->mSrcStart, error->mSrcEnd - error->mSrcStart);
|
||||
|
||||
|
@ -1820,9 +1848,6 @@ void BfPassInstance::TryFlushDeferredError()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((pass == 0) && (hasDisplayedError))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1383,9 +1383,10 @@ public:
|
|||
void MessageAt(const StringImpl& msgPrefix, const StringImpl& error, BfSourceData* bfSource, int srcIdx, int srcLen = 1, BfFailFlags flags = BfFailFlag_None);
|
||||
void FixSrcStartAndEnd(BfSourceData* source, int& startIdx, int& endIdx);
|
||||
|
||||
BfError* WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen = 1);
|
||||
BfError* WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen = 1, bool isDeferred = false);
|
||||
BfError* Warn(int warningNumber, const StringImpl& warning);
|
||||
BfError* Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
|
||||
BfError* Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode, bool isDeferred = false);
|
||||
BfError* DeferWarn(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
|
||||
BfError* WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
|
||||
BfError* WarnAfterAt(int warningNumber, const StringImpl& error, BfSourceData* bfSource, int srcIdx);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue