Skip to content

Commit 357bda5

Browse files
committed
✨ Speedy #embed implementation
1 parent 32c8097 commit 357bda5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+6400
-5766
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4805,6 +4805,58 @@ class SourceLocExpr final : public Expr {
48054805
friend class ASTStmtReader;
48064806
};
48074807

4808+
/// Represents a function call to __builtin_pp_embed().
4809+
class PPEmbedExpr final : public Expr {
4810+
SourceLocation BuiltinLoc, RParenLoc;
4811+
DeclContext *ParentContext;
4812+
StringLiteral *Filename;
4813+
StringLiteral *BinaryData;
4814+
4815+
public:
4816+
enum Action {
4817+
NotFound,
4818+
FoundOne,
4819+
Expanded,
4820+
};
4821+
4822+
PPEmbedExpr(const ASTContext &Ctx, QualType ResultTy, StringLiteral* Filename, StringLiteral* BinaryData,
4823+
SourceLocation BLoc, SourceLocation RParenLoc,
4824+
DeclContext *Context);
4825+
4826+
/// Build an empty call expression.
4827+
explicit PPEmbedExpr(EmptyShell Empty)
4828+
: Expr(SourceLocExprClass, Empty) {}
4829+
4830+
/// If the PPEmbedExpr has been resolved return the subexpression
4831+
/// representing the resolved value. Otherwise return null.
4832+
const DeclContext *getParentContext() const { return ParentContext; }
4833+
DeclContext *getParentContext() { return ParentContext; }
4834+
4835+
SourceLocation getLocation() const { return BuiltinLoc; }
4836+
SourceLocation getBeginLoc() const { return BuiltinLoc; }
4837+
SourceLocation getEndLoc() const { return RParenLoc; }
4838+
4839+
StringLiteral *getFilenameStringLiteral() const { return Filename; }
4840+
StringLiteral *getDataStringLiteral() const { return BinaryData; }
4841+
4842+
size_t getDataElementCount(ASTContext &Context) const;
4843+
4844+
child_range children() {
4845+
return child_range(child_iterator(), child_iterator());
4846+
}
4847+
4848+
const_child_range children() const {
4849+
return const_child_range(child_iterator(), child_iterator());
4850+
}
4851+
4852+
static bool classof(const Stmt *T) {
4853+
return T->getStmtClass() == PPEmbedExprClass;
4854+
}
4855+
4856+
private:
4857+
friend class ASTStmtReader;
4858+
};
4859+
48084860
/// Describes an C or C++ initializer list.
48094861
///
48104862
/// InitListExpr describes an initializer list, which can be used to

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,6 +2809,7 @@ DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
28092809
DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
28102810
DEF_TRAVERSE_STMT(StmtExpr, {})
28112811
DEF_TRAVERSE_STMT(SourceLocExpr, {})
2812+
DEF_TRAVERSE_STMT(PPEmbedExpr, {})
28122813

28132814
DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
28142815
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));

clang/include/clang/Basic/DiagnosticCommonKinds.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ def err_expected_string_literal : Error<"expected string literal "
5959
"'external_source_symbol' attribute|"
6060
"as argument of '%1' attribute}0">;
6161

62+
def err_builtin_pp_embed_invalid_argument : Error<
63+
"invalid argument to '__builtin_pp_embed': %0">;
64+
6265
def err_invalid_string_udl : Error<
6366
"string literal with user-defined suffix cannot be used here">;
6467
def err_invalid_character_udl : Error<
@@ -80,6 +83,9 @@ def err_expected : Error<"expected %0">;
8083
def err_expected_either : Error<"expected %0 or %1">;
8184
def err_expected_after : Error<"expected %1 after %0">;
8285

86+
def err_builtin_pp_embed_invalid_location : Error<
87+
"'__builtin_pp_embed' in invalid location: %0%select{|%2}1">;
88+
8389
def err_param_redefinition : Error<"redefinition of parameter %0">;
8490
def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">;
8591
def warn_method_param_declaration : Warning<"redeclaration of method parameter %0">,

clang/include/clang/Basic/StmtNodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ def OpaqueValueExpr : StmtNode<Expr>;
203203
def TypoExpr : StmtNode<Expr>;
204204
def RecoveryExpr : StmtNode<Expr>;
205205
def BuiltinBitCastExpr : StmtNode<ExplicitCastExpr>;
206+
def PPEmbedExpr : StmtNode<Expr>;
206207

207208
// Microsoft Extensions.
208209
def MSPropertyRefExpr : StmtNode<Expr>;

clang/include/clang/Basic/TokenKinds.def

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,6 @@ TOK(eod) // End of preprocessing directive (end of line inside a
154154
// directive).
155155
TOK(code_completion) // Code completion marker
156156

157-
// #embed speed support
158-
TOK(builtin_embed)
159-
160-
161157
// C99 6.4.9: Comments.
162158
TOK(comment) // Comment (only in -E -C[C] mode)
163159

@@ -758,6 +754,7 @@ ALIAS("__char32_t" , char32_t , KEYCXX)
758754
KEYWORD(__builtin_bit_cast , KEYALL)
759755
KEYWORD(__builtin_available , KEYALL)
760756
KEYWORD(__builtin_sycl_unique_stable_name, KEYSYCL)
757+
KEYWORD(__builtin_pp_embed , KEYALL)
761758

762759
// Keywords defined by Attr.td.
763760
#ifndef KEYWORD_ATTRIBUTE
@@ -993,6 +990,7 @@ ANNOTATION(repl_input_end)
993990
#undef CXX11_KEYWORD
994991
#undef KEYWORD
995992
#undef PUNCTUATOR
993+
#undef BUILTINOK
996994
#undef TOK
997995
#undef C99_KEYWORD
998996
#undef C23_KEYWORD
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===--- MacroArgs.h - Formal argument info for Macros ----------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the MacroArgs interface.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_LEX_PPDIRECTIVEPARAMETER_H
14+
#define LLVM_CLANG_LEX_PPDIRECTIVEPARAMETER_H
15+
16+
#include "clang/Basic/SourceLocation.h"
17+
18+
namespace clang {
19+
20+
/// Captures basic information about a preprocessor directive parameter.
21+
class PPDirectiveParameter {
22+
public:
23+
SourceLocation Start;
24+
SourceLocation End;
25+
26+
PPDirectiveParameter(SourceLocation Start, SourceLocation End)
27+
: Start(Start), End(End) {}
28+
};
29+
30+
} // end namespace clang
31+
32+
#endif
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//===--- MacroArgs.h - Formal argument info for Macros ----------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the MacroArgs interface.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_LEX_PPEMBEDPARAMETERS_H
14+
#define LLVM_CLANG_LEX_PPEMBEDPARAMETERS_H
15+
16+
#include "clang/Lex/Token.h"
17+
#include "clang/Lex/PPDirectiveParameter.h"
18+
#include "llvm/ADT/SmallVector.h"
19+
20+
namespace clang {
21+
22+
/// Preprocessor extension embed parameter "clang::offset"
23+
/// `clang::offset( constant-expression )`
24+
class PPEmbedParameterOffset : public PPDirectiveParameter {
25+
public:
26+
size_t Offset;
27+
28+
PPEmbedParameterOffset(size_t Offset, SourceLocation Start, SourceLocation End)
29+
: Offset(Offset), PPDirectiveParameter(Start, End) {}
30+
};
31+
32+
/// Preprocessor standard embed parameter "limit"
33+
/// `limit( constant-expression )`
34+
class PPEmbedParameterLimit : public PPDirectiveParameter {
35+
public:
36+
size_t Limit;
37+
38+
PPEmbedParameterLimit(size_t Limit, SourceLocation Start,
39+
SourceLocation End)
40+
: Limit(Limit), PPDirectiveParameter(Start, End) {}
41+
};
42+
43+
/// Preprocessor standard embed parameter "prefix"
44+
/// `prefix( balanced-token-seq )`
45+
class PPEmbedParameterPrefix : public PPDirectiveParameter {
46+
public:
47+
SmallVector<Token, 2> Tokens;
48+
49+
PPEmbedParameterPrefix(SmallVector<Token, 2> Tokens, SourceLocation Start,
50+
SourceLocation End)
51+
: Tokens(std::move(Tokens)), PPDirectiveParameter(Start, End) {}
52+
};
53+
54+
/// Preprocessor standard embed parameter "suffix"
55+
/// `suffix( balanced-token-seq )`
56+
class PPEmbedParameterSuffix : public PPDirectiveParameter {
57+
public:
58+
SmallVector<Token, 2> Tokens;
59+
60+
PPEmbedParameterSuffix(SmallVector<Token, 2> Tokens, SourceLocation Start,
61+
SourceLocation End)
62+
: Tokens(std::move(Tokens)), PPDirectiveParameter(Start, End) {}
63+
};
64+
65+
/// Preprocessor standard embed parameter "if_empty"
66+
/// `if_empty( balanced-token-seq )`
67+
class PPEmbedParameterIfEmpty : public PPDirectiveParameter {
68+
public:
69+
SmallVector<Token, 2> Tokens;
70+
71+
PPEmbedParameterIfEmpty(SmallVector<Token, 2> Tokens, SourceLocation Start,
72+
SourceLocation End)
73+
: Tokens(std::move(Tokens)), PPDirectiveParameter(Start, End) {}
74+
};
75+
76+
} // end namespace clang
77+
78+
#endif

clang/include/clang/Lex/Preprocessor.h

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "clang/Lex/ModuleLoader.h"
3030
#include "clang/Lex/ModuleMap.h"
3131
#include "clang/Lex/PPCallbacks.h"
32+
#include "clang/Lex/PPEmbedParameters.h"
3233
#include "clang/Lex/Token.h"
3334
#include "clang/Lex/TokenLexer.h"
3435
#include "llvm/ADT/APSInt.h"
@@ -1163,6 +1164,9 @@ class Preprocessor {
11631164

11641165
void updateOutOfDateIdentifier(IdentifierInfo &II) const;
11651166

1167+
/// Buffers for used #embed directives
1168+
std::vector<std::string> EmbedBuffers;
1169+
11661170
public:
11671171
Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
11681172
DiagnosticsEngine &diags, const LangOptions &LangOpts,
@@ -1730,15 +1734,15 @@ class Preprocessor {
17301734
bool LexHeaderName(Token &Result, bool AllowMacroExpansion = true);
17311735

17321736
struct LexEmbedParametersResult {
1733-
bool Successful;
1734-
std::optional<size_t> MaybeLimitParam;
1735-
std::optional<size_t> MaybeOffsetParam;
1736-
std::optional<SmallVector<Token, 2>> MaybeIfEmptyParam;
1737-
std::optional<SmallVector<Token, 2>> MaybePrefixParam;
1738-
std::optional<SmallVector<Token, 2>> MaybeSuffixParam;
1739-
int UnrecognizedParams;
1737+
std::optional<PPEmbedParameterLimit> MaybeLimitParam;
1738+
std::optional<PPEmbedParameterOffset> MaybeOffsetParam;
1739+
std::optional<PPEmbedParameterIfEmpty> MaybeIfEmptyParam;
1740+
std::optional<PPEmbedParameterPrefix> MaybePrefixParam;
1741+
std::optional<PPEmbedParameterSuffix> MaybeSuffixParam;
17401742
SourceLocation StartLoc;
17411743
SourceLocation EndLoc;
1744+
int UnrecognizedParams;
1745+
bool Successful;
17421746
};
17431747

17441748
LexEmbedParametersResult LexEmbedParameters(Token &Current,
@@ -1807,7 +1811,7 @@ class Preprocessor {
18071811
/// Parses a simple integer literal to get its numeric value. Floating
18081812
/// point literals and user defined literals are rejected. Used primarily to
18091813
/// handle pragmas that accept integer arguments.
1810-
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value);
1814+
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value, bool WithLex = true);
18111815

18121816
/// Disables macro expansion everywhere except for preprocessor directives.
18131817
void SetMacroExpansionOnlyInDirectives() {
@@ -2431,8 +2435,7 @@ class Preprocessor {
24312435
/// reference is for system \#include's or not (i.e. using <> instead of "").
24322436
OptionalFileEntryRef
24332437
LookupEmbedFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled,
2434-
bool OpenFile,
2435-
const FileEntry *LookupFromFile = nullptr,
2438+
bool OpenFile, const FileEntry *LookupFromFile = nullptr,
24362439
SmallVectorImpl<char> *SearchPath = nullptr,
24372440
SmallVectorImpl<char> *RelativePath = nullptr);
24382441

@@ -2724,12 +2727,18 @@ class Preprocessor {
27242727
// Binary data inclusion
27252728
void HandleEmbedDirective(SourceLocation HashLoc, Token &Tok,
27262729
const FileEntry *LookupFromFile = nullptr);
2727-
void HandleEmbedDirectiveNaive(
2728-
SourceLocation FilenameTok, LexEmbedParametersResult &Params,
2729-
StringRef BinaryContents, const size_t TargetCharWidth);
2730-
void HandleEmbedDirectiveBuiltin(
2731-
SourceLocation FilenameTok, LexEmbedParametersResult &Params,
2732-
StringRef BinaryContents, const size_t TargetCharWidth);
2730+
void HandleEmbedDirectiveNaive(SourceLocation HashLoc,
2731+
SourceLocation FilenameTok,
2732+
LexEmbedParametersResult &Params,
2733+
StringRef BinaryContents,
2734+
const size_t TargetCharWidth);
2735+
void HandleEmbedDirectiveBuiltin(SourceLocation HashLoc,
2736+
const Token &FilenameTok,
2737+
StringRef ResolvedFilename,
2738+
StringRef SearchPath, StringRef RelativePath,
2739+
LexEmbedParametersResult &Params,
2740+
StringRef BinaryContents,
2741+
const size_t TargetCharWidth);
27332742

27342743
// File inclusion.
27352744
void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok,

clang/include/clang/Lex/Token.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ class Token {
254254
Flags &= ~Flag;
255255
}
256256

257-
/// Return the internal represtation of the flags.
257+
/// Return the internal representation of the flags.
258258
///
259259
/// This is only intended for low-level operations such as writing tokens to
260260
/// disk.

0 commit comments

Comments
 (0)