kdlibcpp

Форк
0
/
evalexpr.cpp 
1951 строка · 56.2 Кб
1
#include <stdafx.h>
2

3
#include <memory>
4
#include <regex>
5

6
#include "clang/Basic/MemoryBufferCache.h"
7
#include "clang/Basic/TargetOptions.h"
8
#include "clang/Basic/TargetInfo.h"
9

10
#include "clang/Lex/Preprocessor.h"
11
#include "clang/Lex/PreprocessorOptions.h"
12
#include "clang/Lex/HeaderSearch.h"
13
#include "clang/Lex/HeaderSearchOptions.h"
14

15
#include "clang/Frontend/CompilerInstance.h"
16
#include "clang/Frontend/TextDiagnosticPrinter.h"
17

18
#include "kdlib/typedvar.h"
19
#include "kdlib/exceptions.h"
20

21
#include "evalexpr.h"
22
#include "kdlib/strconvert.h"
23
#include "exprparser.h"
24

25
namespace kdlib {
26

27
TypedValue getNumericConst(const clang::Token& token);
28

29
TypedValue getCharConst(const clang::Token& token);
30

31
std::string  getIdentifier(const clang::Token& token);
32

33
kdlib::TypeInfoPtr getStandardIntType(const std::string& name);
34

35
bool isBinOperation(const clang::Token& token);
36

37
///////////////////////////////////////////////////////////////////////////////
38

39
TypedValue evalExpr(const std::wstring& expr, const ScopePtr& scope, const TypeInfoProviderPtr& typeInfoProvider)
40
{
41
    return evalExpr(wstrToStr(expr), scope, typeInfoProvider);
42
}
43

44
///////////////////////////////////////////////////////////////////////////////
45

46
TypedValue evalExpr(const std::string& expr, const ScopePtr& scope, const TypeInfoProviderPtr& typeInfoProvider)
47
{
48
    auto  preprocessorOptions = std::make_shared<clang::PreprocessorOptions>();
49

50
    llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagnosticIDs(new clang::DiagnosticIDs());
51

52
    auto diagnosticOptions = new clang::DiagnosticOptions();
53

54
    //auto textDiagnosticPrinter = new clang::TextDiagnosticPrinter(llvm::outs(), diagnosticOptions);
55

56
    auto diagnosticConsumer = new clang::IgnoringDiagConsumer();
57

58
    clang::DiagnosticsEngine  diagnosticEngine(diagnosticIDs, diagnosticOptions, diagnosticConsumer);
59

60
    clang::LangOptions  langOptions;
61

62
    llvm::IntrusiveRefCntPtr<clang::vfs::InMemoryFileSystem>  memoryFileSystem(new clang::vfs::InMemoryFileSystem());
63

64
    memoryFileSystem->addFile("<input>", 0, llvm::MemoryBuffer::getMemBuffer(expr));
65

66
    clang::FileSystemOptions  fileSystemOptions;
67
    clang::FileManager  fileManager(fileSystemOptions, memoryFileSystem);
68
    clang::SourceManager  sourceManager(diagnosticEngine, fileManager);
69

70
    const clang::FileEntry *pFile = fileManager.getFile("<input>");
71
    clang::FileID  fileID = sourceManager.getOrCreateFileID(pFile, clang::SrcMgr::C_User);
72
    sourceManager.setMainFileID(fileID);
73

74
    clang::MemoryBufferCache  memoryBufferCache;
75

76
    auto headerSearchOptions = std::make_shared<clang::HeaderSearchOptions>();
77
    auto targetOptions = std::make_shared<clang::TargetOptions>();
78
    targetOptions->Triple = llvm::sys::getDefaultTargetTriple();
79
    clang::TargetInfo*  targetInfo = clang::TargetInfo::CreateTargetInfo(diagnosticEngine, targetOptions);
80
    clang::HeaderSearch  headerSearch(headerSearchOptions, sourceManager, diagnosticEngine, langOptions, targetInfo);
81

82
    clang::CompilerInstance  compilerInstance;
83

84
    clang::Preprocessor   preprocessor(
85
        preprocessorOptions,
86
        diagnosticEngine,
87
        langOptions,
88
        sourceManager,
89
        memoryBufferCache,
90
        headerSearch,
91
        compilerInstance
92
    );
93
    preprocessor.Initialize(*targetInfo);
94

95
    preprocessor.EnterMainSourceFile();
96
    diagnosticConsumer->BeginSourceFile(langOptions, &preprocessor);
97

98
    clang::Token token;
99

100
    std::list<clang::Token>  tokens;
101

102
    do {
103

104
        preprocessor.Lex(token);
105

106
        if (diagnosticEngine.hasErrorOccurred())
107
        {
108
            NOT_IMPLEMENTED();
109
        }
110

111
        tokens.push_back(token);
112

113
    } while (!token.is(clang::tok::eof));
114

115
    diagnosticConsumer->EndSourceFile();
116

117
    ExprEval  exprEval(scope, typeInfoProvider, &tokens);
118

119
    return exprEval.getResult();
120
}
121

122
///////////////////////////////////////////////////////////////////////////////
123

124
TypeInfoPtr evalType(const std::wstring& expr, const TypeInfoProviderPtr typeInfoProvider)
125
{
126
    return evalType(wstrToStr(expr), typeInfoProvider);
127
}
128

129
///////////////////////////////////////////////////////////////////////////////
130

131
TypeInfoPtr evalType(const std::string& expr, const TypeInfoProviderPtr typeInfoProvider)
132
{
133
    auto  preprocessorOptions = std::make_shared<clang::PreprocessorOptions>();
134

135
    llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagnosticIDs(new clang::DiagnosticIDs());
136

137
    auto diagnosticOptions = new clang::DiagnosticOptions();
138

139
    //auto textDiagnosticPrinter = new clang::TextDiagnosticPrinter(llvm::outs(), diagnosticOptions);
140

141
    auto diagnosticConsumer = new clang::IgnoringDiagConsumer();
142

143
    clang::DiagnosticsEngine  diagnosticEngine(diagnosticIDs, diagnosticOptions, diagnosticConsumer);
144

145
    clang::LangOptions  langOptions;
146

147
    llvm::IntrusiveRefCntPtr<clang::vfs::InMemoryFileSystem>  memoryFileSystem(new clang::vfs::InMemoryFileSystem());
148
    memoryFileSystem->addFile("<input>", 0, llvm::MemoryBuffer::getMemBuffer(expr.c_str()));
149

150
    clang::FileSystemOptions  fileSystemOptions;
151
    clang::FileManager  fileManager(fileSystemOptions, memoryFileSystem);
152
    clang::SourceManager  sourceManager(diagnosticEngine, fileManager);
153

154
    const clang::FileEntry *pFile = fileManager.getFile("<input>");
155
    clang::FileID  fileID = sourceManager.getOrCreateFileID(pFile, clang::SrcMgr::C_User);
156
    sourceManager.setMainFileID(fileID);
157

158
    clang::MemoryBufferCache  memoryBufferCache;
159

160
    auto headerSearchOptions = std::make_shared<clang::HeaderSearchOptions>();
161
    auto targetOptions = std::make_shared<clang::TargetOptions>();
162
    targetOptions->Triple = llvm::sys::getDefaultTargetTriple();
163
    clang::TargetInfo*  targetInfo = clang::TargetInfo::CreateTargetInfo(diagnosticEngine, targetOptions);
164
    clang::HeaderSearch  headerSearch(headerSearchOptions, sourceManager, diagnosticEngine, langOptions, targetInfo);
165

166
    clang::CompilerInstance  compilerInstance;
167

168
    clang::Preprocessor   preprocessor(
169
        preprocessorOptions,
170
        diagnosticEngine,
171
        langOptions,
172
        sourceManager,
173
        memoryBufferCache,
174
        headerSearch,
175
        compilerInstance
176
    );
177
    preprocessor.Initialize(*targetInfo);
178

179
    preprocessor.EnterMainSourceFile();
180
    diagnosticConsumer->BeginSourceFile(langOptions, &preprocessor);
181

182
    clang::Token token;
183

184
    std::list<clang::Token>  tokens;
185

186
    do {
187

188
        preprocessor.Lex(token);
189

190
        if (diagnosticEngine.hasErrorOccurred())
191
        {
192
            NOT_IMPLEMENTED();
193
        }
194

195
        tokens.push_back(token);
196

197
    } while (!token.is(clang::tok::eof));
198

199
    diagnosticConsumer->EndSourceFile();
200

201
    TypeEval  exprEval(ScopePtr(new ScopeList()), typeInfoProvider, &tokens);
202

203
    return exprEval.getResult();
204
}
205

206
///////////////////////////////////////////////////////////////////////////////
207

208
ExprEval::ExprEval(const ScopePtr& scope,
209
    const TypeInfoProviderPtr& typeInfoProvider,
210
    std::list<clang::Token>* tokens,
211
    clang::tok::TokenKind  endToken)
212
{
213
    m_scope = scope;
214
    m_typeInfoProvider = typeInfoProvider;
215
    m_tokens = tokens;
216
    m_endToken = endToken;
217
}
218

219
///////////////////////////////////////////////////////////////////////////////
220

221
TypedValue  ExprEval::getResult()
222
{
223
    std::list<TypedValue>  operands;
224
    std::list<BinOperation*> operations;
225

226
    std::unique_ptr<UnaryOperation>  ternaryOp;
227

228
    while ( true )
229
    {
230
        UnaryOperation*  preOp = 0;
231
        std::list<UnaryOperation*>  preOperations;
232
        while (0 != (preOp = getPreUnaryOperation()))
233
        {
234
            preOperations.push_front(preOp);
235
        }
236

237
        auto  val = getOperand();
238

239
        UnaryOperation*  postOp = 0;
240
        std::list<UnaryOperation*>  postOperations;
241
        while (0 != (postOp = getPostUnaryOperation()))
242
        {
243
            postOperations.push_back(postOp);
244
        }
245

246
        for (auto op : postOperations)
247
        {
248
            val = op->getResult(val);
249
            delete op;
250
        }
251

252
        for (auto op : preOperations)
253
        {
254
            val = op->getResult(val);
255
            delete op;
256
        }
257

258
        operands.push_back(val);
259

260
        auto token = m_tokens->front();
261

262
        if (token.is(clang::tok::question))
263
        {
264
            ternaryOp.reset(getTernaryOperation());
265
            break;
266
        }
267

268
        if (token.is(m_endToken))
269
        {
270
            m_tokens->pop_front();
271
            break;
272
        }
273

274
        operations.push_back(getOperation());
275
    }
276

277
    while (!operations.empty())
278
    {
279
        auto  op = std::max_element(operations.begin(), operations.end(),
280
            [](const BinOperation* op1, const BinOperation* op2)
281
            {
282
                return op1->getPriority() > op2->getPriority();
283
            });
284

285
        auto op1 = operands.begin();
286
        std::advance(op1, std::distance(operations.begin(), op));
287

288
        auto op2 = operands.begin();
289
        std::advance(op2, std::distance(operations.begin(), op) + 1);
290

291
        auto res = (*op)->getResult(*op1, *op2);
292

293
        delete *op;
294
        operations.erase(op);
295

296
        *op1 = res;
297
        operands.erase(op2);
298
    }
299

300
    if (ternaryOp)
301
        return ternaryOp->getResult(operands.front());
302

303
    return operands.front();
304
}
305

306
///////////////////////////////////////////////////////////////////////////////
307

308
TypedValue ExprEval::getOperand()
309
{
310
    if (m_tokens->empty())
311
        throw ExprException(L"error syntax");
312

313
    auto token = m_tokens->front();
314

315
    if (token.is(clang::tok::identifier))
316
    {
317
        return getIdentifierValue();
318
    }
319

320
    m_tokens->pop_front();
321

322
    if (token.is(clang::tok::numeric_constant))
323
    {
324
        return getNumericConst(token);
325
    }
326

327
    if (token.isOneOf(clang::tok::char_constant, clang::tok::wide_char_constant))
328
    {
329
        return getCharConst(token);
330
    }
331

332
    if (token.is(clang::tok::l_paren))
333
    {
334
        return ExprEval(m_scope, m_typeInfoProvider, m_tokens, clang::tok::r_paren).getResult();
335
    }
336

337
    if (token.is(clang::tok::kw_sizeof))
338
    {
339
        return getSizeof();
340
    }
341
    
342
    throw ExprException(L"error syntax");
343
}
344

345
///////////////////////////////////////////////////////////////////////////////
346

347
BinOperation* ExprEval::getOperation()
348
{
349
    if (m_tokens->empty())
350
        throw ExprException(L"error syntax");
351

352
    auto  token = m_tokens->front();
353

354
    if (!isBinOperation(token))
355
        throw ExprException(L"error syntax");
356

357
    m_tokens->pop_front();
358

359
    if (token.is(clang::tok::plus))
360
        return new AddExprOperation();
361

362
    if (token.is(clang::tok::star))
363
        return new MultExprOperation();
364

365
    if (token.is(clang::tok::minus))
366
        return new SubExprOperation();
367

368
    if (token.is(clang::tok::slash))
369
        return new DivExprOperation();
370

371
    if (token.is(clang::tok::percent))
372
        return new ModExprOperation();
373

374
    if (token.is(clang::tok::equalequal))
375
        return new EqualOperation();
376

377
    if (token.is(clang::tok::exclaimequal))
378
        return new NotEqualOperation();
379

380
    if (token.is(clang::tok::less))
381
        return new LessOperation();
382

383
    if (token.is(clang::tok::lessequal))
384
        return new LessEqualOperation();
385

386
    if (token.is(clang::tok::greater))
387
        return new GreaterOperation();
388

389
    if (token.is(clang::tok::greaterequal))
390
        return new GreaterEqualOperation();
391

392
    if (token.is(clang::tok::lessless))
393
        return new LeftShiftOperation();
394

395
    if (token.is(clang::tok::greatergreater))
396
        return new RightShiftOperation();
397

398
    if (token.is(clang::tok::amp))
399
        return new BitwiseAndOperation();
400

401
    if (token.is(clang::tok::pipe))
402
        return new BitwiseOrOperation();
403

404
    if (token.is(clang::tok::caret))
405
        return new BitwiseXorOperation();
406

407
    if (token.is(clang::tok::pipepipe))
408
        return new BoolOrOperation();
409

410
    if (token.is(clang::tok::ampamp))
411
        return new BoolAndOperation();
412

413
    throw ExprException(L"error syntax");
414
}
415

416
///////////////////////////////////////////////////////////////////////////////
417

418
UnaryOperation* ExprEval::getPreUnaryOperation()
419
{
420
    if (m_tokens->empty())
421
        throw ExprException(L"error syntax");
422

423
    auto  token = m_tokens->front();
424

425
    if (token.isOneOf(clang::tok::numeric_constant,
426
        clang::tok::identifier,
427
        clang::tok::char_constant,
428
        clang::tok::wide_char_constant) )
429
            return nullptr;
430

431
    if (token.is(clang::tok::l_paren))
432
        return getTypeCastOperation();
433

434
    if (token.is(clang::tok::kw_sizeof))
435
        return getSizeofOperation();
436

437
    if (isBaseTypeKeyWord(token))
438
        return nullptr;
439

440
    m_tokens->pop_front();
441

442
    if (token.is(clang::tok::minus))
443
        return new UnMinusOperation();
444

445
    if (token.is(clang::tok::plus))
446
        return new UnPlusOperation();
447

448
    if (token.is(clang::tok::star))
449
        return new DerefOperation();
450

451
    if (token.is(clang::tok::tilde))
452
        return new BitwiseNotOperation();
453

454
    if (token.is(clang::tok::exclaim))
455
        return new BooleanNotOperation();
456

457
    if (token.is(clang::tok::amp))
458
        return new RefOperation();
459

460
    throw ExprException(L"error syntax");
461

462
}
463

464
///////////////////////////////////////////////////////////////////////////////
465

466
UnaryOperation* ExprEval::getPostUnaryOperation()
467
{
468
    assert(!m_tokens->empty());
469

470
    auto  token = m_tokens->front();
471

472
    if (token.isOneOf(m_endToken, clang::tok::question))
473
        return nullptr;
474

475
    if (isBinOperation(token))
476
        return nullptr;
477

478
    if (token.is(clang::tok::l_square))
479
        return getArrayOperation();
480

481
    if (token.is(clang::tok::period))
482
        return getAttributeOperation();
483

484
    if (token.is(clang::tok::arrow))
485
        return getAttributeOperationPtr();
486

487
    throw ExprException(L"error syntax");
488
}
489

490
/////////////////////////////////////////////////////////////////////////////////
491

492
UnaryOperation* ExprEval::getArrayOperation()
493
{
494
    auto  token = m_tokens->front();
495

496
    if (!token.is(clang::tok::l_square))
497
        throw ExprException(L"error syntax");
498

499
    m_tokens->pop_front();
500

501
    auto indexVal = ExprEval(m_scope, m_typeInfoProvider, m_tokens, clang::tok::r_square).getResult();
502

503
    return new ArrayValueOperation(indexVal);
504
}
505

506
/////////////////////////////////////////////////////////////////////////////////
507

508
UnaryOperation* ExprEval::getAttributeOperation()
509
{
510
    auto  token = m_tokens->front();
511

512
    if (!token.is(clang::tok::period))
513
        throw ExprException(L"error syntax");
514

515
    m_tokens->pop_front();
516

517
    if (m_tokens->front().is(m_endToken))
518
        throw ExprException(L"error syntax");
519

520
    token = m_tokens->front();
521
    
522
    if (!token.is(clang::tok::identifier))
523
        throw ExprException(L"error syntax");
524

525
    std::string  name(token.getIdentifierInfo()->getNameStart(), token.getLength());
526

527
    m_tokens->pop_front();
528

529
    return new AttributeOperation(name);
530
}
531

532
/////////////////////////////////////////////////////////////////////////////////
533

534
UnaryOperation* ExprEval::getAttributeOperationPtr()
535
{
536
    auto  token = m_tokens->front();
537

538
    if (!token.is(clang::tok::arrow))
539
        throw ExprException(L"error syntax");
540

541
    m_tokens->pop_front();
542

543
    if (m_tokens->front().is(m_endToken))
544
        throw ExprException(L"error syntax");
545

546
    token = m_tokens->front();
547

548
    if (!token.is(clang::tok::identifier))
549
        throw ExprException(L"error syntax");
550

551
    std::string  name(token.getIdentifierInfo()->getNameStart(), token.getLength());
552

553
    m_tokens->pop_front();
554

555
    return new AttributeOperation(name);
556
}
557

558
/////////////////////////////////////////////////////////////////////////////////
559

560
UnaryOperation* ExprEval::getSizeofOperation()
561
{
562
    auto token = m_tokens->front();
563

564
    if ( !token.is( clang::tok::kw_sizeof ) )
565
        throw ExprException(L"error syntax");
566

567
    if ( std::next(m_tokens->begin())->is( m_endToken) )
568
        throw ExprException(L"error syntax");
569

570
    if (std::next(m_tokens->begin())->is(clang::tok::l_paren))
571
        return nullptr;
572

573
    m_tokens->pop_front();
574
        
575
    return new SizeofOperation();
576
}
577

578
///////////////////////////////////////////////////////////////////////////////
579

580
UnaryOperation* ExprEval::getTypeCastOperation()
581
{
582
    auto token = m_tokens->front();
583

584
    if (!token.is(clang::tok::l_paren))
585
        throw ExprException(L"error syntax");
586

587
    try {
588

589
        std::list<clang::Token>   exprCopy(m_tokens->begin(), m_tokens->end());
590

591
        exprCopy.pop_front();
592

593
        TypeInfoPtr  typeCast = TypeEval(m_scope, m_typeInfoProvider, &exprCopy, clang::tok::r_paren).getResult();
594

595
        *m_tokens = exprCopy;
596

597
        return new TypeCastOperation(typeCast);
598
    }
599
    catch (DbgException&)
600
    {
601
    }
602

603
    return nullptr;
604
}
605

606

607
///////////////////////////////////////////////////////////////////////////////
608

609
UnaryOperation* ExprEval::getTernaryOperation()
610
{
611
    auto token = m_tokens->front();
612

613
    if (!token.is(clang::tok::question))
614
        throw ExprException(L"error syntax");
615

616
    m_tokens->pop_front();
617

618
    TypedValue  val1 = ExprEval(m_scope, m_typeInfoProvider, m_tokens, clang::tok::colon).getResult();
619

620
    TypedValue  val2 = ExprEval(m_scope, m_typeInfoProvider, m_tokens, m_endToken).getResult();
621

622
    return new TrenaryOperation(val1, val2);
623
}
624

625
///////////////////////////////////////////////////////////////////////////////
626

627
size_t ExprEval::getSizeof()
628
{
629
    auto token = m_tokens->front();
630

631
    if (!token.is(clang::tok::l_paren))
632
        throw  ExprException(L"error syntax");
633

634
    m_tokens->pop_front();
635

636
    if (m_tokens->front().is(m_endToken))
637
        throw ExprException(L"error syntax");
638

639
    try {
640
        std::list<clang::Token>   exprCopy(m_tokens->begin(), m_tokens->end());
641
        TypedValue  exprResult = ExprEval(m_scope, m_typeInfoProvider, &exprCopy, clang::tok::r_paren).getResult();
642
        *m_tokens = exprCopy;
643
        return exprResult.getType()->getSize();
644
    }
645
    catch (DbgException&)
646
    {  }
647

648
    TypeInfoPtr  typeInfo = TypeEval(m_scope, m_typeInfoProvider, m_tokens, clang::tok::r_paren).getResult();
649
    if ( !typeInfo )
650
        throw ExprException(L"error syntax");
651

652
    return typeInfo->getSize();
653
}
654

655
///////////////////////////////////////////////////////////////////////////////
656

657
TypedValue ExprEval::getIdentifierValue()
658
{
659
    std::string  fullName;
660

661
    do {
662

663
        if (m_tokens->front().is(m_endToken))
664
            break;
665

666
        auto token = m_tokens->front();
667
 
668
        if (token.is(clang::tok::identifier))
669
        {
670
            m_tokens->pop_front();
671
            std::string  name(token.getIdentifierInfo()->getNameStart(), token.getLength());
672
            fullName += name;             
673
        }
674
        else if ( token.is(clang::tok::colon) )
675
        {
676
            m_tokens->pop_front();
677
            fullName += ":";
678
        }
679
        else
680
        {
681
            break;
682
        }
683

684
    } while (true);
685

686

687
    if (fullName == "true")
688
        return TypedValue(true);
689

690
    if (fullName == "false")
691
        return TypedValue(false);
692

693
    if (fullName == "nullptr")
694
        return TypedValue(nullptr);
695

696
    TypedValue   result;
697
    std::wstring  wname = strToWStr(fullName);
698
    if (m_scope->find(wname, result))
699
        return result;
700

701
    try {
702
        return evalType(fullName, m_typeInfoProvider)->getValue();
703
    }
704
    catch (DbgException&)
705
    {
706
    }
707

708
    throw  ExprException(L"error syntax");
709

710
}
711

712
///////////////////////////////////////////////////////////////////////////////
713

714
TypeInfoPtr applyComplexModifierRecursive(const parser::ComplexMatcher& matcher, TypeInfoPtr& typeInfo_)
715
{
716
    TypeInfoPtr  typeInfo = typeInfo_;
717

718
    if (matcher.isReference())
719
    {
720
        if (typeInfo->isVoid() )
721
            throw  ExprException(L"error syntax");
722
    }
723

724
    if (matcher.isPointer())
725
    {
726
        for ( auto p : matcher.getPointerMatcher().getPointerMatchers() )
727
            typeInfo = typeInfo->ptrTo();
728
    }
729

730
    if (matcher.isArray())
731
    {
732
        auto  indices = matcher.getArrayMatcher().getArrayIndices();
733
        for (auto it = indices.rbegin(); it != indices.rend(); ++it)
734
        {
735
            if (it->isIndexComplete())
736
            {
737
                auto i = getNumericConst(*it->getIndexMatcher().getMatchResult().begin()).getValue().asLongLong();
738
                typeInfo = typeInfo->arrayOf(i);
739
            }
740
            else
741
            {
742
                typeInfo = typeInfo->arrayOf();
743
            }
744
        }
745
    }
746
  
747
    if (matcher.isNestedMatcher())
748
    {
749
        typeInfo = applyComplexModifierRecursive(matcher.getNestedMatcher().getInnerMatcher(), typeInfo);
750
    }
751

752
    return typeInfo;
753
}
754

755
///////////////////////////////////////////////////////////////////////////////
756

757
std::string getTypeModifierRecursive(const parser::ComplexMatcher& matcher)
758
{
759
    std::stringstream  sstr;
760

761
    if (matcher.isPointer())
762
    {
763
        bool  needSpace = false;
764
        for (auto p : matcher.getPointerMatcher().getPointerMatchers())
765
        {
766
            if (needSpace)
767
            {
768
                sstr << ' ';
769
                needSpace = false;
770
            }
771
            sstr << '*';
772
            if (p.isConst())
773
            {
774
                sstr << "const";
775
                needSpace = true;
776
            }
777
        }
778
    }
779

780
    if (matcher.isReference())
781
    {
782
        if (matcher.getRefMatcher().isLvalue())
783
            sstr << '&';
784
        else
785
            sstr << "&&";
786
    }
787

788
    if (matcher.isNestedMatcher())
789
    {
790
        sstr << '(' << getTypeModifierRecursive(matcher.getNestedMatcher().getInnerMatcher()) << ')';
791
    }   
792
    
793
    if (matcher.isArray())
794
    {
795
        auto  indices = matcher.getArrayMatcher().getArrayIndices();
796
        for (auto it = indices.rbegin(); it != indices.rend(); ++it)
797
        {
798
            if (it->isIndexComplete())
799
            {
800
                auto i = getNumericConst(*it->getIndexMatcher().getMatchResult().begin()).getValue().asLongLong();
801
                sstr << '[' << std::dec << i << ']';
802
            }
803
            else
804
            {
805
                sstr << "[]";
806
            }
807
        }
808
    }
809

810
    return sstr.str();
811
}
812

813
//////////////////////////////////////////////////////////////////////////////
814

815
TypeInfoPtr TypeEval::getResult()
816
{
817
    using namespace parser;
818

819
    QualifiedTypeMatcher typeMatcher;
820

821
    auto matcher = all_of(typeMatcher, token_is(m_endToken));
822
    auto matchResult = matcher.match(std::make_pair(m_tokens->cbegin(), m_tokens->cend()));
823

824
    if (!matchResult.isMatched())
825
        throw  ExprException(L"error syntax");
826

827
    TypeInfoPtr  typeInfo;
828

829
    if (typeMatcher.isBasedType())
830
    {
831
        typeInfo = typeMatcher.getBaseTypeMatcher().getBaseType();
832
    }
833
    else if (typeMatcher.isStandardIntType())
834
    {
835
        typeInfo = getStandardIntType(typeMatcher.getStandardIntMatcher());
836
    }
837
    else if (typeMatcher.isCustomType())
838
    {
839
        typeInfo = getCustomType(typeMatcher.getCustomMatcher());
840
    }
841
    else
842
    {
843
        NOT_IMPLEMENTED();
844
    }
845

846
    if (!typeInfo)
847
        throw  ExprException(L"error syntax");
848

849
    if (typeMatcher.isComplexType() )
850
    {
851
        typeInfo = applyComplexModifierRecursive(typeMatcher.getComplexMather(), typeInfo);
852
    }  
853

854
    m_tokens->erase(matchResult.begin(), matchResult.end());
855

856
    return typeInfo;
857
}
858

859
///////////////////////////////////////////////////////////////////////////////
860

861
std::list<std::string>  TypeEval::getTemplateArgList()
862
{
863
    using namespace parser;
864

865
    TypeMatcher typeMatcher;
866

867
    auto matcher = all_of(typeMatcher, token_is(m_endToken));
868
    auto matchResult = matcher.match(std::make_pair(m_tokens->cbegin(), m_tokens->cend()));
869

870
    if (!matchResult.isMatched())
871
        throw  ExprException(L"error syntax");
872

873
    if (!typeMatcher.isCustomType())
874
        throw  ExprException(L"error syntax");
875

876
    const auto& customMatcher = typeMatcher.getCustomMatcher();
877

878
    if (customMatcher.isTemplate())
879
    {
880
        const auto& argListMatcher = customMatcher.getTemplateMatcher().getTemplateArgs();
881

882
        return getTemplateArgList(argListMatcher);
883
    }
884

885
    if (customMatcher.isNestedTemplate())
886
    {
887
        const auto& templateMatcher = customMatcher.getNestedTemplateMatcher();
888
        const auto& argListMatcher = templateMatcher.getTemplateArgs1();
889
        
890
        std::list<std::string>  argStrList = getTemplateArgList(argListMatcher);
891

892
        std::string  templateName = templateMatcher.getNestedTemplateName();
893

894
        templateName += '<';
895

896
        const auto& nestedArgList = getTemplateArgList(templateMatcher.getTemplateArgs2());
897

898
        std::string argsStr;
899
        for (const auto& arg : nestedArgList)
900
        {
901
            if (!argsStr.empty())
902
                argsStr += ',';
903
            argsStr += arg;
904
        }
905

906
        templateName += argsStr;
907

908
        templateName += '>';
909

910
        argStrList.push_back(templateName);
911

912
        return argStrList;
913
    }
914

915
    throw  ExprException(L"error syntax");
916
}
917

918
///////////////////////////////////////////////////////////////////////////////
919

920
std::list<std::string>  TypeEval::getTemplateArgList(const parser::ListMatcher<parser::TemplateArgMatcher>& argList)
921
{
922
    std::list<std::string>  argStrList;
923

924
    for (auto& arg : argList)
925
    {
926
        if (arg.isType())
927
        {
928
            argStrList.push_back(getTypeName(arg.getTypeMatcher()));
929
        }
930
        else if (arg.isExpression())
931
        {
932
            auto  value = ExprEval2(m_scope, m_typeInfoProvider, arg.getExpressionMatcher().getMatchResult().getMatchedRange()).getResult();
933
            argStrList.push_back(std::to_string(value.getValue().asLongLong()));
934
        }
935
        else
936
        {
937
            throw  ExprException(L"error syntax");
938
        }
939
    }
940

941
    return argStrList;
942
}
943

944
///////////////////////////////////////////////////////////////////////////////
945

946
std::string TypeEval::getTemplateArgs(const parser::ListMatcher<parser::TemplateArgMatcher>& argListMatcher)
947
{
948
    const auto& argList = getTemplateArgList(argListMatcher);
949

950
    std::string argsStr;
951
    for (const auto& arg : argList)
952
    {
953
        if (!argsStr.empty())
954
            argsStr += ',';
955
        argsStr += arg;
956
    }
957

958
    return argsStr;
959
}
960

961
///////////////////////////////////////////////////////////////////////////////
962

963
std::string TypeEval::getTemplateName(const parser::TemplateMatcher& templateMatcher)
964
{
965
    std::string  templateName = getTemplateArgs(templateMatcher.getTemplateArgs());
966
    
967
    templateName.insert(templateName.begin(), '<');
968
    if (templateName.back() == '>')
969
        templateName.insert(templateName.end(), ' ');
970
    templateName.insert(templateName.end(), '>');
971

972
    return templateName;
973
}
974

975
///////////////////////////////////////////////////////////////////////////////
976

977
std::string TypeEval::getNestedTemplateName(const parser::DoubleTemplateMatcher& templateMatcher)
978
{
979
    std::string  templateName = getTemplateArgs(templateMatcher.getTemplateArgs1());
980

981
    if (!templateName.empty())
982
        templateName += ',';
983

984
    auto nestedTemplate = templateMatcher.getNestedTemplateName();
985

986
    nestedTemplate += '<';
987

988
    nestedTemplate += getTemplateArgs(templateMatcher.getTemplateArgs2());
989

990
    if (nestedTemplate.back() == '>')
991
        nestedTemplate += " >";
992
    else
993
        nestedTemplate += '>';
994

995
    auto fullNestedTypeName = m_typeInfoProvider->makeTypeName(strToWStr(nestedTemplate), L"", templateMatcher.isNetstedTemplateConst());
996

997
    templateName += wstrToStr(fullNestedTypeName);
998

999
    templateName += " >";
1000

1001
    templateName.insert(templateName.begin(), '<');
1002
     
1003
    //templateName += templateMatcher.getNestedTemplateName();
1004

1005
    //templateName += '<';
1006

1007
    //templateName += getTemplateArgs(templateMatcher.getTemplateArgs2());
1008

1009
    //templateName.insert(templateName.begin(), '<');
1010

1011
    //if (templateName.back() == '>')
1012
    //    templateName.insert(templateName.end(), ' ');
1013

1014
    //templateName += "> >";
1015

1016
    return templateName;
1017
}
1018

1019
///////////////////////////////////////////////////////////////////////////////
1020

1021
TypeInfoPtr TypeEval::getCustomType(const parser::CustomTypeMatcher&  customMatcher)
1022
{
1023
    TypeInfoPtr  typeInfo;
1024

1025
    std::string  typeName = customMatcher.getTypeNameMatcher().getName();
1026

1027
    if (customMatcher.isTemplate() || customMatcher.isNestedTemplate() )
1028
    {
1029
        for (auto namespaceMatcher : customMatcher.getTypeNameMatcher().getNamespaces())
1030
        {
1031
            typeName += "::";
1032
            typeName += namespaceMatcher.getName();
1033
        }
1034

1035
        if (customMatcher.isTemplate())
1036
        {
1037
            typeName += getTemplateName(customMatcher.getTemplateMatcher());
1038
        }
1039
        else if (customMatcher.isNestedTemplate())
1040
        {
1041
            typeName += getNestedTemplateName(customMatcher.getNestedTemplateMatcher());
1042
        }
1043

1044
        typeInfo = m_typeInfoProvider->getTypeByName(strToWStr(typeName));
1045

1046
        for (auto fieldMatcher : customMatcher.getFields())
1047
        {
1048
            auto fieldName = fieldMatcher.getName();
1049
            typeInfo = typeInfo->getElement(strToWStr(fieldName));
1050
        }
1051
    }
1052
    else
1053
    {
1054
        try 
1055
        {
1056
            typeInfo = m_typeInfoProvider->getTypeByName(strToWStr(typeName));
1057
        }
1058
        catch (SymbolException&)
1059
        {}
1060

1061
        for (auto namespaceMatcher : customMatcher.getTypeNameMatcher().getNamespaces())
1062
        {
1063

1064
            if (typeInfo)
1065
            {
1066
                auto fieldName = namespaceMatcher.getName();
1067
                typeInfo = typeInfo->getElement(strToWStr(fieldName));
1068
            }
1069
            else
1070
            {
1071
                typeName += "::";
1072
                typeName += namespaceMatcher.getName();
1073

1074
                try 
1075
                {
1076
                    typeInfo = m_typeInfoProvider->getTypeByName(strToWStr(typeName));
1077
                }
1078
                catch (SymbolException&)
1079
                { }
1080
            }
1081
        }
1082
    }
1083
    
1084
    return typeInfo;
1085
}
1086

1087
///////////////////////////////////////////////////////////////////////////////
1088

1089
std::string TypeEval::getTypeName(const parser::QualifiedTypeMatcher& typeMatcher)
1090
{
1091
    std::string    typeName;
1092
    std::string    typeQualifier;
1093

1094
    if (typeMatcher.isBasedType())
1095
    {
1096
        typeName =  typeMatcher.getBaseTypeMatcher().getTypeName();
1097
    }
1098
    else
1099
    if (typeMatcher.isStandardIntType())
1100
    {
1101
        auto& token = typeMatcher.getStandardIntMatcher().getMatchResult().begin();
1102
        typeName = std::string(token->getIdentifierInfo()->getNameStart(), token->getLength());
1103
    }
1104
    else
1105
    if (typeMatcher.isCustomType())
1106
    {
1107
        typeName = getCustomTypeName(typeMatcher.getCustomMatcher());
1108
    }
1109
    else
1110
    {
1111
        throw  ExprException(L"error syntax");
1112
    }
1113

1114
    if (typeMatcher.isComplexType())
1115
     {
1116
         typeQualifier = getTypeModifierRecursive(typeMatcher.getComplexMather());
1117
     }
1118

1119
    auto fullTypeName = m_typeInfoProvider->makeTypeName(strToWStr(typeName), strToWStr(typeQualifier), typeMatcher.isConst());
1120

1121
    return wstrToStr(fullTypeName);
1122
}
1123

1124
///////////////////////////////////////////////////////////////////////////////
1125

1126
std::string TypeEval::getCustomTypeName(const parser::CustomTypeMatcher& customMatcher)
1127
{
1128
    std::string   typeName = customMatcher.getTypeNameMatcher().getName();
1129

1130
    if (customMatcher.isTemplate() || customMatcher.isNestedTemplate())
1131
    {
1132
        for (auto namespaceMatcher : customMatcher.getTypeNameMatcher().getNamespaces())
1133
        {
1134
            typeName += "::";
1135
            typeName += namespaceMatcher.getName();
1136
        }
1137

1138
        if (customMatcher.isTemplate())
1139
        {
1140
            typeName += getTemplateName(customMatcher.getTemplateMatcher());
1141
        }
1142
        else if (customMatcher.isNestedTemplate())
1143
        {
1144
            typeName += getNestedTemplateName(customMatcher.getNestedTemplateMatcher());
1145
        }
1146

1147
        for (auto fieldMatcher : customMatcher.getFields())
1148
        {
1149
            typeName += "::";
1150
            typeName += fieldMatcher.getName();
1151
        }
1152
    }
1153
    else
1154
    {
1155
        for (auto namespaceMatcher : customMatcher.getTypeNameMatcher().getNamespaces())
1156
        {
1157
            typeName += "::";
1158
            typeName += namespaceMatcher.getName();
1159
        }
1160
    }
1161

1162
    return typeName;
1163
}
1164

1165
///////////////////////////////////////////////////////////////////////////////
1166

1167
TypeInfoPtr TypeEval::getStandardIntType(const parser::StandardIntMatcher& stdIntMatcher)
1168
{
1169
    auto& token = stdIntMatcher.getMatchResult().begin();
1170
    std::string  name(token->getIdentifierInfo()->getNameStart(), token->getLength());
1171
    return kdlib::getStandardIntType(name);
1172
}
1173

1174
///////////////////////////////////////////////////////////////////////////////
1175

1176
static const std::regex integralLiteralRe("(0x[0-9a-f]+|0[0-7]+|[1-9][0-9]*|0)((l)|(u)|(ul|lu)|(ll)|(ull|llu))?", std::regex::icase);
1177
static const std::regex floatLiteralRe("\\d*((\\.(\\d+(e[+\\-]?\\d+)?)?)|(e[+\\-]?\\d+))((f)|(l))?", std::regex::icase);
1178

1179
TypedValue  getNumericConst(const clang::Token& token)
1180
{
1181
    if (token.is(clang::tok::identifier))
1182
    {
1183
        std::string  strVal = token.getIdentifierInfo()->getName();
1184

1185
        if (strVal == "false")
1186
            return TypedValue(false);
1187
        if (strVal == "true")
1188
            return TypedValue(true);
1189

1190
        throw ExprException(L"error syntax");
1191
    }
1192

1193
    if (token.isOneOf(clang::tok::char_constant, clang::tok::wide_char_constant))
1194
        return  getCharConst(token);
1195

1196
    std::string  strVal(token.getLiteralData(), token.getLength());
1197

1198
    std::smatch  smatch;
1199

1200
    if (std::regex_match(strVal, smatch, integralLiteralRe))
1201
    {
1202
        bool  isSuffix = smatch[2].matched;
1203
        bool  isLong = smatch[3].matched;
1204
        bool  isUnsigned = smatch[4].matched;
1205
        bool  isULong = smatch[5].matched;
1206
        bool  isLongLong = smatch[6].matched;
1207
        bool  isULongLong = smatch[7].matched;
1208

1209
        if (!isSuffix || isLong )
1210
        {
1211
            try {
1212
                return std::stol(strVal, nullptr, 0);
1213
            } 
1214
            catch (std::out_of_range&)
1215
            {}
1216

1217
            try {
1218
                return std::stoul(strVal, nullptr, 0);
1219
            }
1220
            catch (std::out_of_range&)
1221
            {}
1222

1223
            try {
1224
                return std::stoll(strVal, nullptr, 0);
1225
            }
1226
            catch (std::out_of_range&)
1227
            {}
1228

1229
            try {
1230
                return std::stoull(strVal, nullptr, 0);
1231
            }
1232
            catch (std::out_of_range&)
1233
            {}
1234

1235
            throw ExprException(L"error syntax");
1236
        }
1237
        else
1238
        {
1239
            if (isUnsigned || isULong )
1240
            {
1241

1242
                try {
1243
                    return std::stoul(strVal, nullptr, 0);
1244
                }
1245
                catch (std::out_of_range&)
1246
                {}
1247

1248
                try {
1249
                    return std::stoull(strVal, nullptr, 0);
1250
                }
1251
                catch (std::out_of_range&)
1252
                {}
1253

1254
                throw ExprException(L"error syntax");
1255
            }
1256
            else if (isLongLong)
1257
            {
1258
                try {
1259
                    return std::stoll(strVal, nullptr, 0);
1260
                }
1261
                catch (std::out_of_range&)
1262
                {
1263
                }
1264

1265
                throw ExprException(L"error syntax");
1266
            }
1267
            else if (isULongLong)
1268
            {
1269
                try {
1270
                    return std::stoull(strVal, nullptr, 0);
1271
                }
1272
                catch (std::out_of_range&)
1273
                {
1274
                }
1275

1276
                throw ExprException(L"error syntax");
1277
            }
1278

1279
            assert(0);
1280
        }
1281
    }
1282
    else if (std::regex_match(strVal, smatch, floatLiteralRe))
1283
    {
1284
        bool isLong = !smatch[7].matched;
1285

1286
        try {
1287
            if (isLong)
1288
                return std::stod(strVal);
1289
            else
1290
                return std::stof(strVal);
1291
        }
1292
        catch (std::exception&)
1293
        {
1294
        }
1295

1296
        throw ExprException(L"error syntax");
1297
    }
1298

1299
    throw ExprException(L"error syntax");
1300
}
1301

1302
///////////////////////////////////////////////////////////////////////////////
1303

1304
static const std::regex charLiteralRe("(L'(.).*')|('(.{1,4})')", std::regex::icase);
1305

1306
TypedValue getCharConst(const clang::Token& token)
1307
{
1308
    std::string  strVal(token.getLiteralData(), token.getLength());
1309

1310
    std::smatch  smatch;
1311

1312
    const int  a = 'ff';
1313

1314
    if (std::regex_match(strVal, smatch, charLiteralRe))
1315
    {
1316
        if (smatch[1].matched)
1317
        {
1318
            return strToWStr(smatch[2].str())[0];
1319
        }
1320

1321
        auto  bytesSeq = smatch[4].str();
1322
        if (bytesSeq.size() == 1)
1323
            return bytesSeq[0];
1324

1325
        int  intRes = 0;
1326
        for (auto byte : bytesSeq)
1327
            intRes = ( intRes << 8 ) | byte;
1328

1329
        return intRes;
1330
    }
1331

1332
    throw ExprException(L"error syntax");
1333
}
1334

1335
///////////////////////////////////////////////////////////////////////////////
1336

1337
std::string  tokenToStr(const clang::Token& token)
1338
{
1339
    switch (token.getKind())
1340
    {
1341
    case clang::tok::identifier:
1342
        return std::string(token.getIdentifierInfo()->getNameStart(), token.getLength());
1343
    case clang::tok::numeric_constant:
1344
        return std::string(token.getLiteralData(), token.getLength());       
1345
    case clang::tok::less:
1346
        return "<";
1347
    case clang::tok::greater:
1348
        return ">";
1349
    case clang::tok::kw_bool:
1350
        return "bool";
1351
    case clang::tok::kw_char:
1352
        return "char";
1353
    case clang::tok::kw_char16_t:
1354
        return "char16_t";
1355
    case clang::tok::kw_char32_t:
1356
        return "char32_t";
1357
    case clang::tok::kw_double:
1358
        return "double";
1359
    case clang::tok::kw_float:
1360
        return "float";
1361
    case clang::tok::kw_int:
1362
        return "int";
1363
    case clang::tok::kw_long:
1364
        return "long";
1365
    case clang::tok::kw_short:
1366
        return "short";
1367
    case clang::tok::kw_signed:
1368
        return "signed";
1369
    case clang::tok::kw_unsigned:
1370
        return "unsigned";
1371
    case clang::tok::kw_void:
1372
        return "void";
1373
    case clang::tok::kw_wchar_t:
1374
        return "wchar_t";
1375
    case clang::tok::kw_struct:
1376
        return "struct";
1377
    case clang::tok::minus:
1378
        return "-";
1379
    case clang::tok::plus:
1380
        return "+";
1381
    case clang::tok::colon:
1382
        return ":";
1383
    case clang::tok::star:
1384
        return "*";
1385
    case clang::tok::l_square:
1386
        return "[";
1387
    case clang::tok::r_square:
1388
        return "]";
1389
    case clang::tok::l_paren:
1390
        return "(";
1391
    case clang::tok::r_paren:
1392
        return ")";
1393
    case clang::tok::amp:
1394
        return "&";
1395
    case clang::tok::ampamp:
1396
        return "&&";
1397
    case clang::tok::comma:
1398
        return ",";
1399
    }
1400

1401
    NOT_IMPLEMENTED();
1402
}
1403

1404
///////////////////////////////////////////////////////////////////////////////
1405

1406
bool isBaseTypeKeyWord(const clang::Token& token)
1407
{
1408
    if (token.isOneOf(
1409
        clang::tok::kw_bool,
1410
        clang::tok::kw_char,
1411
        clang::tok::kw_char16_t,
1412
        clang::tok::kw_char32_t,
1413
        clang::tok::kw_double,
1414
        clang::tok::kw_float,
1415
        clang::tok::kw_int,
1416
        clang::tok::kw_long,
1417
        clang::tok::kw_short,
1418
        clang::tok::kw_signed,
1419
        clang::tok::kw_unsigned,
1420
        clang::tok::kw_void,
1421
        clang::tok::kw_wchar_t
1422
    )) return true;
1423

1424
    return isInt64KeyWord(token);
1425
}
1426

1427
///////////////////////////////////////////////////////////////////////////////
1428

1429
static const std::map< std::string, std::function<kdlib::TypeInfoPtr(void)>  >  standardIntTypes = {
1430
    { "wchar_t", []() { return kdlib::loadType(L"Int2B"); }  },
1431
    { "int8_t", []() { return kdlib::loadType(L"Int1B"); } },
1432
    { "uint8_t", []() { return kdlib::loadType(L"UInt1B"); } },
1433
    { "int16_t", []() { return kdlib::loadType(L"Int2B"); } },
1434
    { "uint16_t",[]() { return kdlib::loadType(L"UInt2B"); } },
1435
    { "int32_t", []() { return kdlib::loadType(L"Int4B"); } },
1436
    { "uint32_t", []() { return kdlib::loadType(L"UInt4B"); } },
1437
    { "int64_t", []() { return kdlib::loadType(L"Int8B"); } },
1438
    { "uint64_t", []() { return kdlib::loadType(L"UInt8B"); } },
1439
    { "size_t", []() { return kdlib::ptrSize() == 4 ? kdlib::loadType(L"UInt4B") : kdlib::loadType(L"UInt8B");  } },
1440
    { "intptr_t", []() { return kdlib::ptrSize() == 4 ? kdlib::loadType(L"Int4B") : kdlib::loadType(L"Int8B");  } },
1441
    { "uintptr_t", []() { return kdlib::ptrSize() == 4 ? kdlib::loadType(L"UInt4B") : kdlib::loadType(L"UInt8B");  } },
1442
    { "bool", []() { return kdlib::loadType(L"Bool");  } },
1443
    { "void", []() { return kdlib::loadType(L"Void"); } }
1444
};
1445

1446
bool isStandardIntType(const clang::Token& token)
1447
{
1448
    if (token.is(clang::tok::identifier))
1449
    {
1450
        std::string  name(token.getIdentifierInfo()->getNameStart(), token.getLength());
1451

1452
        return standardIntTypes.find(name) != standardIntTypes.end();
1453
    }
1454

1455
    return false;
1456
}
1457

1458
bool isTrueFalse(const clang::Token& token)
1459
{
1460
    if (token.is(clang::tok::identifier))
1461
    {
1462
        std::string  name(token.getIdentifierInfo()->getNameStart(), token.getLength());
1463

1464
        return name == "true" || name == "false";
1465
    }
1466

1467
    return false;
1468
}
1469

1470
kdlib::TypeInfoPtr getStandardIntType(const std::string& name)
1471
{
1472
    return standardIntTypes.at(name)();
1473
}
1474

1475
///////////////////////////////////////////////////////////////////////////////
1476

1477
bool isBinOperation(const clang::Token& token)
1478
{
1479
    return token.isOneOf(
1480
        clang::tok::plus,
1481
        clang::tok::star,
1482
        clang::tok::minus,
1483
        clang::tok::slash,
1484
        clang::tok::percent,
1485
        clang::tok::equalequal,
1486
        clang::tok::exclaimequal,
1487
        clang::tok::less,
1488
        clang::tok::lessequal,
1489
        clang::tok::greater,
1490
        clang::tok::greaterequal,
1491
        clang::tok::lessless,
1492
        clang::tok::greatergreater,
1493
        clang::tok::amp,
1494
        clang::tok::pipe,
1495
        clang::tok::caret,
1496
        clang::tok::pipepipe,
1497
        clang::tok::ampamp
1498
    );
1499
}
1500

1501
///////////////////////////////////////////////////////////////////////////////
1502

1503
bool isOperationToken(const clang::Token& token)
1504
{
1505
    return isBinOperation(token) ||
1506
        token.isOneOf(
1507
            clang::tok::exclaim,
1508
            clang::tok::plusplus,
1509
            clang::tok::minusminus,
1510
            clang::tok::tilde,
1511
            clang::tok::l_paren,
1512
            clang::tok::r_paren
1513
        );
1514
   
1515
}
1516

1517
///////////////////////////////////////////////////////////////////////////////
1518

1519
bool isInt64KeyWord(const clang::Token& token)
1520
{
1521
    if (token.is(clang::tok::identifier))
1522
    {
1523
        std::string  name(token.getIdentifierInfo()->getNameStart(), token.getLength());
1524
        return name == "__int64";
1525
    }
1526

1527
    return false;
1528
}
1529

1530

1531
///////////////////////////////////////////////////////////////////////////////
1532

1533
std::string  getIdentifier(const clang::Token& token)
1534
{
1535
    return std::string(token.getIdentifierInfo()->getNameStart(), token.getLength());
1536
}
1537

1538

1539
///////////////////////////////////////////////////////////////////////////////
1540

1541
TypedValue ExprEval2::getResult()
1542
{
1543
    using namespace parser;
1544

1545
    ConstExpressionMatcher  exprMatcher;
1546

1547
    auto matchResult = exprMatcher.match(m_tokenRange);
1548

1549
    if (!matchResult.isMatched() || matchResult.end() != m_tokenRange.second)
1550
        throw  ExprException(L"error syntax");
1551

1552
    return getResultForMatcher(exprMatcher);
1553
}
1554

1555
///////////////////////////////////////////////////////////////////////////////
1556

1557
TypedValue ExprEval2::getResultForMatcher(const parser::ConstExpressionMatcher& matcher)
1558
{
1559
    std::list< std::unique_ptr<BinOperation>> operations;
1560

1561
    std::list<TypedValue>  operands;
1562

1563
    std::transform(
1564
        matcher.getOperationMatchers().begin(),
1565
        matcher.getOperationMatchers().end(),
1566
        std::back_inserter(operations),
1567
        [](auto& operationMatcher) {
1568
            if (operationMatcher.isAdd())
1569
                return std::unique_ptr<BinOperation>(new AddExprOperation());
1570
            if (operationMatcher.isMinus())
1571
                return std::unique_ptr<BinOperation>(new SubExprOperation());
1572
            if (operationMatcher.isStar())
1573
                return std::unique_ptr<BinOperation>(new MultExprOperation());
1574
            if (operationMatcher.isSlash())
1575
                return std::unique_ptr<BinOperation>(new DivExprOperation());
1576
            if (operationMatcher.isPercent())
1577
                return std::unique_ptr<BinOperation>(new ModExprOperation());
1578
            if (operationMatcher.isGreaterGreater())
1579
                return std::unique_ptr<BinOperation>(new RightShiftOperation());
1580
            if (operationMatcher.isLessLess())
1581
                return std::unique_ptr<BinOperation>(new LeftShiftOperation());
1582
            if (operationMatcher.isAmp())
1583
                return std::unique_ptr<BinOperation>(new BitwiseAndOperation());
1584
            if (operationMatcher.isPipe())
1585
                return std::unique_ptr<BinOperation>(new BitwiseOrOperation());
1586
            if (operationMatcher.isCaret())
1587
                return std::unique_ptr<BinOperation>(new BitwiseXorOperation());
1588
            if (operationMatcher.isEqualequal())
1589
                return std::unique_ptr<BinOperation>(new EqualOperation());
1590
            if (operationMatcher.isExclaimequal())
1591
                return std::unique_ptr<BinOperation>(new NotEqualOperation());
1592
            if (operationMatcher.isLess())
1593
                return std::unique_ptr<BinOperation>(new LessOperation());
1594
            if (operationMatcher.isLessEqual())
1595
                return std::unique_ptr<BinOperation>(new LessEqualOperation());
1596
            if (operationMatcher.isGreater())
1597
                return std::unique_ptr<BinOperation>(new GreaterOperation());
1598
            if (operationMatcher.isGreaterEqual())
1599
                return std::unique_ptr<BinOperation>(new GreaterEqualOperation());
1600
            if (operationMatcher.isPipePipe())
1601
                return std::unique_ptr<BinOperation>(new BoolOrOperation());
1602
            if (operationMatcher.isAmpAmp())
1603
                return std::unique_ptr<BinOperation>(new BoolAndOperation());
1604
            throw  ExprException(L"error syntax");
1605
        } );
1606

1607
    std::transform(
1608
        matcher.getOperandMatchers().begin(),
1609
        matcher.getOperandMatchers().end(),
1610
        std::back_inserter(operands),
1611
        [](auto& operandMatcher) -> TypedValue
1612
    {
1613
        if (operandMatcher.isNumericMatcher())
1614
        {
1615
            auto val = getNumericConst(*operandMatcher.getNumericMatcher().getMatchResult().begin());
1616

1617
            std::for_each( 
1618
                operandMatcher.getUnaryOperations().begin(),
1619
                operandMatcher.getUnaryOperations().end(),
1620
                [&val](auto& unaryOperationMatcher)
1621
            {
1622
                if (unaryOperationMatcher.isPlus())
1623
                    val = UnPlusOperation().getResult(val);
1624
                else if (unaryOperationMatcher.isMinus())
1625
                    val = UnMinusOperation().getResult(val);
1626
                else if (unaryOperationMatcher.isExclaim())
1627
                    val = BooleanNotOperation().getResult(val);
1628
                else if (unaryOperationMatcher.isTilde())
1629
                    val = BitwiseNotOperation().getResult(val);
1630
                else
1631
                    throw  ExprException(L"error syntax");
1632
            });
1633

1634
            return val;
1635
        }
1636

1637
        if (operandMatcher.isNestedExpression())
1638
        {
1639
            return getResultForMatcher(operandMatcher.getNestedExpressionMatcher().getExprMatcher());
1640
        }
1641
        throw  ExprException(L"error syntax");
1642
    });
1643

1644
    while (!operations.empty())
1645
    {
1646
        auto  op = std::max_element(operations.begin(), operations.end(),
1647
            [](const auto& op1, const auto& op2)
1648
        {
1649
            return op1->getPriority() > op2->getPriority();
1650
        });
1651

1652
        auto op1 = operands.begin();
1653
        std::advance(op1, std::distance(operations.begin(), op));
1654

1655
        auto op2 = operands.begin();
1656
        std::advance(op2, std::distance(operations.begin(), op) + 1);
1657

1658
        TypedValue res;
1659
        
1660
        try 
1661
        {
1662
            res = (*op)->getResult(*op1, *op2);
1663
        }
1664
        catch (DbgException&)
1665
        {
1666
            throw  ExprException(L"error syntax");
1667
        }
1668

1669
        operations.erase(op);
1670

1671
        *op1 = res;
1672
        operands.erase(op2);
1673

1674
        continue;
1675
    }
1676

1677
    return operands.front();
1678
}
1679

1680
///////////////////////////////////////////////////////////////////////////////
1681

1682
TypedValue TypeCastOperation::getResult(const TypedValue& val)
1683
{
1684
    if (m_type->isBase())
1685
    {
1686
        return castToBase(val);
1687
    }
1688
    else if (m_type->isPointer())
1689
    {
1690
        return castToPtr(val);
1691
    }
1692
    else if (m_type->isArray())
1693
    {
1694
        throw ExprException(L"error syntax");
1695
    }
1696
    else if (m_type->isUserDefined())
1697
    {
1698
        throw ExprException(L"error syntax");
1699
    }
1700

1701
    NOT_IMPLEMENTED();
1702
}
1703

1704
///////////////////////////////////////////////////////////////////////////////
1705

1706
TypedValue TypeCastOperation::castToBase(const TypedValue& val)
1707
{
1708
    NumVariant  srcValue;
1709
    if (val.getType()->isBase())
1710
        srcValue = val.getValue();
1711
    else if (val.getType()->isPointer())
1712
        srcValue = val.getValue();
1713
    else if (val.getType()->isArray())
1714
        srcValue = val.getAddress();
1715
    else
1716
        throw ExprException(L"error syntax");
1717

1718
    if (m_type->getName() == L"Char")
1719
        return srcValue.asChar();
1720

1721
    if (m_type->getName() == L"WChar")
1722
        return srcValue.asShort();
1723

1724
    if (m_type->getName() == L"Long")
1725
        return srcValue.asLong();
1726

1727
    if (m_type->getName() == L"ULong")
1728
        return srcValue.asULong();
1729

1730
    if (m_type->getName() == L"Int1B")
1731
        return srcValue.asChar();
1732

1733
    if (m_type->getName() == L"UInt1B")
1734
        return srcValue.asUChar();
1735

1736
    if (m_type->getName() == L"Int2B")
1737
        return srcValue.asShort();
1738

1739
    if (m_type->getName() == L"UInt2B")
1740
        return srcValue.asUShort();
1741

1742
    if (m_type->getName() == L"Int4B")
1743
        return srcValue.asLong();
1744

1745
    if (m_type->getName() == L"UInt4B")
1746
        return srcValue.asULong();
1747

1748
    if (m_type->getName() == L"Int8B")
1749
        return srcValue.asLongLong();
1750

1751
    if (m_type->getName() == L"UInt8B")
1752
        return srcValue.asULongLong();
1753

1754
    if (m_type->getName() == L"Float")
1755
        return srcValue.asFloat();
1756

1757
    if (m_type->getName() == L"Double")
1758
        return srcValue.asDouble();
1759

1760
    if (m_type->getName() == L"Bool")
1761
        return srcValue.asBool();
1762

1763
    NOT_IMPLEMENTED();
1764
}
1765

1766
///////////////////////////////////////////////////////////////////////////////
1767

1768
TypedValue TypeCastOperation::castToPtr(const TypedValue& val)
1769
{
1770
    NumVariant  srcValue;
1771
    if (val.getType()->isBase())
1772
    {
1773
        return TypedValue(val.getValue().asULongLong()).castTo(m_type);
1774
    }
1775

1776
    if (val.getType()->isPointer())
1777
    {
1778
        return val.castTo(m_type);
1779
    }
1780

1781
    if (val.getType()->isArray())
1782
    {
1783
        return TypedValue(val.getAddress()).castTo(m_type);
1784
    }
1785

1786
    NOT_IMPLEMENTED();
1787
}
1788

1789
///////////////////////////////////////////////////////////////////////////////
1790

1791
TypedValue AddExprOperation::getResult(const TypedValue& val1, const TypedValue& val2)
1792
{
1793
    if (val1.getType()->isBase() && val2.getType()->isBase())
1794
        return val1 + val2;
1795

1796
    if (val1.getType()->isPointer() || val1.getType()->isArray())
1797
    {
1798
        if (val2.getType()->isBase())
1799
            return TypedValue(val1 + val1.getType()->deref()->getSize() * val2).castTo(val1.getType()->deref()->ptrTo());
1800
        throw ExprException(L"error syntax");
1801
    }
1802

1803
    if (val2.getType()->isPointer() || val2.getType()->isArray())
1804
    {
1805
        if (val1.getType()->isBase())
1806
            return TypedValue(val2 + val2.getType()->deref()->getSize() * val1).castTo(val2.getType()->deref()->ptrTo());
1807
        throw ExprException(L"error syntax");
1808
    }
1809

1810
    throw ExprException(L"error syntax");
1811
}
1812

1813
///////////////////////////////////////////////////////////////////////////////
1814

1815
TypedValue SubExprOperation::getResult(const TypedValue& val1, const TypedValue& val2)
1816
{
1817
    if (val1.getType()->isBase() && val2.getType()->isBase())
1818
        return val1 - val2;
1819

1820
    if (val1.getType()->isPointer() || val1.getType()->isArray())
1821
    {
1822
        if (val2.getType()->isBase())
1823
            return TypedValue(val1 - val1.getType()->deref()->getSize() * val2).castTo(val1.getType()->deref()->ptrTo());
1824

1825
        if (val2.getType()->isPointer() || val2.getType()->isArray())
1826
            return (val1 - val2) / (val1.getType()->deref()->getSize());
1827

1828
        throw ExprException(L"error syntax");
1829
    }
1830

1831
    throw ExprException(L"error syntax");
1832

1833
}
1834

1835
///////////////////////////////////////////////////////////////////////////////
1836

1837
TypedValue MultExprOperation::getResult(const TypedValue& val1, const TypedValue& val2) 
1838
{
1839
    if (val1.getType()->isBase() && val2.getType()->isBase())
1840
        return val1 * val2;
1841

1842
    throw ExprException(L"error syntax");
1843
}
1844

1845
///////////////////////////////////////////////////////////////////////////////
1846

1847
TypedValue DivExprOperation::getResult(const TypedValue& val1, const TypedValue& val2)
1848
{
1849
    if (val2 == 0 )
1850
        throw DbgException("expression division error");
1851

1852
    if (val1.getType()->isBase() && val2.getType()->isBase())
1853
        return val1 / val2;
1854

1855
    throw ExprException(L"error syntax");
1856
}
1857

1858
///////////////////////////////////////////////////////////////////////////////
1859

1860
TypedValue ModExprOperation::getResult(const TypedValue& val1, const TypedValue& val2)
1861
{
1862
    if (val1.getType()->isBase() && val2.getType()->isBase())
1863
        return val1 % val2;
1864

1865
    throw ExprException(L"error syntax");
1866
}
1867

1868
///////////////////////////////////////////////////////////////////////////////
1869

1870
TypedValue LeftShiftOperation::getResult(const TypedValue& val1, const TypedValue& val2)
1871
{
1872
    if (val1.getType()->isBase() && val2.getType()->isBase())
1873
        return val1 << val2;
1874

1875
    throw ExprException(L"error syntax");
1876
}
1877

1878

1879
///////////////////////////////////////////////////////////////////////////////
1880

1881
TypedValue RightShiftOperation::getResult(const TypedValue& val1, const TypedValue& val2)
1882
{
1883
    if (val1.getType()->isBase() && val2.getType()->isBase())
1884
        return val1 >> val2;
1885

1886
    throw ExprException(L"error syntax");
1887
}
1888

1889
///////////////////////////////////////////////////////////////////////////////
1890

1891
TypedValue BitwiseOrOperation::getResult(const TypedValue& val1, const TypedValue& val2)
1892
{
1893
    if (val1.getType()->isBase() && val2.getType()->isBase())
1894
        return val1 | val2;
1895

1896
    throw ExprException(L"error syntax");
1897
}
1898

1899
///////////////////////////////////////////////////////////////////////////////
1900

1901
TypedValue BitwiseAndOperation::getResult(const TypedValue& val1, const TypedValue& val2)
1902
{
1903
    if (val1.getType()->isBase() && val2.getType()->isBase())
1904
        return val1 & val2;
1905

1906
    throw ExprException(L"error syntax");
1907
}
1908

1909
///////////////////////////////////////////////////////////////////////////////
1910

1911
TypedValue BitwiseXorOperation::getResult(const TypedValue& val1, const TypedValue& val2)
1912
{
1913
    if (val1.getType()->isBase() && val2.getType()->isBase())
1914
        return val1 ^ val2;
1915

1916
    throw ExprException(L"error syntax");
1917
}
1918

1919
///////////////////////////////////////////////////////////////////////////////
1920

1921
TypedValue UnMinusOperation::getResult(const TypedValue& val)
1922
{
1923
    if (val.getType()->isBase())
1924
        return -val;
1925

1926
    throw ExprException(L"error syntax");
1927
}
1928

1929
///////////////////////////////////////////////////////////////////////////////
1930

1931
TypedValue BitwiseNotOperation::getResult(const TypedValue& val)
1932
{
1933
    if (val.getType()->isBase())
1934
        return ~val;
1935

1936
    throw ExprException(L"error syntax");
1937
}
1938

1939
///////////////////////////////////////////////////////////////////////////////
1940

1941
TypedValue BooleanNotOperation::getResult(const TypedValue& val)
1942
{
1943
    if (val.getType()->isBase())
1944
        return !val.getValue();
1945

1946
    throw ExprException(L"error syntax");
1947
}
1948

1949
///////////////////////////////////////////////////////////////////////////////
1950

1951
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.