<commit_before>// This code is licensed under the New BSD license.
// See LICENSE.txt for more details.
#include <iostream>

#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Host.h"

#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"

#include "clang/Basic/LangOptions.h"
#include "clang/Basic/FileSystemOptions.h"

#include "clang/Basic/SourceManager.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/FileManager.h"

#include "clang/Frontend/HeaderSearchOptions.h"
#include "clang/Frontend/Utils.h"

#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"

#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/PreprocessorOptions.h"
#include "clang/Frontend/FrontendOptions.h"

#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Builtins.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Sema/Sema.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Type.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Ownership.h"
#include "clang/AST/DeclGroup.h"

#include "clang/Parse/Parser.h"

#include "clang/Parse/ParseAST.h"

class MyASTConsumer : public clang::ASTConsumer
{
public:
  clang::SourceManager *aSourceManager;
  MyASTConsumer(clang::SourceManager *sourceManager) : clang::ASTConsumer(), aSourceManager(sourceManager) { }
    virtual ~MyASTConsumer() { }

    virtual void HandleTopLevelDecl( clang::DeclGroupRef d)
    {
        static int count = 0;
        clang::DeclGroupRef::iterator it;
        for( it = d.begin(); it != d.end(); it++)
        {
            count++;
            clang::ObjCInterfaceDecl *vdc = dyn_cast<clang::ObjCInterfaceDecl>(*it);
            if (!vdc)
            {
              continue;
            }

            std::cout << "Classname: " << vdc->getNameAsString() << " LineNum: " << aSourceManager->getInstantiationLineNumber(vdc->getClassLoc()) << " Filename: " <<  aSourceManager->getBufferName(vdc->getClassLoc()) << std::endl;
        }
    }
};

int main()
{
	clang::DiagnosticOptions diagnosticOptions;
	clang::TextDiagnosticPrinter *pTextDiagnosticPrinter =
		new clang::TextDiagnosticPrinter(
			llvm::outs(),
			diagnosticOptions);
	llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs;
	clang::Diagnostic diagnostic(pDiagIDs, pTextDiagnosticPrinter);

	clang::LangOptions languageOptions;
        languageOptions.ObjC1 = 1;
        languageOptions.ObjC2 = 1;
	clang::FileSystemOptions fileSystemOptions;
	clang::FileManager fileManager(fileSystemOptions);

	clang::SourceManager sourceManager(
        diagnostic,
        fileManager);
	clang::HeaderSearch headerSearch(fileManager);

	clang::HeaderSearchOptions headerSearchOptions;
	// <Warning!!> -- Platform Specific Code lives here
	// This depends on A) that you're running linux and
	// B) that you have the same GCC LIBs installed that
	// I do.
	// Search through Clang itself for something like this,
	// go on, you won't find it. The reason why is Clang
	// has its own versions of std* which are installed under
	// /usr/local/lib/clang/<version>/include/
	// See somewhere around Driver.cpp:77 to see Clang adding
	// its version of the headers to its include path.
	headerSearchOptions.AddPath("/usr/include/linux",
			clang::frontend::Angled,
			false,
			false,
			false);

	headerSearchOptions.AddPath("/usr/include/c++/4.4/tr1",
			clang::frontend::Angled,
			false,
			false,
			false);
	headerSearchOptions.AddPath("/usr/include/c++/4.4",
			clang::frontend::Angled,
			false,
			false,
			false);
	// </Warning!!> -- End of Platform Specific Code

	clang::TargetOptions targetOptions;
	targetOptions.Triple = llvm::sys::getHostTriple();

	clang::TargetInfo *pTargetInfo =
		clang::TargetInfo::CreateTargetInfo(
			diagnostic,
			targetOptions);

	clang::ApplyHeaderSearchOptions(
		headerSearch,
		headerSearchOptions,
		languageOptions,
		pTargetInfo->getTriple());

	clang::Preprocessor preprocessor(
		diagnostic,
		languageOptions,
		*pTargetInfo,
		sourceManager,
		headerSearch);

	clang::PreprocessorOptions preprocessorOptions;
	clang::FrontendOptions frontendOptions;
	clang::InitializePreprocessor(
		preprocessor,
		preprocessorOptions,
		headerSearchOptions,
		frontendOptions);

	const clang::FileEntry *pFile = fileManager.getFile(
        "DCILatLon.m");
	sourceManager.createMainFileID(pFile);
	//preprocessor.EnterMainSourceFile();

    const clang::TargetInfo &targetInfo = *pTargetInfo;

    clang::IdentifierTable identifierTable(languageOptions);
    clang::SelectorTable selectorTable;

    clang::Builtin::Context builtinContext(targetInfo);
    clang::ASTContext astContext(
        languageOptions,
        sourceManager,
        targetInfo,
        identifierTable,
        selectorTable,
        builtinContext,
        0 /* size_reserve*/);
   // clang::ASTConsumer astConsumer;
    MyASTConsumer astConsumer(&sourceManager);

    clang::Sema sema(
        preprocessor,
        astContext,
        astConsumer);
    sema.Initialize();

   //MySemanticAnalisys mySema( preprocessor, astContext, astConsumer);

    //clang::Parser parser( preprocessor, sema);
    //parser.ParseTranslationUnit();
    pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor);
    clang::ParseAST(preprocessor, &astConsumer, astContext);
    pTextDiagnosticPrinter->EndSourceFile();
	return 0;
}
<commit_msg>Labeled column and file name<commit_after>// This code is licensed under the New BSD license.
// See LICENSE.txt for more details.
#include <iostream>

#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Host.h"

#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"

#include "clang/Basic/LangOptions.h"
#include "clang/Basic/FileSystemOptions.h"

#include "clang/Basic/SourceManager.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/FileManager.h"

#include "clang/Frontend/HeaderSearchOptions.h"
#include "clang/Frontend/Utils.h"

#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"

#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/PreprocessorOptions.h"
#include "clang/Frontend/FrontendOptions.h"

#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Builtins.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Sema/Sema.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Type.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Ownership.h"
#include "clang/AST/DeclGroup.h"

#include "clang/Parse/Parser.h"

#include "clang/Parse/ParseAST.h"

class MyASTConsumer : public clang::ASTConsumer
{
public:
  clang::SourceManager *aSourceManager;
  MyASTConsumer(clang::SourceManager *sourceManager) : clang::ASTConsumer(), aSourceManager(sourceManager) { }
    virtual ~MyASTConsumer() { }

    virtual void HandleTopLevelDecl( clang::DeclGroupRef d)
    {
        static int count = 0;
        clang::DeclGroupRef::iterator it;
        for( it = d.begin(); it != d.end(); it++)
        {
            count++;
            clang::ObjCInterfaceDecl *vdc = dyn_cast<clang::ObjCInterfaceDecl>(*it);
            if (!vdc)
            {
              continue;
            }

            std::cout << "Classname: " << vdc->getNameAsString() << " LineNum: " << aSourceManager->getInstantiationLineNumber(vdc->getClassLoc()) << " Column: "<< aSourceManager->getInstantiationColumnNumber(vdc->getClassLoc()) << " Filename: " <<  aSourceManager->getBufferName(vdc->getClassLoc()) << std::endl;
        }
    }
};

int main()
{
	clang::DiagnosticOptions diagnosticOptions;
	clang::TextDiagnosticPrinter *pTextDiagnosticPrinter =
		new clang::TextDiagnosticPrinter(
			llvm::outs(),
			diagnosticOptions);
	llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs;
	clang::Diagnostic diagnostic(pDiagIDs, pTextDiagnosticPrinter);

	clang::LangOptions languageOptions;
        languageOptions.ObjC1 = 1;
        languageOptions.ObjC2 = 1;
	clang::FileSystemOptions fileSystemOptions;
	clang::FileManager fileManager(fileSystemOptions);

	clang::SourceManager sourceManager(
        diagnostic,
        fileManager);
	clang::HeaderSearch headerSearch(fileManager);

	clang::HeaderSearchOptions headerSearchOptions;
	// <Warning!!> -- Platform Specific Code lives here
	// This depends on A) that you're running linux and
	// B) that you have the same GCC LIBs installed that
	// I do.
	// Search through Clang itself for something like this,
	// go on, you won't find it. The reason why is Clang
	// has its own versions of std* which are installed under
	// /usr/local/lib/clang/<version>/include/
	// See somewhere around Driver.cpp:77 to see Clang adding
	// its version of the headers to its include path.
	headerSearchOptions.AddPath("/usr/include/linux",
			clang::frontend::Angled,
			false,
			false,
			false);

	headerSearchOptions.AddPath("/usr/include/c++/4.4/tr1",
			clang::frontend::Angled,
			false,
			false,
			false);
	headerSearchOptions.AddPath("/usr/include/c++/4.4",
			clang::frontend::Angled,
			false,
			false,
			false);
	// </Warning!!> -- End of Platform Specific Code

	clang::TargetOptions targetOptions;
	targetOptions.Triple = llvm::sys::getHostTriple();

	clang::TargetInfo *pTargetInfo =
		clang::TargetInfo::CreateTargetInfo(
			diagnostic,
			targetOptions);

	clang::ApplyHeaderSearchOptions(
		headerSearch,
		headerSearchOptions,
		languageOptions,
		pTargetInfo->getTriple());

	clang::Preprocessor preprocessor(
		diagnostic,
		languageOptions,
		*pTargetInfo,
		sourceManager,
		headerSearch);

	clang::PreprocessorOptions preprocessorOptions;
	clang::FrontendOptions frontendOptions;
	clang::InitializePreprocessor(
		preprocessor,
		preprocessorOptions,
		headerSearchOptions,
		frontendOptions);

	const clang::FileEntry *pFile = fileManager.getFile(
        "DCILatLon.m");
	sourceManager.createMainFileID(pFile);
	//preprocessor.EnterMainSourceFile();

    const clang::TargetInfo &targetInfo = *pTargetInfo;

    clang::IdentifierTable identifierTable(languageOptions);
    clang::SelectorTable selectorTable;

    clang::Builtin::Context builtinContext(targetInfo);
    clang::ASTContext astContext(
        languageOptions,
        sourceManager,
        targetInfo,
        identifierTable,
        selectorTable,
        builtinContext,
        0 /* size_reserve*/);
   // clang::ASTConsumer astConsumer;
    MyASTConsumer astConsumer(&sourceManager);

    clang::Sema sema(
        preprocessor,
        astContext,
        astConsumer);
    sema.Initialize();

   //MySemanticAnalisys mySema( preprocessor, astContext, astConsumer);

    //clang::Parser parser( preprocessor, sema);
    //parser.ParseTranslationUnit();
    pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor);
    clang::ParseAST(preprocessor, &astConsumer, astContext);
    pTextDiagnosticPrinter->EndSourceFile();
	return 0;
}
<|endoftext|>


<commit_before><commit_msg>overflow in EstimateDataBitsFlat (#1459)<commit_after><|endoftext|>


<commit_before>//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
namespace Js
{
#ifdef SSE2MATH
    namespace SSE2
    {
#endif
        __inline Var JavascriptMath::Increment(Var aRight, ScriptContext* scriptContext)
        {
            return Increment_Full(aRight, scriptContext);
        }

        __inline Var JavascriptMath::Decrement(Var aRight, ScriptContext* scriptContext)
        {
            return Decrement_Full(aRight, scriptContext);
        }

        __inline Var JavascriptMath::Negate(Var aRight, ScriptContext* scriptContext)
        {
            return
                (TaggedInt::Is(aRight) && aRight != TaggedInt::ToVarUnchecked(0) && aRight != TaggedInt::MinVal()) ?
                    TaggedInt::NegateUnchecked(aRight) :
                    Negate_Full(aRight,scriptContext);
        }

        __inline Var JavascriptMath::Not(Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::Is(aRight) ?
                TaggedInt::Not(aRight,scriptContext) :
                Not_Full(aRight,scriptContext);
        }

        __inline Var JavascriptMath::Or(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::Or(aLeft,aRight) :
                Or_Full(aLeft,aRight,scriptContext);
        }

        __inline Var JavascriptMath::And(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
#if FLOATVAR
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::And(aLeft,aRight) :
                And_Full(aLeft,aRight,scriptContext);
#else
            Var varSpeculative = TaggedInt::Speculative_And(aLeft, aRight);
            if (TaggedInt::Is(varSpeculative))
            {
                return varSpeculative;
            }

            return And_Full(aLeft, aRight, scriptContext);
#endif
        }

        __inline Var JavascriptMath::ShiftLeft(Var aLeft,Var aRight,ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft, aRight) ?
                TaggedInt::ShiftLeft(aLeft, aRight,scriptContext) :
                ShiftLeft_Full(aLeft, aRight,scriptContext);
        }

        __inline Var JavascriptMath::ShiftRight(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft, aRight) ?
                TaggedInt::ShiftRight(aLeft, aRight) :
                ShiftRight_Full(aLeft, aRight,scriptContext);
        }

        __inline Var JavascriptMath::ShiftRightU(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft, aRight) ?
                TaggedInt::ShiftRightU(aLeft, aRight, scriptContext) :
                ShiftRightU_Full(aLeft, aRight,scriptContext);
        }

        __inline Var JavascriptMath::Xor(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft, aRight) ?
                TaggedInt::Xor(aLeft, aRight) :
                Xor_Full(aLeft, aRight,scriptContext);
        }

        __inline double JavascriptMath::Decrement_Helper(Var aRight, ScriptContext* scriptContext)
        {
    #if defined(DBG)
            if (TaggedInt::Is(aRight))
            {
                // The only reason to be here is if TaggedInt increment underflowed
                AssertMsg(aRight == TaggedInt::MinVal(), "TaggedInt decrement should be handled in generated code.");
            }
    #endif

            double value = JavascriptConversion::ToNumber(aRight, scriptContext);
            return --value;
        }

        __inline double JavascriptMath::Increment_Helper(Var aRight, ScriptContext* scriptContext)
        {
    #if defined(DBG)
            if (TaggedInt::Is(aRight))
            {
                // The only reason to be here is if TaggedInt increment overflowed
                AssertMsg(aRight == TaggedInt::MaxVal(), "TaggedInt increment should be handled in generated code.");
            }
    #endif

            double value = JavascriptConversion::ToNumber(aRight, scriptContext);
            return ++value;
        }

        __inline double JavascriptMath::Negate_Helper(Var aRight,ScriptContext* scriptContext)
        {
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);

            double value = JavascriptConversion::ToNumber(aRight, scriptContext);
            return -value;
        }

        __inline int32 JavascriptMath::And_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);
#if _M_IX86
            AssertMsg(!TaggedInt::IsPair(aLeft, aRight), "TaggedInt bitwise and should have been handled already");
#endif

            int32 nLeft = JavascriptConversion::ToInt32(aLeft, scriptContext);
            int32 nRight = JavascriptConversion::ToInt32(aRight, scriptContext);
            return nLeft & nRight;
        }

        __inline int32 JavascriptMath::Or_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);
#if _M_IX86
            AssertMsg(!TaggedInt::IsPair(aLeft, aRight), "TaggedInt bitwise or should have been handled already");
#endif
            int32 nLeft = JavascriptConversion::ToInt32(aLeft, scriptContext);
            int32 nRight = JavascriptConversion::ToInt32(aRight, scriptContext);
            return nLeft | nRight;
        }

        __inline double JavascriptMath::Add_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            AssertMsg( !JavascriptString::Is(aLeft), "Strings should have been handled already" );
            AssertMsg( !JavascriptString::Is(aRight), "Strings should have been handled already" );

            double dblLeft = JavascriptConversion::ToNumber(aLeft, scriptContext);
            double dblRight = JavascriptConversion::ToNumber(aRight, scriptContext);
            return dblLeft + dblRight;
        }

        __inline Var JavascriptMath::Add(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::Add(aLeft, aRight, scriptContext) :
                Add_Full(aLeft, aRight, scriptContext);
        }

        __inline Var JavascriptMath::Subtract(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::Subtract(aLeft, aRight, scriptContext) :
                Subtract_Full(aLeft, aRight, scriptContext);
        }

        __inline double JavascriptMath::Subtract_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);

            // The IEEE 754 floating point spec ensures that NaNs are preserved in all operations
            double dblLeft = JavascriptConversion::ToNumber(aLeft, scriptContext);
            double dblRight = JavascriptConversion::ToNumber(aRight, scriptContext);
            return dblLeft - dblRight;
        }

        __inline Var JavascriptMath::Multiply(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::Multiply(aLeft, aRight, scriptContext) :
                Multiply_Full(aLeft, aRight, scriptContext);
        }

        __inline Var JavascriptMath::Exponentiation(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return Exponentiation_Full(aLeft, aRight, scriptContext);
        }

        __inline double JavascriptMath::Multiply_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);

            // The IEEE 754 floating point spec ensures that NaNs are preserved in all operations
            return JavascriptConversion::ToNumber(aLeft, scriptContext) * JavascriptConversion::ToNumber(aRight, scriptContext);
        }

        __inline Var JavascriptMath::Divide(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            // The TaggedInt,TaggedInt case is handled within Divide_Full
            return Divide_Full(aLeft, aRight,scriptContext);
        }

        __inline double JavascriptMath::Divide_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);

#if !defined(_M_ARM32_OR_ARM64)
            AssertMsg(!TaggedInt::IsPair(aLeft, aRight), "Integer division should have been handled already");
#endif

            // The IEEE 754 floating point spec ensures that NaNs are preserved in all operations
            return JavascriptConversion::ToNumber(aLeft, scriptContext) / JavascriptConversion::ToNumber(aRight, scriptContext);
        }

        __inline Var JavascriptMath::Modulus(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return Modulus_Full(aLeft, aRight, scriptContext);
        }

        __inline double JavascriptMath::Modulus_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            double dblLeft = JavascriptConversion::ToNumber(aLeft, scriptContext);
            double dblRight = JavascriptConversion::ToNumber(aRight, scriptContext);
            return NumberUtilities::Modulus(dblLeft, dblRight);
        }

#if defined(_M_ARM32_OR_ARM64)
        __inline int32 JavascriptMath::ToInt32Core(double T1)
        {
            // Try the int32 conversion first and only do the more expensive (& closer to spec)
            // i64 conversion if it fails.
            __int32 i32 = (__int32)T1;
            if ((i32 != 0x80000000) && (i32 != 0x7fffffff))
                return i32;     //No overflow so just return i32

            int64 T4_64 = TryToInt64(T1);
            if (!NumberUtilities::IsValidTryToInt64(T4_64)) // overflow
            {
                T4_64 = ToInt32ES5OverflowHelper(T1);
            }

            return static_cast<int32>(T4_64);
        }
#else
        __inline int32 JavascriptMath::ToInt32Core(double T1)
        {
            // ES5 Spec for ToUInt32
            //
            //  T3 = sign(T1) * floor(abs(T1))
            //  T4 = T3 % 2^32
            //
            // Casting gives equivalent result, except when T1 > INT64_MAX, or T1 < INT64_MIN (or NaN Inf Zero),
            // in which case we'll use slow path.

            // Try casting to int32 first. Results in 0x80000000 if it overflows.
            int32 T4_32 = static_cast<int32>(T1);
            if (T4_32 != 0x80000000)
            {
                return T4_32;
            }

            int64 T4_64 = TryToInt64(T1);
            if (T4_64 == 0x8000000000000000) // overflow && ES5
            {
                T4_64 = ToInt32ES5OverflowHelper(T1);
            }

            return static_cast<int32>(T4_64);
        }
#endif

        // Implements platform-agnostic part of handling overflow when converting Number to int32, ES5 version.
        __inline __int64 JavascriptMath::ToInt32ES5OverflowHelper(double d)
        {
            if (IsNanInfZero(d)) // ShortCut NaN Inf Zero
            {
                return 0;
            }
            const double k_2to32 = 4294967296.0;
            double floored;

#pragma prefast(suppress:6031, "We don't care about the fraction part")
            modf(d, &floored);                      // take out the floating point part.
            double m2to32 = fmod(floored, k_2to32); // divide modulo 2^32.
            __int64 result = TryToInt64(m2to32);

            AssertMsg(NumberUtilities::IsValidTryToInt64(result), "No more overflow expected");

            return result;
        }

        __inline BOOL JavascriptMath::IsNanInfZero(double v)
        {
            return JavascriptNumber::IsNan(v) || JavascriptNumber::IsZero(v) || JavascriptNumber::IsPosInf(v) || JavascriptNumber::IsNegInf(v);
        }

        __inline int64 JavascriptMath::TryToInt64(double T1)
        {
            return Js::NumberUtilities::TryToInt64(T1);
        }

        __inline int32 JavascriptMath::ToInt32_NoObjects(Var aValue, ScriptContext* scriptContext, bool& isObject)
        {
            if (JavascriptOperators::IsObject(aValue))
            {
                isObject = true; // jitted code should bailout
                return 0;
            }

            isObject = false;
            return ToInt32(aValue, scriptContext);
        }

        __inline int32 JavascriptMath::ToInt32(Var aValue, ScriptContext* scriptContext)
        {
            return
                TaggedInt::Is(aValue) ?
                TaggedInt::ToInt32(aValue) :
                ToInt32_Full(aValue, scriptContext);
        }
#ifdef SSE2MATH
    }
#endif
}
<commit_msg>update interpreter to use SSE2 div when possible<commit_after>//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

#include "RuntimeMathPch.h"

namespace Js
{
#ifdef SSE2MATH
    namespace SSE2
    {
#endif
        __inline Var JavascriptMath::Increment(Var aRight, ScriptContext* scriptContext)
        {
            return Increment_Full(aRight, scriptContext);
        }

        __inline Var JavascriptMath::Decrement(Var aRight, ScriptContext* scriptContext)
        {
            return Decrement_Full(aRight, scriptContext);
        }

        __inline Var JavascriptMath::Negate(Var aRight, ScriptContext* scriptContext)
        {
            return
                (TaggedInt::Is(aRight) && aRight != TaggedInt::ToVarUnchecked(0) && aRight != TaggedInt::MinVal()) ?
                    TaggedInt::NegateUnchecked(aRight) :
                    Negate_Full(aRight,scriptContext);
        }

        __inline Var JavascriptMath::Not(Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::Is(aRight) ?
                TaggedInt::Not(aRight,scriptContext) :
                Not_Full(aRight,scriptContext);
        }

        __inline Var JavascriptMath::Or(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::Or(aLeft,aRight) :
                Or_Full(aLeft,aRight,scriptContext);
        }

        __inline Var JavascriptMath::And(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
#if FLOATVAR
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::And(aLeft,aRight) :
                And_Full(aLeft,aRight,scriptContext);
#else
            Var varSpeculative = TaggedInt::Speculative_And(aLeft, aRight);
            if (TaggedInt::Is(varSpeculative))
            {
                return varSpeculative;
            }

            return And_Full(aLeft, aRight, scriptContext);
#endif
        }

        __inline Var JavascriptMath::ShiftLeft(Var aLeft,Var aRight,ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft, aRight) ?
                TaggedInt::ShiftLeft(aLeft, aRight,scriptContext) :
                ShiftLeft_Full(aLeft, aRight,scriptContext);
        }

        __inline Var JavascriptMath::ShiftRight(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft, aRight) ?
                TaggedInt::ShiftRight(aLeft, aRight) :
                ShiftRight_Full(aLeft, aRight,scriptContext);
        }

        __inline Var JavascriptMath::ShiftRightU(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft, aRight) ?
                TaggedInt::ShiftRightU(aLeft, aRight, scriptContext) :
                ShiftRightU_Full(aLeft, aRight,scriptContext);
        }

        __inline Var JavascriptMath::Xor(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft, aRight) ?
                TaggedInt::Xor(aLeft, aRight) :
                Xor_Full(aLeft, aRight,scriptContext);
        }

        __inline double JavascriptMath::Decrement_Helper(Var aRight, ScriptContext* scriptContext)
        {
    #if defined(DBG)
            if (TaggedInt::Is(aRight))
            {
                // The only reason to be here is if TaggedInt increment underflowed
                AssertMsg(aRight == TaggedInt::MinVal(), "TaggedInt decrement should be handled in generated code.");
            }
    #endif

            double value = JavascriptConversion::ToNumber(aRight, scriptContext);
            return --value;
        }

        __inline double JavascriptMath::Increment_Helper(Var aRight, ScriptContext* scriptContext)
        {
    #if defined(DBG)
            if (TaggedInt::Is(aRight))
            {
                // The only reason to be here is if TaggedInt increment overflowed
                AssertMsg(aRight == TaggedInt::MaxVal(), "TaggedInt increment should be handled in generated code.");
            }
    #endif

            double value = JavascriptConversion::ToNumber(aRight, scriptContext);
            return ++value;
        }

        __inline double JavascriptMath::Negate_Helper(Var aRight,ScriptContext* scriptContext)
        {
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);

            double value = JavascriptConversion::ToNumber(aRight, scriptContext);
            return -value;
        }

        __inline int32 JavascriptMath::And_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);
#if _M_IX86
            AssertMsg(!TaggedInt::IsPair(aLeft, aRight), "TaggedInt bitwise and should have been handled already");
#endif

            int32 nLeft = JavascriptConversion::ToInt32(aLeft, scriptContext);
            int32 nRight = JavascriptConversion::ToInt32(aRight, scriptContext);
            return nLeft & nRight;
        }

        __inline int32 JavascriptMath::Or_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);
#if _M_IX86
            AssertMsg(!TaggedInt::IsPair(aLeft, aRight), "TaggedInt bitwise or should have been handled already");
#endif
            int32 nLeft = JavascriptConversion::ToInt32(aLeft, scriptContext);
            int32 nRight = JavascriptConversion::ToInt32(aRight, scriptContext);
            return nLeft | nRight;
        }

        __inline double JavascriptMath::Add_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            AssertMsg( !JavascriptString::Is(aLeft), "Strings should have been handled already" );
            AssertMsg( !JavascriptString::Is(aRight), "Strings should have been handled already" );

            double dblLeft = JavascriptConversion::ToNumber(aLeft, scriptContext);
            double dblRight = JavascriptConversion::ToNumber(aRight, scriptContext);
            return dblLeft + dblRight;
        }

        __inline Var JavascriptMath::Add(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::Add(aLeft, aRight, scriptContext) :
                Add_Full(aLeft, aRight, scriptContext);
        }

        __inline Var JavascriptMath::Subtract(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::Subtract(aLeft, aRight, scriptContext) :
                Subtract_Full(aLeft, aRight, scriptContext);
        }

        __inline double JavascriptMath::Subtract_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);

            // The IEEE 754 floating point spec ensures that NaNs are preserved in all operations
            double dblLeft = JavascriptConversion::ToNumber(aLeft, scriptContext);
            double dblRight = JavascriptConversion::ToNumber(aRight, scriptContext);
            return dblLeft - dblRight;
        }

        __inline Var JavascriptMath::Multiply(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return
                TaggedInt::IsPair(aLeft,aRight) ?
                TaggedInt::Multiply(aLeft, aRight, scriptContext) :
                Multiply_Full(aLeft, aRight, scriptContext);
        }

        __inline Var JavascriptMath::Exponentiation(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return Exponentiation_Full(aLeft, aRight, scriptContext);
        }

        __inline double JavascriptMath::Multiply_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);

            // The IEEE 754 floating point spec ensures that NaNs are preserved in all operations
            return JavascriptConversion::ToNumber(aLeft, scriptContext) * JavascriptConversion::ToNumber(aRight, scriptContext);
        }

        __inline Var JavascriptMath::Divide(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
#if defined(_M_IX86) && !defined(SSE2MATH)
            if (AutoSystemInfo::Data.SSE2Available())
            {
                return SSE2::JavascriptMath::Divide_Full(aLeft, aRight, scriptContext);
            }
            else
#endif
            {
                // The TaggedInt,TaggedInt case is handled within Divide_Full
                return Divide_Full(aLeft, aRight, scriptContext);
            }
        }

        __inline double JavascriptMath::Divide_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            Assert(aLeft != nullptr);
            Assert(aRight != nullptr);
            Assert(scriptContext != nullptr);

#if !defined(_M_ARM32_OR_ARM64)
            AssertMsg(!TaggedInt::IsPair(aLeft, aRight), "Integer division should have been handled already");
#endif

            // The IEEE 754 floating point spec ensures that NaNs are preserved in all operations
            return JavascriptConversion::ToNumber(aLeft, scriptContext) / JavascriptConversion::ToNumber(aRight, scriptContext);
        }

        __inline Var JavascriptMath::Modulus(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            return Modulus_Full(aLeft, aRight, scriptContext);
        }

        __inline double JavascriptMath::Modulus_Helper(Var aLeft, Var aRight, ScriptContext* scriptContext)
        {
            double dblLeft = JavascriptConversion::ToNumber(aLeft, scriptContext);
            double dblRight = JavascriptConversion::ToNumber(aRight, scriptContext);
            return NumberUtilities::Modulus(dblLeft, dblRight);
        }

#if defined(_M_ARM32_OR_ARM64)
        __inline int32 JavascriptMath::ToInt32Core(double T1)
        {
            // Try the int32 conversion first and only do the more expensive (& closer to spec)
            // i64 conversion if it fails.
            __int32 i32 = (__int32)T1;
            if ((i32 != 0x80000000) && (i32 != 0x7fffffff))
                return i32;     //No overflow so just return i32

            int64 T4_64 = TryToInt64(T1);
            if (!NumberUtilities::IsValidTryToInt64(T4_64)) // overflow
            {
                T4_64 = ToInt32ES5OverflowHelper(T1);
            }

            return static_cast<int32>(T4_64);
        }
#else
        __inline int32 JavascriptMath::ToInt32Core(double T1)
        {
            // ES5 Spec for ToUInt32
            //
            //  T3 = sign(T1) * floor(abs(T1))
            //  T4 = T3 % 2^32
            //
            // Casting gives equivalent result, except when T1 > INT64_MAX, or T1 < INT64_MIN (or NaN Inf Zero),
            // in which case we'll use slow path.

            // Try casting to int32 first. Results in 0x80000000 if it overflows.
            int32 T4_32 = static_cast<int32>(T1);
            if (T4_32 != 0x80000000)
            {
                return T4_32;
            }

            int64 T4_64 = TryToInt64(T1);
            if (T4_64 == 0x8000000000000000) // overflow && ES5
            {
                T4_64 = ToInt32ES5OverflowHelper(T1);
            }

            return static_cast<int32>(T4_64);
        }
#endif

        // Implements platform-agnostic part of handling overflow when converting Number to int32, ES5 version.
        __inline __int64 JavascriptMath::ToInt32ES5OverflowHelper(double d)
        {
            if (IsNanInfZero(d)) // ShortCut NaN Inf Zero
            {
                return 0;
            }
            const double k_2to32 = 4294967296.0;
            double floored;

#pragma prefast(suppress:6031, "We don't care about the fraction part")
            modf(d, &floored);                      // take out the floating point part.
            double m2to32 = fmod(floored, k_2to32); // divide modulo 2^32.
            __int64 result = TryToInt64(m2to32);

            AssertMsg(NumberUtilities::IsValidTryToInt64(result), "No more overflow expected");

            return result;
        }

        __inline BOOL JavascriptMath::IsNanInfZero(double v)
        {
            return JavascriptNumber::IsNan(v) || JavascriptNumber::IsZero(v) || JavascriptNumber::IsPosInf(v) || JavascriptNumber::IsNegInf(v);
        }

        __inline int64 JavascriptMath::TryToInt64(double T1)
        {
            return Js::NumberUtilities::TryToInt64(T1);
        }

        __inline int32 JavascriptMath::ToInt32_NoObjects(Var aValue, ScriptContext* scriptContext, bool& isObject)
        {
            if (JavascriptOperators::IsObject(aValue))
            {
                isObject = true; // jitted code should bailout
                return 0;
            }

            isObject = false;
            return ToInt32(aValue, scriptContext);
        }

        __inline int32 JavascriptMath::ToInt32(Var aValue, ScriptContext* scriptContext)
        {
            return
                TaggedInt::Is(aValue) ?
                TaggedInt::ToInt32(aValue) :
                ToInt32_Full(aValue, scriptContext);
        }
#ifdef SSE2MATH
    }
#endif
}
<|endoftext|>


<commit_before>/*
  Simple Logger for Qt

  Mario Ban, 05.2015

  GNU General Public License v2.0
  Copyright (C) 2015 Mario Ban
*/

#include "simpleQtLogger.h"

#include <QCoreApplication>
#include <QTimer>
#include <QDateTime>
#include <QFileInfo>
#include <QtDebug>

/* Log-level */
bool SQTL_LOG_ENABLE_FATAL = true;
bool SQTL_LOG_ENABLE_ERROR = true;
bool SQTL_LOG_ENABLE_WARNING = true;
bool SQTL_LOG_ENABLE_INFO = true;
bool SQTL_LOG_ENABLE_DEBUG = false;
bool SQTL_LOG_ENABLE_FUNCTION = false;

// -------------------------------------------------------------------------------------------------

SimpleQtLogger::SimpleQtLogger(QObject *parent)
  : QObject(parent)
  , _logFileRotationSize(0)
  , _logFileMaxNumber(0)
  , _stackDepth(0)
  , _logFile(0)
  , _logFileActivity(false)
{
  qDebug("SimpleQtLogger::SimpleQtLogger");

  Qt::ConnectionType connectionType = Qt::DirectConnection;
#if ENABLED_SQTL_LOG_SINK_FILE > 0
  QObject::connect(this, SIGNAL(signalLog(const QString&, const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)),
    this, SLOT(slotLog_File(const QString&, const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)), connectionType);
#endif
#if ENABLED_SQTL_LOG_SINK_QDEBUG > 0
  QObject::connect(this, SIGNAL(signalLog(const QString&, const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)),
    this, SLOT(slotLog_qDebug(const QString&, const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)), connectionType);
#endif
}

SimpleQtLogger::~SimpleQtLogger()
{
  qDebug("SimpleQtLogger::~SimpleQtLogger");

  // check close log file
  if(_logFile) {
    if(_logFile->isOpen()) {
      _logFile->close();
    }
    delete _logFile;
    _logFile = 0;
  }
}

void SimpleQtLogger::setLogFileName(const QString& logFileName, unsigned int logFileRotationSize, unsigned int logFileMaxNumber)
{
  qDebug("SimpleQtLogger::setLogFileName");

  // check valid log-file name ending
  if(logFileName.right(4) != ".log") {
    qWarning() << "Name of log-file not ending with '.log'" << logFileName;
    return;
  }

  _logFileName = logFileName;
  _logFileRotationSize = logFileRotationSize;
  _logFileMaxNumber = logFileMaxNumber;

  // check valid number ranges
  if(_logFileRotationSize < 100) {
    _logFileRotationSize = 100;
  }
  if(_logFileMaxNumber < 1) {
    _logFileMaxNumber = 1;
  }
  if(_logFileMaxNumber > 99) {
    _logFileMaxNumber = 99;
  }

  checkLogFileOpen();

  log("Start logger", SQTL_LOG_INFO, "", "", 0);
}

void SimpleQtLogger::log(const QString& text, SQTL_LOG_Level level, const QString& functionName, const char* fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::log");

  // time-stamp
  QDateTime dateTime = QDateTime::currentDateTime(); // or better use QDateTime::currentDateTimeUtc() instead
  QString ts = dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");

  emit signalLog(ts, text, level, functionName, fileName, lineNumber);
}

void SimpleQtLogger::slotLog_File(const QString& ts, const QString& text, SQTL_LOG_Level level, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::slotLog_File");

  if(functionName.isEmpty()) {
    // stream (append) to log file
    if(_logFile && _logFile->isOpen()) {
      QTextStream out(_logFile);
      out << ts << " [" << LOG_LEVEL_CHAR[level] << "] " << (text.isEmpty() ? "?" : text.trimmed()) << '\n';
      _logFileActivity = true;
    }
    return;
  }

  // stream (append) to log file
  if(_logFile && _logFile->isOpen()) {
    QTextStream out(_logFile);
    out << ts << " [" << LOG_LEVEL_CHAR[level] << "] " << (text.isEmpty() ? "?" : text.trimmed()) << " (" << functionName << "@" << fileName << ":" << lineNumber << ")" << '\n';
    _logFileActivity = true;
  }
}

void SimpleQtLogger::slotLog_qDebug(const QString& ts, const QString& text, SQTL_LOG_Level level, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::slotLog_qDebug");

  if(functionName.isEmpty()) {
    qDebug("%s", QString("%1 [%2] %3").arg(ts).arg(LOG_LEVEL_CHAR[level]).arg(text.isEmpty() ? "?" : text.trimmed()).toStdString().c_str());
    return;
  }

  qDebug("%s", QString("%1 [%2] %3 (%4@%5:%6)").arg(ts).arg(LOG_LEVEL_CHAR[level]).arg(text.isEmpty() ? "?" : text.trimmed()).arg(functionName).arg(fileName).arg(lineNumber).toStdString().c_str());
}

#if ENABLED_SQTL_LOG_FUNCTION > 0

void SimpleQtLogger::logFuncBegin(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::logFuncBegin");

  _stackDepth++; // adjust stack-trace depth

  QString stackDepth("");
  for(unsigned int i=1; i<_stackDepth; ++i) {
    stackDepth += STACK_DEPTH_CHAR;
  }
  if(text.isEmpty()) {
    log(QString("%1\\").arg(stackDepth), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
  else {
    log(QString("%1\\ %2").arg(stackDepth).arg(text), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
}

void SimpleQtLogger::logFuncEnd(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::logFuncEnd");

  QString stackDepth("");
  for(unsigned int i=1; i<_stackDepth; ++i) {
    stackDepth += STACK_DEPTH_CHAR;
  }
  if(text.isEmpty()) {
    log(QString("%1/").arg(stackDepth), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
  else {
    log(QString("%1/ %2").arg(stackDepth).arg(text), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }

  _stackDepth--; // adjust stack-trace depth
}

#endif

void SimpleQtLogger::checkLogFileOpen()
{
  // qDebug("SimpleQtLogger::checkLogFileOpen");

  // check close and open log file
  if(_logFile) {
    if(_logFile->isOpen()) {
      _logFile->close();
    }
    delete _logFile;
  }

  // open log-file
  _logFile = new QFile(_logFileName);
  if(!_logFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
    delete _logFile;
    _logFile = 0;
    qWarning() << "Open log-file failed!" << _logFileName;
  }

  if(!_logFile) {
    return;
  }

  qDebug() << "Current log-file:" << _logFileName;

  QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
}

void SimpleQtLogger::checkLogFileRolling()
{
  // qDebug("SimpleQtLogger::checkLogFileRolling");

  if(!_logFile) {
    return;
  }

  // check current log-file size
  QFileInfo logFileInfo(*_logFile);
  qint64 logFileRotationSize = logFileInfo.size();

  if(logFileRotationSize < _logFileRotationSize) {
    QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
    return;
  }
  log(QString("Current log-file size=%1 (rolling-size=%2) --> rolling").arg(logFileRotationSize).arg(_logFileRotationSize), SQTL_LOG_INFO, "", "", 0);

  // handle file rolling

  // delete last file
  QString logFileName = _logFileName;
  logFileName.replace(".log", QString("_%1.log").arg(_logFileMaxNumber, 2, 10, QLatin1Char('0')));
  if(QFile::exists(logFileName)) {
    if(QFile::remove(logFileName)) {
      qDebug() << "Removed" << logFileName;
    }
    else {
      qWarning() << "ERROR: Remove" << logFileName;
    }
  }

  // rolling files
  for(int i=_logFileMaxNumber-1; i>0; --i) {
    QString logFileNameFrom = _logFileName;
    logFileNameFrom.replace(".log", QString("_%1.log").arg(i, 2, 10, QLatin1Char('0')));
    QString logFileNameTo = _logFileName;
    logFileNameTo.replace(".log", QString("_%1.log").arg(i+1, 2, 10, QLatin1Char('0')));
    if(QFile::exists(logFileNameFrom)) {
      if(QFile::rename(logFileNameFrom, logFileNameTo)) {
        qDebug() << "Moved" << logFileNameFrom << "to" << logFileNameTo;
      }
      else {
        qWarning() << "ERROR: Move" << logFileNameFrom << "to" << logFileNameTo;
      }
    }
  }

  _logFile->close();

  // move first file
  QString logFileNameTo = _logFileName;
  logFileNameTo.replace(".log", QString("_%1.log").arg(1, 2, 10, QLatin1Char('0')));
  if(QFile::exists(_logFileName)) {
    if(QFile::rename(_logFileName, logFileNameTo)) {
      qDebug() << "Moved" << _logFileName << "to" << logFileNameTo;
    }
    else {
      qWarning() << "ERROR: Move" << _logFileName << "to" << logFileNameTo;
    }
  }

  checkLogFileOpen();
}

void SimpleQtLogger::slotCheckLogFileActivity()
{
  // qDebug("SimpleQtLogger::slotCheckLogFileActivity");

  if(!_logFile) {
    return;
  }

  if(_logFileActivity) {
    _logFileActivity = false;
    checkLogFileRolling();
    return;
  }

  QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
}

// -------------------------------------------------------------------------------------------------

#if ENABLED_SQTL_LOG_FUNCTION > 0

SimpleQtLoggerFunc::SimpleQtLoggerFunc(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
  : _text(text)
  , _functionName(functionName)
  , _fileName(fileName)
  , _lineNumber(lineNumber)
{
  // qDebug("SimpleQtLoggerFunc::SimpleQtLoggerFunc");
  if(ENABLED_SQTL_LOG_FUNCTION && SQTL_LOG_ENABLE_FUNCTION) simpleQtLogger_.logFuncBegin(_text, _functionName, _fileName, _lineNumber);
}

SimpleQtLoggerFunc::~SimpleQtLoggerFunc()
{
  // qDebug("SimpleQtLoggerFunc::~SimpleQtLoggerFunc");
  if(ENABLED_SQTL_LOG_FUNCTION && SQTL_LOG_ENABLE_FUNCTION) simpleQtLogger_.logFuncEnd(_text, _functionName, _fileName, _lineNumber);
}

#endif
<commit_msg>Clean-up<commit_after>/*
  Simple Logger for Qt

  Mario Ban, 05.2015

  GNU General Public License v2.0
  Copyright (C) 2015 Mario Ban
*/

#include "simpleQtLogger.h"

#include <QCoreApplication>
#include <QTimer>
#include <QDateTime>
#include <QFileInfo>
#include <QtDebug>

/* Log-level */
bool SQTL_LOG_ENABLE_FATAL = true;
bool SQTL_LOG_ENABLE_ERROR = true;
bool SQTL_LOG_ENABLE_WARNING = true;
bool SQTL_LOG_ENABLE_INFO = true;
bool SQTL_LOG_ENABLE_DEBUG = false;
bool SQTL_LOG_ENABLE_FUNCTION = false;

// -------------------------------------------------------------------------------------------------

SimpleQtLogger::SimpleQtLogger(QObject *parent)
  : QObject(parent)
  , _logFileRotationSize(0)
  , _logFileMaxNumber(0)
  , _stackDepth(0)
  , _logFile(0)
  , _logFileActivity(false)
{
  qDebug("SimpleQtLogger::SimpleQtLogger");

  Qt::ConnectionType connectionType = Qt::DirectConnection;
#if ENABLED_SQTL_LOG_SINK_FILE > 0
  QObject::connect(this, SIGNAL(signalLog(const QString&, const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)),
    this, SLOT(slotLog_File(const QString&, const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)), connectionType);
#endif
#if ENABLED_SQTL_LOG_SINK_QDEBUG > 0
  QObject::connect(this, SIGNAL(signalLog(const QString&, const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)),
    this, SLOT(slotLog_qDebug(const QString&, const QString&, SQTL_LOG_Level, const QString&, const QString&, unsigned int)), connectionType);
#endif
}

SimpleQtLogger::~SimpleQtLogger()
{
  qDebug("SimpleQtLogger::~SimpleQtLogger");

  // check close log file
  if(_logFile) {
    if(_logFile->isOpen()) {
      _logFile->close();
    }
    delete _logFile;
    _logFile = 0;
  }
}

void SimpleQtLogger::setLogFileName(const QString& logFileName, unsigned int logFileRotationSize, unsigned int logFileMaxNumber)
{
  qDebug("SimpleQtLogger::setLogFileName");

  // check valid log-file name ending
  if(logFileName.right(4) != ".log") {
    qWarning() << "Name of log-file not ending with '.log'" << logFileName;
    return;
  }

  _logFileName = logFileName;
  _logFileRotationSize = logFileRotationSize;
  _logFileMaxNumber = logFileMaxNumber;

  // check valid number ranges
  if(_logFileRotationSize < 100) {
    _logFileRotationSize = 100;
  }
  if(_logFileMaxNumber < 1) {
    _logFileMaxNumber = 1;
  }
  if(_logFileMaxNumber > 99) {
    _logFileMaxNumber = 99;
  }

  checkLogFileOpen();

  log("Start logger", SQTL_LOG_INFO, "", "", 0);
}

void SimpleQtLogger::log(const QString& text, SQTL_LOG_Level level, const QString& functionName, const char* fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::log");

  // time-stamp
  QDateTime dateTime = QDateTime::currentDateTime(); // or better use QDateTime::currentDateTimeUtc() instead
  QString ts = dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");

  emit signalLog(ts, text, level, functionName, fileName, lineNumber);
}

void SimpleQtLogger::slotLog_File(const QString& ts, const QString& text, SQTL_LOG_Level level, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::slotLog_File");

  if(functionName.isEmpty()) {
    // stream (append) to log file
    if(_logFile && _logFile->isOpen()) {
      QTextStream out(_logFile);
      out << ts << " [" << LOG_LEVEL_CHAR[level] << "] " << (text.isEmpty() ? "?" : text.trimmed()) << '\n';
      _logFileActivity = true;
    }
    return;
  }

  // stream (append) to log file
  if(_logFile && _logFile->isOpen()) {
    QTextStream out(_logFile);
    out << ts << " [" << LOG_LEVEL_CHAR[level] << "] " << (text.isEmpty() ? "?" : text.trimmed()) << " (" << functionName << "@" << fileName << ":" << lineNumber << ")" << '\n';
    _logFileActivity = true;
  }
}

void SimpleQtLogger::slotLog_qDebug(const QString& ts, const QString& text, SQTL_LOG_Level level, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::slotLog_qDebug");

  if(functionName.isEmpty()) {
    qDebug("%s", QString("%1 [%2] %3").arg(ts).arg(LOG_LEVEL_CHAR[level]).arg(text.isEmpty() ? "?" : text.trimmed()).toStdString().c_str());
    return;
  }

  qDebug("%s", QString("%1 [%2] %3 (%4@%5:%6)").arg(ts).arg(LOG_LEVEL_CHAR[level]).arg(text.isEmpty() ? "?" : text.trimmed()).arg(functionName).arg(fileName).arg(lineNumber).toStdString().c_str());
}

#if ENABLED_SQTL_LOG_FUNCTION > 0

void SimpleQtLogger::logFuncBegin(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::logFuncBegin");

  _stackDepth++; // adjust stack-trace depth

  QString stackDepth("");
  for(unsigned int i=1; i<_stackDepth; ++i) {
    stackDepth += STACK_DEPTH_CHAR;
  }
  if(text.isEmpty()) {
    log(QString("%1\\").arg(stackDepth), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
  else {
    log(QString("%1\\ %2").arg(stackDepth).arg(text), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
}

void SimpleQtLogger::logFuncEnd(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
{
  // qDebug("SimpleQtLogger::logFuncEnd");

  QString stackDepth("");
  for(unsigned int i=1; i<_stackDepth; ++i) {
    stackDepth += STACK_DEPTH_CHAR;
  }
  if(text.isEmpty()) {
    log(QString("%1/").arg(stackDepth), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }
  else {
    log(QString("%1/ %2").arg(stackDepth).arg(text), SQTL_LOG_FUNCTION, functionName, fileName.toStdString().c_str(), lineNumber);
  }

  _stackDepth--; // adjust stack-trace depth
}

#endif

void SimpleQtLogger::checkLogFileOpen()
{
  // qDebug("SimpleQtLogger::checkLogFileOpen");

  // check close and open log file
  if(_logFile) {
    if(_logFile->isOpen()) {
      _logFile->close();
    }
    delete _logFile;
  }

  // open log-file
  _logFile = new QFile(_logFileName);
  if(!_logFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
    delete _logFile;
    _logFile = 0;
    qWarning() << "Open log-file failed!" << _logFileName;
  }

  if(!_logFile) {
    return;
  }

  qDebug() << "Current log-file:" << _logFileName;

  QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
}

void SimpleQtLogger::checkLogFileRolling()
{
  // qDebug("SimpleQtLogger::checkLogFileRolling");

  if(!_logFile) {
    return;
  }

  // check current log-file size
  QFileInfo logFileInfo(*_logFile);
  qint64 logFileRotationSize = logFileInfo.size();

  if(logFileRotationSize < _logFileRotationSize) {
    QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
    return;
  }
  log(QString("Current log-file size=%1 (rotation-size=%2) --> rolling").arg(logFileRotationSize).arg(_logFileRotationSize), SQTL_LOG_INFO, "", "", 0);

  // handle file rolling

  // delete last file
  QString logFileName = _logFileName;
  logFileName.replace(".log", QString("_%1.log").arg(_logFileMaxNumber, 2, 10, QLatin1Char('0')));
  if(QFile::exists(logFileName)) {
    if(QFile::remove(logFileName)) {
      qDebug() << "Removed" << logFileName;
    }
    else {
      qWarning() << "ERROR: Remove" << logFileName;
    }
  }

  // rolling files
  for(int i=_logFileMaxNumber-1; i>0; --i) {
    QString logFileNameFrom = _logFileName;
    logFileNameFrom.replace(".log", QString("_%1.log").arg(i, 2, 10, QLatin1Char('0')));
    QString logFileNameTo = _logFileName;
    logFileNameTo.replace(".log", QString("_%1.log").arg(i+1, 2, 10, QLatin1Char('0')));
    if(QFile::exists(logFileNameFrom)) {
      if(QFile::rename(logFileNameFrom, logFileNameTo)) {
        qDebug() << "Moved" << logFileNameFrom << "to" << logFileNameTo;
      }
      else {
        qWarning() << "ERROR: Move" << logFileNameFrom << "to" << logFileNameTo;
      }
    }
  }

  _logFile->close();

  // move first file
  QString logFileNameTo = _logFileName;
  logFileNameTo.replace(".log", QString("_%1.log").arg(1, 2, 10, QLatin1Char('0')));
  if(QFile::exists(_logFileName)) {
    if(QFile::rename(_logFileName, logFileNameTo)) {
      qDebug() << "Moved" << _logFileName << "to" << logFileNameTo;
    }
    else {
      qWarning() << "ERROR: Move" << _logFileName << "to" << logFileNameTo;
    }
  }

  checkLogFileOpen();
}

void SimpleQtLogger::slotCheckLogFileActivity()
{
  // qDebug("SimpleQtLogger::slotCheckLogFileActivity");

  if(!_logFile) {
    return;
  }

  if(_logFileActivity) {
    _logFileActivity = false;
    checkLogFileRolling();
    return;
  }

  QTimer::singleShot(CHECK_LOG_FILE_ACTIVITY_INTERVAL, this, SLOT(slotCheckLogFileActivity()));
}

// -------------------------------------------------------------------------------------------------

#if ENABLED_SQTL_LOG_FUNCTION > 0

SimpleQtLoggerFunc::SimpleQtLoggerFunc(const QString& text, const QString& functionName, const QString& fileName, unsigned int lineNumber)
  : _text(text)
  , _functionName(functionName)
  , _fileName(fileName)
  , _lineNumber(lineNumber)
{
  // qDebug("SimpleQtLoggerFunc::SimpleQtLoggerFunc");
  if(ENABLED_SQTL_LOG_FUNCTION && SQTL_LOG_ENABLE_FUNCTION) simpleQtLogger_.logFuncBegin(_text, _functionName, _fileName, _lineNumber);
}

SimpleQtLoggerFunc::~SimpleQtLoggerFunc()
{
  // qDebug("SimpleQtLoggerFunc::~SimpleQtLoggerFunc");
  if(ENABLED_SQTL_LOG_FUNCTION && SQTL_LOG_ENABLE_FUNCTION) simpleQtLogger_.logFuncEnd(_text, _functionName, _fileName, _lineNumber);
}

#endif
<|endoftext|>


<commit_before><commit_msg>Added constant potts model loss function, added alias for adaptive scale modularity.<commit_after><|endoftext|>


<commit_before>//===-- X86TargetMachine.cpp - Define TargetMachine for the X86 -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the X86 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//

#include "X86TargetMachine.h"
#include "X86.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;

X86VectorEnum llvm::X86Vector = NoSSE;
bool llvm::X86ScalarSSE = false;
bool llvm::X86DAGIsel = false;

/// X86TargetMachineModule - Note that this is used on hosts that cannot link
/// in a library unless there are references into the library.  In particular,
/// it seems that it is not possible to get things to work on Win32 without
/// this.  Though it is unused, do not remove it.
extern "C" int X86TargetMachineModule;
int X86TargetMachineModule = 0;

namespace {
  cl::opt<bool> DisableOutput("disable-x86-llc-output", cl::Hidden,
                              cl::desc("Disable the X86 asm printer, for use "
                                       "when profiling the code generator."));
  cl::opt<bool, true> EnableSSEFP("enable-sse-scalar-fp",
                cl::desc("Perform FP math in SSE regs instead of the FP stack"),
                cl::location(X86ScalarSSE),
                cl::init(false));

  cl::opt<bool, true> EnableX86DAGDAG("enable-x86-dag-isel", cl::Hidden,
                      cl::desc("Enable DAG-to-DAG isel for X86"),
                      cl::location(X86DAGIsel),
                      cl::init(true));

  // FIXME: This should eventually be handled with target triples and
  // subtarget support!
  cl::opt<X86VectorEnum, true>
  SSEArg(
    cl::desc("Enable SSE support in the X86 target:"),
    cl::values(
       clEnumValN(SSE,  "sse", "  Enable SSE support"),
       clEnumValN(SSE2, "sse2", "  Enable SSE and SSE2 support"),
       clEnumValN(SSE3, "sse3", "  Enable SSE, SSE2, and SSE3 support"),
       clEnumValEnd),
    cl::location(X86Vector), cl::init(NoSSE));

  // Register the target.
  RegisterTarget<X86TargetMachine> X("x86", "  IA-32 (Pentium and above)");
}

unsigned X86TargetMachine::getJITMatchQuality() {
#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
  return 10;
#else
  return 0;
#endif
}

unsigned X86TargetMachine::getModuleMatchQuality(const Module &M) {
  // We strongly match "i[3-9]86-*".
  std::string TT = M.getTargetTriple();
  if (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
      TT[4] == '-' && TT[1] - '3' < 6)
    return 20;

  if (M.getEndianness()  == Module::LittleEndian &&
      M.getPointerSize() == Module::Pointer32)
    return 10;                                   // Weak match
  else if (M.getEndianness() != Module::AnyEndianness ||
           M.getPointerSize() != Module::AnyPointerSize)
    return 0;                                    // Match for some other target

  return getJITMatchQuality()/2;
}

/// X86TargetMachine ctor - Create an ILP32 architecture model
///
X86TargetMachine::X86TargetMachine(const Module &M,
                                  IntrinsicLowering *IL,
                                  const std::string &FS)
  : TargetMachine("X86", IL, true, 4, 4, 4, 4, 4),
    Subtarget(M, FS),
    FrameInfo(TargetFrameInfo::StackGrowsDown,
              Subtarget.getStackAlignment(), -4),
    JITInfo(*this) {
  // Scalar SSE FP requires at least SSE2
  X86ScalarSSE &= X86Vector >= SSE2;

  // Ignore -enable-sse-scalar-fp if -enable-x86-dag-isel.
  X86ScalarSSE |= (X86DAGIsel && X86Vector >= SSE2);
}

// addPassesToEmitFile - We currently use all of the same passes as the JIT
// does to emit statically compiled machine code.
bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
                                           CodeGenFileType FileType,
                                           bool Fast) {
  if (FileType != TargetMachine::AssemblyFile &&
      FileType != TargetMachine::ObjectFile) return true;

  // FIXME: Implement efficient support for garbage collection intrinsics.
  PM.add(createLowerGCPass());

  // FIXME: Implement the invoke/unwind instructions!
  PM.add(createLowerInvokePass());

  // FIXME: Implement the switch instruction in the instruction selector!
  PM.add(createLowerSwitchPass());

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  // Install an instruction selector.
  if (X86DAGIsel)
    PM.add(createX86ISelDag(*this));
  else
    PM.add(createX86ISelPattern(*this));

  // Print the instruction selected machine code...
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  // Perform register allocation to convert to a concrete x86 representation
  PM.add(createRegisterAllocator());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  PM.add(createX86FloatingPointStackifierPass());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());

  PM.add(createX86PeepholeOptimizerPass());

  if (PrintMachineCode)  // Print the register-allocated code
    PM.add(createX86CodePrinterPass(std::cerr, *this));

  if (!DisableOutput)
    switch (FileType) {
    default:
      assert(0 && "Unexpected filetype here!");
    case TargetMachine::AssemblyFile:
      PM.add(createX86CodePrinterPass(Out, *this));
      break;
    case TargetMachine::ObjectFile:
      // FIXME: We only support emission of ELF files for now, this should check
      // the target triple and decide on the format to write (e.g. COFF on
      // win32).
      addX86ELFObjectWriterPass(PM, Out, *this);
      break;
    }

  // Delete machine code for this function
  PM.add(createMachineCodeDeleter());

  return false; // success!
}

/// addPassesToJITCompile - Add passes to the specified pass manager to
/// implement a fast dynamic compiler for this target.  Return true if this is
/// not supported for this target.
///
void X86JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
  // FIXME: Implement efficient support for garbage collection intrinsics.
  PM.add(createLowerGCPass());

  // FIXME: Implement the invoke/unwind instructions!
  PM.add(createLowerInvokePass());

  // FIXME: Implement the switch instruction in the instruction selector!
  PM.add(createLowerSwitchPass());

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  // Install an instruction selector.
  if (X86DAGIsel)
    PM.add(createX86ISelDag(TM));
  else
    PM.add(createX86ISelPattern(TM));

  // FIXME: Add SSA based peephole optimizer here.

  // Print the instruction selected machine code...
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  // Perform register allocation to convert to a concrete x86 representation
  PM.add(createRegisterAllocator());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  PM.add(createX86FloatingPointStackifierPass());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());

  PM.add(createX86PeepholeOptimizerPass());

  if (PrintMachineCode)  // Print the register-allocated code
    PM.add(createX86CodePrinterPass(std::cerr, TM));
}

bool X86TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
                                                  MachineCodeEmitter &MCE) {
  PM.add(createX86CodeEmitterPass(MCE));
  // Delete machine code for this function
  PM.add(createMachineCodeDeleter());
  return false;
}
<commit_msg>Didn't mean to commit the last one.<commit_after>//===-- X86TargetMachine.cpp - Define TargetMachine for the X86 -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the X86 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//

#include "X86TargetMachine.h"
#include "X86.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;

X86VectorEnum llvm::X86Vector = NoSSE;
bool llvm::X86ScalarSSE = false;
bool llvm::X86DAGIsel = false;

/// X86TargetMachineModule - Note that this is used on hosts that cannot link
/// in a library unless there are references into the library.  In particular,
/// it seems that it is not possible to get things to work on Win32 without
/// this.  Though it is unused, do not remove it.
extern "C" int X86TargetMachineModule;
int X86TargetMachineModule = 0;

namespace {
  cl::opt<bool> DisableOutput("disable-x86-llc-output", cl::Hidden,
                              cl::desc("Disable the X86 asm printer, for use "
                                       "when profiling the code generator."));
  cl::opt<bool, true> EnableSSEFP("enable-sse-scalar-fp",
                cl::desc("Perform FP math in SSE regs instead of the FP stack"),
                cl::location(X86ScalarSSE),
                cl::init(false));

  cl::opt<bool, true> EnableX86DAGDAG("enable-x86-dag-isel", cl::Hidden,
                      cl::desc("Enable DAG-to-DAG isel for X86"),
                      cl::location(X86DAGIsel),
                      cl::init(false));

  // FIXME: This should eventually be handled with target triples and
  // subtarget support!
  cl::opt<X86VectorEnum, true>
  SSEArg(
    cl::desc("Enable SSE support in the X86 target:"),
    cl::values(
       clEnumValN(SSE,  "sse", "  Enable SSE support"),
       clEnumValN(SSE2, "sse2", "  Enable SSE and SSE2 support"),
       clEnumValN(SSE3, "sse3", "  Enable SSE, SSE2, and SSE3 support"),
       clEnumValEnd),
    cl::location(X86Vector), cl::init(NoSSE));

  // Register the target.
  RegisterTarget<X86TargetMachine> X("x86", "  IA-32 (Pentium and above)");
}

unsigned X86TargetMachine::getJITMatchQuality() {
#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
  return 10;
#else
  return 0;
#endif
}

unsigned X86TargetMachine::getModuleMatchQuality(const Module &M) {
  // We strongly match "i[3-9]86-*".
  std::string TT = M.getTargetTriple();
  if (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
      TT[4] == '-' && TT[1] - '3' < 6)
    return 20;

  if (M.getEndianness()  == Module::LittleEndian &&
      M.getPointerSize() == Module::Pointer32)
    return 10;                                   // Weak match
  else if (M.getEndianness() != Module::AnyEndianness ||
           M.getPointerSize() != Module::AnyPointerSize)
    return 0;                                    // Match for some other target

  return getJITMatchQuality()/2;
}

/// X86TargetMachine ctor - Create an ILP32 architecture model
///
X86TargetMachine::X86TargetMachine(const Module &M,
                                  IntrinsicLowering *IL,
                                  const std::string &FS)
  : TargetMachine("X86", IL, true, 4, 4, 4, 4, 4),
    Subtarget(M, FS),
    FrameInfo(TargetFrameInfo::StackGrowsDown,
              Subtarget.getStackAlignment(), -4),
    JITInfo(*this) {
  // Scalar SSE FP requires at least SSE2
  X86ScalarSSE &= X86Vector >= SSE2;

  // Ignore -enable-sse-scalar-fp if -enable-x86-dag-isel.
  X86ScalarSSE |= (X86DAGIsel && X86Vector >= SSE2);
}

// addPassesToEmitFile - We currently use all of the same passes as the JIT
// does to emit statically compiled machine code.
bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
                                           CodeGenFileType FileType,
                                           bool Fast) {
  if (FileType != TargetMachine::AssemblyFile &&
      FileType != TargetMachine::ObjectFile) return true;

  // FIXME: Implement efficient support for garbage collection intrinsics.
  PM.add(createLowerGCPass());

  // FIXME: Implement the invoke/unwind instructions!
  PM.add(createLowerInvokePass());

  // FIXME: Implement the switch instruction in the instruction selector!
  PM.add(createLowerSwitchPass());

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  // Install an instruction selector.
  if (X86DAGIsel)
    PM.add(createX86ISelDag(*this));
  else
    PM.add(createX86ISelPattern(*this));

  // Print the instruction selected machine code...
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  // Perform register allocation to convert to a concrete x86 representation
  PM.add(createRegisterAllocator());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  PM.add(createX86FloatingPointStackifierPass());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());

  PM.add(createX86PeepholeOptimizerPass());

  if (PrintMachineCode)  // Print the register-allocated code
    PM.add(createX86CodePrinterPass(std::cerr, *this));

  if (!DisableOutput)
    switch (FileType) {
    default:
      assert(0 && "Unexpected filetype here!");
    case TargetMachine::AssemblyFile:
      PM.add(createX86CodePrinterPass(Out, *this));
      break;
    case TargetMachine::ObjectFile:
      // FIXME: We only support emission of ELF files for now, this should check
      // the target triple and decide on the format to write (e.g. COFF on
      // win32).
      addX86ELFObjectWriterPass(PM, Out, *this);
      break;
    }

  // Delete machine code for this function
  PM.add(createMachineCodeDeleter());

  return false; // success!
}

/// addPassesToJITCompile - Add passes to the specified pass manager to
/// implement a fast dynamic compiler for this target.  Return true if this is
/// not supported for this target.
///
void X86JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
  // FIXME: Implement efficient support for garbage collection intrinsics.
  PM.add(createLowerGCPass());

  // FIXME: Implement the invoke/unwind instructions!
  PM.add(createLowerInvokePass());

  // FIXME: Implement the switch instruction in the instruction selector!
  PM.add(createLowerSwitchPass());

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  // Install an instruction selector.
  if (X86DAGIsel)
    PM.add(createX86ISelDag(TM));
  else
    PM.add(createX86ISelPattern(TM));

  // FIXME: Add SSA based peephole optimizer here.

  // Print the instruction selected machine code...
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  // Perform register allocation to convert to a concrete x86 representation
  PM.add(createRegisterAllocator());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  PM.add(createX86FloatingPointStackifierPass());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(&std::cerr));

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());

  PM.add(createX86PeepholeOptimizerPass());

  if (PrintMachineCode)  // Print the register-allocated code
    PM.add(createX86CodePrinterPass(std::cerr, TM));
}

bool X86TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
                                                  MachineCodeEmitter &MCE) {
  PM.add(createX86CodeEmitterPass(MCE));
  // Delete machine code for this function
  PM.add(createMachineCodeDeleter());
  return false;
}
<|endoftext|>


<commit_before>//===--- CommonOptionsParser.cpp - common options for clang tools ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements the CommonOptionsParser class used to parse common
//  command-line options for clang tools, so that they can be run as separate
//  command-line applications with a consistent common interface for handling
//  compilation database and input files.
//
//  It provides a common subset of command-line options, common algorithm
//  for locating a compilation database and source files, and help messages
//  for the basic command-line interface.
//
//  It creates a CompilationDatabase and reads common command-line options.
//
//  This class uses the Clang Tooling infrastructure, see
//    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
//  for details on setting it up with LLVM source tree.
//
//===----------------------------------------------------------------------===//

#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"

using namespace clang::tooling;
using namespace llvm;

const char *const CommonOptionsParser::HelpMessage =
    "\n"
    "-p <build-path> is used to read a compile command database.\n"
    "\n"
    "\tFor example, it can be a CMake build directory in which a file named\n"
    "\tcompile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON\n"
    "\tCMake option to get this output). When no build path is specified,\n"
    "\ta search for compile_commands.json will be attempted through all\n"
    "\tparent paths of the first input file . See:\n"
    "\thttp://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an\n"
    "\texample of setting up Clang Tooling on a source tree.\n"
    "\n"
    "<source0> ... specify the paths of source files. These paths are\n"
    "\tlooked up in the compile command database. If the path of a file is\n"
    "\tabsolute, it needs to point into CMake's source tree. If the path is\n"
    "\trelative, the current working directory needs to be in the CMake\n"
    "\tsource tree and the file must be in a subdirectory of the current\n"
    "\tworking directory. \"./\" prefixes in the relative files will be\n"
    "\tautomatically removed, but the rest of a relative path must be a\n"
    "\tsuffix of a path in the compile command database.\n"
    "\n";

void ArgumentsAdjustingCompilations::appendArgumentsAdjuster(
    ArgumentsAdjuster Adjuster) {
  Adjusters.push_back(std::move(Adjuster));
}

std::vector<CompileCommand> ArgumentsAdjustingCompilations::getCompileCommands(
    StringRef FilePath) const {
  return adjustCommands(Compilations->getCompileCommands(FilePath));
}

std::vector<std::string>
ArgumentsAdjustingCompilations::getAllFiles() const {
  return Compilations->getAllFiles();
}

std::vector<CompileCommand>
ArgumentsAdjustingCompilations::getAllCompileCommands() const {
  return adjustCommands(Compilations->getAllCompileCommands());
}

std::vector<CompileCommand> ArgumentsAdjustingCompilations::adjustCommands(
    std::vector<CompileCommand> Commands) const {
  for (CompileCommand &Command : Commands)
    for (const auto &Adjuster : Adjusters)
      Command.CommandLine = Adjuster(Command.CommandLine, Command.Filename);
  return Commands;
}

llvm::Error CommonOptionsParser::init(
    int &argc, const char **argv, cl::OptionCategory &Category,
    llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {

  static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
                                        cl::Optional, cl::cat(Category),
                                        cl::sub(*cl::AllSubCommands));

  static cl::list<std::string> SourcePaths(
      cl::Positional, cl::desc("<source0> [... <sourceN>]"), OccurrencesFlag,
      cl::cat(Category), cl::sub(*cl::AllSubCommands));

  static cl::list<std::string> ArgsAfter(
      "extra-arg",
      cl::desc("Additional argument to append to the compiler command line"),
      cl::cat(Category), cl::sub(*cl::AllSubCommands));

  static cl::list<std::string> ArgsBefore(
      "extra-arg-before",
      cl::desc("Additional argument to prepend to the compiler command line"),
      cl::cat(Category), cl::sub(*cl::AllSubCommands));

  cl::ResetAllOptionOccurrences();

  cl::HideUnrelatedOptions(Category);

  std::string ErrorMessage;
  Compilations =
      FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage);
  if (!ErrorMessage.empty())
    ErrorMessage.append("\n");
  llvm::raw_string_ostream OS(ErrorMessage);
  // Stop initializing if command-line option parsing failed.
  if (!cl::ParseCommandLineOptions(argc, argv, Overview, &OS)) {
    OS.flush();
    return llvm::make_error<llvm::StringError>("[CommonOptionsParser]: " +
                                                   ErrorMessage,
                                               llvm::inconvertibleErrorCode());
  }

  cl::PrintOptionValues();

  SourcePathList = SourcePaths;
  if ((OccurrencesFlag == cl::ZeroOrMore || OccurrencesFlag == cl::Optional) &&
      SourcePathList.empty())
    return llvm::Error::success();
  if (!Compilations) {
    if (!BuildPath.empty()) {
      Compilations =
          CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage);
    } else {
      Compilations = CompilationDatabase::autoDetectFromSource(SourcePaths[0],
                                                               ErrorMessage);
    }
    if (!Compilations) {
      llvm::errs() << "Error while trying to load a compilation database:\n"
                   << ErrorMessage << "Running without flags.\n";
      Compilations.reset(
          new FixedCompilationDatabase(".", std::vector<std::string>()));
    }
  }
  auto AdjustingCompilations =
      llvm::make_unique<ArgumentsAdjustingCompilations>(
          std::move(Compilations));
  Adjuster =
      getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN);
  Adjuster = combineAdjusters(
      std::move(Adjuster),
      getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END));
  AdjustingCompilations->appendArgumentsAdjuster(Adjuster);
  Compilations = std::move(AdjustingCompilations);
  return llvm::Error::success();
}

llvm::Expected<CommonOptionsParser> CommonOptionsParser::create(
    int &argc, const char **argv, llvm::cl::OptionCategory &Category,
    llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
  CommonOptionsParser Parser;
  llvm::Error Err =
      Parser.init(argc, argv, Category, OccurrencesFlag, Overview);
  if (Err)
    return std::move(Err);
  return std::move(Parser);
}

CommonOptionsParser::CommonOptionsParser(
    int &argc, const char **argv, cl::OptionCategory &Category,
    llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
  llvm::Error Err = init(argc, argv, Category, OccurrencesFlag, Overview);
  if (Err) {
    llvm::report_fatal_error(
        "CommonOptionsParser: failed to parse command-line arguments. " +
        llvm::toString(std::move(Err)));
  }
}
<commit_msg>Revert r358337: "[CommandLineParser] Add DefaultOption flag"<commit_after>//===--- CommonOptionsParser.cpp - common options for clang tools ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements the CommonOptionsParser class used to parse common
//  command-line options for clang tools, so that they can be run as separate
//  command-line applications with a consistent common interface for handling
//  compilation database and input files.
//
//  It provides a common subset of command-line options, common algorithm
//  for locating a compilation database and source files, and help messages
//  for the basic command-line interface.
//
//  It creates a CompilationDatabase and reads common command-line options.
//
//  This class uses the Clang Tooling infrastructure, see
//    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
//  for details on setting it up with LLVM source tree.
//
//===----------------------------------------------------------------------===//

#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"

using namespace clang::tooling;
using namespace llvm;

const char *const CommonOptionsParser::HelpMessage =
    "\n"
    "-p <build-path> is used to read a compile command database.\n"
    "\n"
    "\tFor example, it can be a CMake build directory in which a file named\n"
    "\tcompile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON\n"
    "\tCMake option to get this output). When no build path is specified,\n"
    "\ta search for compile_commands.json will be attempted through all\n"
    "\tparent paths of the first input file . See:\n"
    "\thttp://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an\n"
    "\texample of setting up Clang Tooling on a source tree.\n"
    "\n"
    "<source0> ... specify the paths of source files. These paths are\n"
    "\tlooked up in the compile command database. If the path of a file is\n"
    "\tabsolute, it needs to point into CMake's source tree. If the path is\n"
    "\trelative, the current working directory needs to be in the CMake\n"
    "\tsource tree and the file must be in a subdirectory of the current\n"
    "\tworking directory. \"./\" prefixes in the relative files will be\n"
    "\tautomatically removed, but the rest of a relative path must be a\n"
    "\tsuffix of a path in the compile command database.\n"
    "\n";

void ArgumentsAdjustingCompilations::appendArgumentsAdjuster(
    ArgumentsAdjuster Adjuster) {
  Adjusters.push_back(std::move(Adjuster));
}

std::vector<CompileCommand> ArgumentsAdjustingCompilations::getCompileCommands(
    StringRef FilePath) const {
  return adjustCommands(Compilations->getCompileCommands(FilePath));
}

std::vector<std::string>
ArgumentsAdjustingCompilations::getAllFiles() const {
  return Compilations->getAllFiles();
}

std::vector<CompileCommand>
ArgumentsAdjustingCompilations::getAllCompileCommands() const {
  return adjustCommands(Compilations->getAllCompileCommands());
}

std::vector<CompileCommand> ArgumentsAdjustingCompilations::adjustCommands(
    std::vector<CompileCommand> Commands) const {
  for (CompileCommand &Command : Commands)
    for (const auto &Adjuster : Adjusters)
      Command.CommandLine = Adjuster(Command.CommandLine, Command.Filename);
  return Commands;
}

llvm::Error CommonOptionsParser::init(
    int &argc, const char **argv, cl::OptionCategory &Category,
    llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
  static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden,
                            cl::sub(*cl::AllSubCommands));

  static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
                                        cl::Optional, cl::cat(Category),
                                        cl::sub(*cl::AllSubCommands));

  static cl::list<std::string> SourcePaths(
      cl::Positional, cl::desc("<source0> [... <sourceN>]"), OccurrencesFlag,
      cl::cat(Category), cl::sub(*cl::AllSubCommands));

  static cl::list<std::string> ArgsAfter(
      "extra-arg",
      cl::desc("Additional argument to append to the compiler command line"),
      cl::cat(Category), cl::sub(*cl::AllSubCommands));

  static cl::list<std::string> ArgsBefore(
      "extra-arg-before",
      cl::desc("Additional argument to prepend to the compiler command line"),
      cl::cat(Category), cl::sub(*cl::AllSubCommands));

  cl::ResetAllOptionOccurrences();

  cl::HideUnrelatedOptions(Category);

  std::string ErrorMessage;
  Compilations =
      FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage);
  if (!ErrorMessage.empty())
    ErrorMessage.append("\n");
  llvm::raw_string_ostream OS(ErrorMessage);
  // Stop initializing if command-line option parsing failed.
  if (!cl::ParseCommandLineOptions(argc, argv, Overview, &OS)) {
    OS.flush();
    return llvm::make_error<llvm::StringError>("[CommonOptionsParser]: " +
                                                   ErrorMessage,
                                               llvm::inconvertibleErrorCode());
  }

  cl::PrintOptionValues();

  SourcePathList = SourcePaths;
  if ((OccurrencesFlag == cl::ZeroOrMore || OccurrencesFlag == cl::Optional) &&
      SourcePathList.empty())
    return llvm::Error::success();
  if (!Compilations) {
    if (!BuildPath.empty()) {
      Compilations =
          CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage);
    } else {
      Compilations = CompilationDatabase::autoDetectFromSource(SourcePaths[0],
                                                               ErrorMessage);
    }
    if (!Compilations) {
      llvm::errs() << "Error while trying to load a compilation database:\n"
                   << ErrorMessage << "Running without flags.\n";
      Compilations.reset(
          new FixedCompilationDatabase(".", std::vector<std::string>()));
    }
  }
  auto AdjustingCompilations =
      llvm::make_unique<ArgumentsAdjustingCompilations>(
          std::move(Compilations));
  Adjuster =
      getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN);
  Adjuster = combineAdjusters(
      std::move(Adjuster),
      getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END));
  AdjustingCompilations->appendArgumentsAdjuster(Adjuster);
  Compilations = std::move(AdjustingCompilations);
  return llvm::Error::success();
}

llvm::Expected<CommonOptionsParser> CommonOptionsParser::create(
    int &argc, const char **argv, llvm::cl::OptionCategory &Category,
    llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
  CommonOptionsParser Parser;
  llvm::Error Err =
      Parser.init(argc, argv, Category, OccurrencesFlag, Overview);
  if (Err)
    return std::move(Err);
  return std::move(Parser);
}

CommonOptionsParser::CommonOptionsParser(
    int &argc, const char **argv, cl::OptionCategory &Category,
    llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
  llvm::Error Err = init(argc, argv, Category, OccurrencesFlag, Overview);
  if (Err) {
    llvm::report_fatal_error(
        "CommonOptionsParser: failed to parse command-line arguments. " +
        llvm::toString(std::move(Err)));
  }
}
<|endoftext|>