update Directive.

This commit is contained in:
ykiko
2024-08-14 21:44:05 +08:00
parent 939394927c
commit a94b33d012
8 changed files with 318 additions and 107 deletions

View File

@@ -8,6 +8,7 @@
#include <clang/Sema/Sema.h>
#include <clang/Tooling/CompilationDatabase.h>
#include <clang/Tooling/Syntax/Tokens.h>
#include <clang/Lex/PPCallbacks.h>
namespace clice {
@@ -16,4 +17,9 @@ using PathRef = StringRef;
using clang::CompilerInstance;
using clang::CompilerInvocation;
using clang::SourceLocation;
using clang::SourceRange;
using clang::PPCallbacks;
using clang::Token;
} // namespace clice

View File

@@ -2,26 +2,141 @@
namespace clice {
struct MacroDefinition {
std::string name;
std::string definition;
clang::SourceRange range;
};
struct MacroExpansion {
std::string name;
std::string expansion;
};
// note that `#` is not part of the directive token. it is a separate token.
class Directive {
friend class DirectiveCollector;
private:
std::string name;
clang::SourceRange range;
std::vector<MacroDefinition> definitions;
std::vector<MacroExpansion> expansions;
/// represent a `#include` directive.
struct Header {
SourceLocation hashLoc;
Token includeTok;
StringRef fileName;
bool isAngled;
clang::CharSourceRange filenameRange;
clang::OptionalFileEntryRef file;
StringRef searchPath;
StringRef relativePath;
const clang::Module* suggestedModule;
bool moduleImported;
clang::SrcMgr::CharacteristicKind fileType;
};
/// represent a `#define` directive.
struct Define {
Token name;
const clang::MacroDirective* directive;
};
/// represent a `#undef` directive.
struct Undef {
Token name;
const clang::MacroDefinition* definition;
const clang::MacroDirective* directive;
};
/// represent a `#pragma` directive.
struct Pragma {
/// the location of `pragma` directive.
SourceLocation location;
/// the kind of the pragma directive.
clang::PragmaIntroducerKind kind;
};
/// represent a condition in `#if` or `#elif` directive.
struct Condition {
/// the source range of the condition.
SourceRange range;
/// the evaluated value of the condition.
PPCallbacks::ConditionValueKind value;
};
/// represent a `#if` directive
struct If {
/// the location of `if` directive.
SourceLocation location;
Condition condition;
};
/// represent a `#elif` directive
struct Elif {
/// the location of `elif` directive.
SourceLocation location;
Condition condition;
};
/// represent a macro condition in `#ifdef` or `#elifdef` directive.
struct MacroCondition {
/// the source range of the macro name.
Token token;
/// the corresponding macro definition(may be null).
clang::MacroDefinition definition;
};
/// represent a `#ifdef` directive
struct Ifdef {
/// the location of `ifdef` directive.
SourceLocation location;
MacroCondition condition;
};
/// represent a `#elifdef` directive
struct Elifdef {
/// the location of `elifdef` directive.
SourceLocation location;
MacroCondition condition;
};
struct Else {
/// the location of `else` directive.
SourceLocation location;
};
struct Endif {
/// the location of `endif` directive.
SourceLocation location;
};
struct IfBlock {
If if_;
std::vector<Elif> elifs;
std::optional<Else> else_;
Endif endif;
};
struct IfdefBlock {
Ifdef ifdef;
std::vector<Elifdef> elifdefs;
std::optional<Else> else_;
Endif endif;
};
private:
std::vector<Header> headers;
std::vector<Define> defines;
std::vector<Undef> undefs;
std::vector<Pragma> pragmas;
std::vector<IfBlock> ifBlocks;
std::vector<IfdefBlock> ifdefBlocks;
public:
static std::unique_ptr<Directive> create(clang::SourceManager& sourceManager, clang::SourceRange range);
Directive(clang::Preprocessor& pp);
auto& Headers() { return headers; }
auto& Defines() { return defines; }
auto& Undefs() { return undefs; }
auto& Pragmas() { return pragmas; }
auto& IfBlocks() { return ifBlocks; }
auto& IfdefBlocks() { return ifdefBlocks; }
};
#if 1111
#endif
} // namespace clice

View File

@@ -10,8 +10,6 @@ namespace feature {
protocol::SemanticTokens semanticTokens(const ParsedAST& ast);
}
} // namespace clice