Skip to content

Commit 6a7a4c9

Browse files
ThePhDh-vetinari
authored andcommitted
✨ Speedy #embed implementation
⚡ [Lex] Better reservations for improved performance/memory usage. 🛠 [Lex, Frontend] Remove comma hardcoding since we are servicing a full file apply suggestions from git-clang-format
1 parent 7050c93 commit 6a7a4c9

Some content is hidden

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

45 files changed

+1351
-172
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4805,6 +4805,57 @@ 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,
4823+
StringLiteral *BinaryData, SourceLocation BLoc,
4824+
SourceLocation RParenLoc, DeclContext *Context);
4825+
4826+
/// Build an empty call expression.
4827+
explicit PPEmbedExpr(EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {}
4828+
4829+
/// If the PPEmbedExpr has been resolved return the subexpression
4830+
/// representing the resolved value. Otherwise return null.
4831+
const DeclContext *getParentContext() const { return ParentContext; }
4832+
DeclContext *getParentContext() { return ParentContext; }
4833+
4834+
SourceLocation getLocation() const { return BuiltinLoc; }
4835+
SourceLocation getBeginLoc() const { return BuiltinLoc; }
4836+
SourceLocation getEndLoc() const { return RParenLoc; }
4837+
4838+
StringLiteral *getFilenameStringLiteral() const { return Filename; }
4839+
StringLiteral *getDataStringLiteral() const { return BinaryData; }
4840+
4841+
size_t getDataElementCount(ASTContext &Context) const;
4842+
4843+
child_range children() {
4844+
return child_range(child_iterator(), child_iterator());
4845+
}
4846+
4847+
const_child_range children() const {
4848+
return const_child_range(child_iterator(), child_iterator());
4849+
}
4850+
4851+
static bool classof(const Stmt *T) {
4852+
return T->getStmtClass() == PPEmbedExprClass;
4853+
}
4854+
4855+
private:
4856+
friend class ASTStmtReader;
4857+
};
4858+
48084859
/// Describes an C or C++ initializer list.
48094860
///
48104861
/// 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/FileManager.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,9 @@ class FileManager : public RefCountedBase<FileManager> {
282282
getBufferForFile(StringRef Filename, bool isVolatile = false,
283283
bool RequiresNullTerminator = true,
284284
std::optional<int64_t> MaybeLimit = std::nullopt) {
285-
return getBufferForFileImpl(Filename, /*FileSize=*/(MaybeLimit ? *MaybeLimit : -1), isVolatile,
286-
RequiresNullTerminator);
285+
return getBufferForFileImpl(Filename,
286+
/*FileSize=*/(MaybeLimit ? *MaybeLimit : -1),
287+
isVolatile, RequiresNullTerminator);
287288
}
288289

289290
private:

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

clang/include/clang/Frontend/PreprocessorOutputOptions.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ class PreprocessorOutputOptions {
2222
unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
2323
unsigned ShowMacros : 1; ///< Print macro definitions.
2424
unsigned ShowIncludeDirectives : 1; ///< Print includes, imports etc. within preprocessed output.
25-
unsigned ShowEmbedDirectives : 1; ///< Print embeds, etc. within preprocessed output.
25+
unsigned ShowEmbedDirectives : 1; ///< Print embeds, etc. within preprocessed
26+
///< output.
2627
unsigned RewriteIncludes : 1; ///< Preprocess include directives only.
2728
unsigned RewriteImports : 1; ///< Include contents of transitively-imported modules.
2829
unsigned MinimizeWhitespace : 1; ///< Ignore whitespace from input.
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/PPDirectiveParameter.h"
17+
#include "clang/Lex/Token.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,
29+
SourceLocation End)
30+
: Offset(Offset), PPDirectiveParameter(Start, End) {}
31+
};
32+
33+
/// Preprocessor standard embed parameter "limit"
34+
/// `limit( constant-expression )`
35+
class PPEmbedParameterLimit : public PPDirectiveParameter {
36+
public:
37+
size_t Limit;
38+
39+
PPEmbedParameterLimit(size_t Limit, SourceLocation Start, 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: 26 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"
@@ -1165,6 +1166,9 @@ class Preprocessor {
11651166

11661167
void updateOutOfDateIdentifier(IdentifierInfo &II) const;
11671168

1169+
/// Buffers for used #embed directives
1170+
std::vector<std::string> EmbedBuffers;
1171+
11681172
public:
11691173
Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
11701174
DiagnosticsEngine &diags, const LangOptions &LangOpts,
@@ -1735,15 +1739,15 @@ class Preprocessor {
17351739
bool LexHeaderName(Token &Result, bool AllowMacroExpansion = true);
17361740

17371741
struct LexEmbedParametersResult {
1738-
bool Successful;
1739-
std::optional<size_t> MaybeLimitParam;
1740-
std::optional<size_t> MaybeOffsetParam;
1741-
std::optional<SmallVector<Token, 2>> MaybeIfEmptyParam;
1742-
std::optional<SmallVector<Token, 2>> MaybePrefixParam;
1743-
std::optional<SmallVector<Token, 2>> MaybeSuffixParam;
1744-
int UnrecognizedParams;
1742+
std::optional<PPEmbedParameterLimit> MaybeLimitParam;
1743+
std::optional<PPEmbedParameterOffset> MaybeOffsetParam;
1744+
std::optional<PPEmbedParameterIfEmpty> MaybeIfEmptyParam;
1745+
std::optional<PPEmbedParameterPrefix> MaybePrefixParam;
1746+
std::optional<PPEmbedParameterSuffix> MaybeSuffixParam;
17451747
SourceLocation StartLoc;
17461748
SourceLocation EndLoc;
1749+
int UnrecognizedParams;
1750+
bool Successful;
17471751
};
17481752

17491753
LexEmbedParametersResult LexEmbedParameters(Token &Current,
@@ -1812,7 +1816,8 @@ class Preprocessor {
18121816
/// Parses a simple integer literal to get its numeric value. Floating
18131817
/// point literals and user defined literals are rejected. Used primarily to
18141818
/// handle pragmas that accept integer arguments.
1815-
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value);
1819+
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value,
1820+
bool WithLex = true);
18161821

18171822
/// Disables macro expansion everywhere except for preprocessor directives.
18181823
void SetMacroExpansionOnlyInDirectives() {
@@ -2441,8 +2446,7 @@ class Preprocessor {
24412446
/// reference is for system \#include's or not (i.e. using <> instead of "").
24422447
OptionalFileEntryRef
24432448
LookupEmbedFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled,
2444-
bool OpenFile,
2445-
const FileEntry *LookupFromFile = nullptr,
2449+
bool OpenFile, const FileEntry *LookupFromFile = nullptr,
24462450
SmallVectorImpl<char> *SearchPath = nullptr,
24472451
SmallVectorImpl<char> *RelativePath = nullptr);
24482452

@@ -2735,12 +2739,18 @@ class Preprocessor {
27352739
// Binary data inclusion
27362740
void HandleEmbedDirective(SourceLocation HashLoc, Token &Tok,
27372741
const FileEntry *LookupFromFile = nullptr);
2738-
void HandleEmbedDirectiveNaive(
2739-
SourceLocation FilenameTok, LexEmbedParametersResult &Params,
2740-
StringRef BinaryContents, const size_t TargetCharWidth);
2741-
void HandleEmbedDirectiveBuiltin(
2742-
SourceLocation FilenameTok, LexEmbedParametersResult &Params,
2743-
StringRef BinaryContents, const size_t TargetCharWidth);
2742+
void HandleEmbedDirectiveNaive(SourceLocation HashLoc,
2743+
SourceLocation FilenameTok,
2744+
const LexEmbedParametersResult &Params,
2745+
StringRef BinaryContents,
2746+
const size_t TargetCharWidth);
2747+
void HandleEmbedDirectiveBuiltin(SourceLocation HashLoc,
2748+
const Token &FilenameTok,
2749+
StringRef ResolvedFilename,
2750+
StringRef SearchPath, StringRef RelativePath,
2751+
const LexEmbedParametersResult &Params,
2752+
StringRef BinaryContents,
2753+
const size_t TargetCharWidth);
27442754

27452755
// File inclusion.
27462756
void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok,

clang/include/clang/Sema/Sema.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5981,6 +5981,10 @@ class Sema final {
59815981
ArrayRef<Expr *> Arg, SourceLocation RParenLoc,
59825982
Expr *Config = nullptr, bool IsExecConfig = false,
59835983
ADLCallKind UsesADL = ADLCallKind::NotADL);
5984+
/// `Fn` may be a null pointer.
5985+
void ModifyCallExprArguments(Expr *Fn, SourceLocation LParenLoc,
5986+
SmallVectorImpl<Expr *> &ArgExprs,
5987+
SourceLocation RParenLoc);
59845988

59855989
ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
59865990
MultiExprArg ExecConfig,
@@ -6098,6 +6102,35 @@ class Sema final {
60986102
SourceLocation BuiltinLoc,
60996103
SourceLocation RPLoc);
61006104

6105+
// __builtin_pp_embed()
6106+
ExprResult ActOnPPEmbedExpr(SourceLocation BuiltinLoc,
6107+
SourceLocation Base64DataLocation,
6108+
SourceLocation RPLoc, StringLiteral *Filename,
6109+
QualType DataTy, std::vector<char> BinaryData);
6110+
6111+
IntegerLiteral *ExpandSinglePPEmbedExpr(PPEmbedExpr *PPEmbed);
6112+
6113+
PPEmbedExpr::Action
6114+
CheckExprListForPPEmbedExpr(ArrayRef<Expr *> ExprList,
6115+
std::optional<QualType> MaybeInitType);
6116+
PPEmbedExpr::Action
6117+
ExpandPPEmbedExprInExprList(ArrayRef<Expr *> ExprList,
6118+
SmallVectorImpl<Expr *> &OutputExprList,
6119+
bool ClearOutputFirst = true);
6120+
PPEmbedExpr::Action
6121+
ExpandPPEmbedExprInExprList(SmallVectorImpl<Expr *> &OutputList);
6122+
6123+
enum PPEmbedExprContext {
6124+
PPEEC__StaticAssert,
6125+
PPEEC_StaticAssert,
6126+
};
6127+
6128+
StringRef GetLocationName(PPEmbedExprContext Context) const;
6129+
6130+
bool DiagnosePPEmbedExpr(Expr *&E, SourceLocation ContextLocation,
6131+
PPEmbedExprContext Context,
6132+
bool SingleAllowed = true);
6133+
61016134
// Build a potentially resolved SourceLocExpr.
61026135
ExprResult BuildSourceLocExpr(SourceLocExpr::IdentKind Kind,
61036136
QualType ResultTy, SourceLocation BuiltinLoc,
@@ -8290,6 +8323,10 @@ class Sema final {
82908323
SourceLocation EqualLoc,
82918324
ParsedTemplateArgument DefaultArg);
82928325

8326+
void ModifyTemplateArguments(
8327+
const TemplateTy &Template,
8328+
SmallVectorImpl<ParsedTemplateArgument> &TemplateArgs);
8329+
82938330
TemplateParameterList *
82948331
ActOnTemplateParameterList(unsigned Depth,
82958332
SourceLocation ExportLoc,

0 commit comments

Comments
 (0)