1/****************************************************************************
2 * Copyright (C) 2013-2016 Woboq GmbH
3 * Olivier Goffart <contact at woboq.com>
4 * https://woboq.com/
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <clang/Lex/Token.h>
23#include <clang/Lex/Preprocessor.h>
24#include <clang/Lex/Lexer.h>
25#include <clang/Sema/Sema.h>
26#include "mocng.h"
27
28
29class PropertyParser {
30 clang::Sema &Sema;
31 clang::Preprocessor &PP;
32
33 llvm::MemoryBuffer *Buf;
34 clang::Lexer Lexer;
35 clang::Token PrevToken;
36 clang::Token CurrentTok;
37
38
39
40 clang::SourceLocation BaseLoc;
41
42 clang::CXXRecordDecl *RD;
43
44 bool IsEnum = false;
45 bool IsPossiblyForwardDeclared = false;
46
47public:
48
49 clang::CXXRecordDecl *Extra = nullptr;
50
51 PropertyParser(llvm::StringRef Text, clang::SourceLocation Loc, clang::Sema &Sema,
52 clang::CXXRecordDecl *RD) :
53 Sema(Sema), PP(Sema.getPreprocessor()),
54 Buf(maybe_unique(llvm::MemoryBuffer::getMemBufferCopy(Text/*, "Q_PROPERTY"*/))),
55// Lexer(PP.getSourceManager().getSpellingLoc(Loc), PP.getLangOpts(), Text.begin(), Text.begin(), Text.end()),
56 Lexer(CreateFileIDForMemBuffer(PP, Buf, Loc),
57 Buf, PP.getSourceManager(), PP.getLangOpts()),
58 BaseLoc(Loc), RD(RD)
59 { }
60
61private:
62 clang::SourceLocation OriginalLocation(clang::SourceLocation SpellingLoc = clang::SourceLocation()) {
63 if (SpellingLoc.isInvalid())
64 SpellingLoc = PrevToken.getLocation();
65 return BaseLoc.getLocWithOffset(PP.getSourceManager().getFileOffset(SpellingLoc));
66 }
67
68 void Consume() {
69 PrevToken = CurrentTok;
70 Lexer.LexFromRawLexer(CurrentTok);
71 if (CurrentTok.is(clang::tok::raw_identifier)) {
72 PP.LookUpIdentifierInfo(CurrentTok);
73 }
74 }
75
76 std::string Spelling() {
77 return PP.getSpelling(PrevToken);
78 }
79
80 bool Test(clang::tok::TokenKind Kind) {
81 if (!CurrentTok.is(Kind))
82 return false;
83 Consume();
84 return true;
85 }
86
87
88 bool IsIdentChar(char c) {
89 return (c=='_' || c=='$' || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
90 }
91
92 std::string LexemUntil(clang::tok::TokenKind Until, bool Templ = false);
93public:
94 std::string parseUnsigned();
95 std::string parseTemplateType();
96 std::string parseType(bool SupressDiagnostics = true);
97 PropertyDef parseProperty(bool PrivateProperty = false);
98 PrivateSlotDef parsePrivateSlot();
99};
100
101