Files
clice/include/Compiler/Directive.h
2025-06-10 22:33:17 +08:00

144 lines
3.2 KiB
C++

#pragma once
#include "AST/SourceLocation.h"
#include "clang/Lex/MacroInfo.h"
#include "llvm/ADT/DenseMap.h"
namespace clice {
/// Information about `#include` directive.
struct Include {
/// whether this header is skipped because of #pragma once
/// or a header guard macro.
bool skipped;
/// The file id of included file.
clang::FileID fid;
/// Location of the `include`.
clang::SourceLocation location;
/// The range of filename(includes `""` or `<>`).
clang::SourceRange fileNameRange;
};
/// Information about `__has_include` directive.
struct HasInclude {
/// The file id of included file, may be empty if there is
/// not such file.
clang::FileID fid;
/// Location of the filename token start.
clang::SourceLocation location;
};
/// Information about `#if`, `#ifdef`, `#ifndef`, `#elif`,
/// `#elifdef`, `#else`, `#endif` directive.
struct Condition {
enum class BranchKind : uint8_t {
If = 0,
Elif,
Ifdef,
Elifdef,
Ifndef,
Elifndef,
Else,
EndIf,
};
using enum BranchKind;
enum class ConditionValue : uint8_t {
True = 0,
False,
Skipped,
None,
};
using enum ConditionValue;
/// Kind of the branch.
BranchKind kind;
/// Value of the condition.
ConditionValue value;
/// Location of the directive identifier.
clang::SourceLocation loc;
/// Range of the condition.
clang::SourceRange conditionRange;
};
/// Information about macro definition, reference and undef.
struct MacroRef {
enum class Kind : uint8_t {
Def = 0,
Ref,
Undef,
};
using enum Kind;
/// The macro definition information.
const clang::MacroInfo* macro;
/// Kind of the macro reference.
Kind kind;
/// The location of the macro name.
clang::SourceLocation loc;
};
/// Information about `#pragma` directive.
struct Pragma {
enum class Kind : uint8_t {
Region,
EndRegion,
// Other unused cases in clice, For example: `#pragma once`.
Other,
};
using enum Kind;
/// The pragma text in that line, for example:
/// "#pragma region"
/// "#pragma once"
/// "#pragma GCC error"
llvm::StringRef stmt;
/// Kind of the pragma.
Kind kind;
/// Location of the `#` token.
clang::SourceLocation loc;
};
struct Import {
/// The name of imported module.
std::string name;
/// The location of import keyword, may comes from macro expansion.
clang::SourceLocation location;
/// The locations of tokens that make up the token name, may comes
/// from macro expansion.
std::vector<clang::SourceLocation> name_locations;
};
struct Directive {
std::vector<Include> includes;
std::vector<HasInclude> hasIncludes;
std::vector<Condition> conditions;
std::vector<MacroRef> macros;
std::vector<Pragma> pragmas;
std::vector<Import> imports;
/// Tell preprocessor to collect directives information and store them in `directives`.
static void attach(clang::Preprocessor& pp,
llvm::DenseMap<clang::FileID, Directive>& directives);
};
} // namespace clice