Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ [Sema, Lex, Parse] Preprocessor embed in C and C++ (and Obj-C and Obj-C++ by-proxy) #68620

Open
wants to merge 136 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
136 commits
Select commit Hold shift + click to select a range
7050c93
✨ [Sema, Driver, Lex, Frontend] Implement naive #embed for C23 and C+…
ThePhD Sep 28, 2023
6a7a4c9
✨ Speedy #embed implementation
ThePhD Oct 8, 2023
324ff1d
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 7, 2023
77aad07
Update based on API changes in community
AaronBallman Nov 7, 2023
da636a2
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 7, 2023
1cca725
We don't yet expose a libclang cursor for embed expressions
AaronBallman Nov 7, 2023
cd6142d
Update preprocessor tests for new builtin macros
AaronBallman Nov 7, 2023
495f1d4
Fix logical think-o with the test
AaronBallman Nov 7, 2023
680c379
Fix -Wreorder diagnostics; NFC
AaronBallman Nov 7, 2023
a0f8278
Clean up these constructors to take a SmallVectorImpl
AaronBallman Nov 7, 2023
4d9ed9e
Fix a crash with argument parsing
AaronBallman Nov 7, 2023
8a466f3
Back out unrelated CMake changes
AaronBallman Nov 7, 2023
a3d4b13
Remove a spurious #undef; NFC
AaronBallman Nov 7, 2023
7dad1be
Backing out more unnecessary CMake changes
AaronBallman Nov 7, 2023
29ac376
Correct the logic for this diagnostic checking function
AaronBallman Nov 8, 2023
e4e28eb
Fix think-o with test to get it to pass
AaronBallman Nov 8, 2023
ab5f8c2
Restore previous behavior; fixes two more failing test cases
AaronBallman Nov 8, 2023
0cda935
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 8, 2023
9d5eadf
Clean up the way we expose the __STDC_EMBED_*__ macros; NFC
AaronBallman Nov 8, 2023
f88a1ae
Fix a broken pp-trace test
AaronBallman Nov 8, 2023
e7ef292
Remove __builtin_pp_embed as a builtin function; NFC
AaronBallman Nov 8, 2023
7c6bc7b
Add a test for feature testing the builtin
AaronBallman Nov 8, 2023
038c90d
Correct parsing behavior and add tests
AaronBallman Nov 8, 2023
c204b73
No longer expose the embed driver options to Flang
AaronBallman Nov 8, 2023
ec01bec
Fix type mismatch that was upsetting the precommit CI bot
AaronBallman Nov 9, 2023
f57334a
Fix misuse of Twine and add a test
AaronBallman Nov 9, 2023
8ef8da3
Remove unused variable; NFC
AaronBallman Nov 9, 2023
a5517cb
Fix a typo that snuck into this test
AaronBallman Nov 9, 2023
7f856dd
Fix another type mismatch that was upsetting the precommit CI bot
AaronBallman Nov 10, 2023
6d49cc8
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 13, 2023
b8a57c2
Fix new compile error from rebase; NFC
AaronBallman Nov 13, 2023
6a6f813
Replace __builtin_pp_embed with annotation tokens
AaronBallman Nov 13, 2023
c7e1304
Formatting changes; NFC
AaronBallman Nov 13, 2023
8c1a8fb
Change how we handle prefix and suffix tokens
AaronBallman Nov 14, 2023
14d08b6
Add some FIXME comments about AST fidelity; NFC
AaronBallman Nov 14, 2023
16cfd31
Backing out an unneeded change; NFC
AaronBallman Nov 14, 2023
528077e
Correct diagnostic behavior for ext and compat warnings
AaronBallman Nov 14, 2023
23eaf98
Fix formatting; NFC
AaronBallman Nov 14, 2023
626b1e4
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 14, 2023
a10d9d6
Fix the way we preprocess to a file
AaronBallman Nov 14, 2023
a245899
Fix formatting; NFC
AaronBallman Nov 14, 2023
00c6ff9
Attempt to appease clang-format; NFC
AaronBallman Nov 14, 2023
f36c95f
Improve the __has_embed tests somewhat
AaronBallman Nov 14, 2023
a76fa14
Use named constants in test instead of magic values; NFC
AaronBallman Nov 14, 2023
1dcc449
Start reworking the way we represent a PPEmbedExpr
AaronBallman Nov 17, 2023
1bc8f7b
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 17, 2023
aee2f34
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 27, 2023
8433fd5
Rename `-embed-dir` to `--embed-dir` and only accept the = form
AaronBallman Nov 27, 2023
d6c3c90
Remove the embed path group; it's not necessary
AaronBallman Nov 27, 2023
6abddb6
Replace some uses of string literals in diagnostics; NFC
AaronBallman Nov 27, 2023
08004b8
Simplify the implementation somewhat; NFC intended
AaronBallman Nov 27, 2023
257fc01
Correct the way we look up files with __has_embed vs #embed
AaronBallman Nov 27, 2023
137961a
Test and fix the behavior for dependency file generation
AaronBallman Nov 27, 2023
7dbd5f7
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 29, 2023
a91723c
Remove changes for clang-format
AaronBallman Nov 29, 2023
0d6ea7d
No longer pass around base64 encoded data
AaronBallman Nov 30, 2023
178cd3e
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 30, 2023
fbb0ff2
Fix the diagnostic group for unknown directives
AaronBallman Nov 30, 2023
250ec6b
Remove a newly-added unused diagnostic group, add test coverage
AaronBallman Nov 30, 2023
102d683
Remove more diagnostics related to CHAR_BIT
AaronBallman Nov 30, 2023
659e6b4
Back out unrelated changes
AaronBallman Nov 30, 2023
7f83440
Correct header file comments; NFC
AaronBallman Nov 30, 2023
df7aeae
Use a single annotation token rather than play parsing games
AaronBallman Nov 30, 2023
bab4ffb
Remove unused data member; NFC
AaronBallman Nov 30, 2023
830ab5d
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Nov 30, 2023
013bb3e
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Dec 1, 2023
b8c08af
Correct and simplify embed file lookup logic
AaronBallman Dec 1, 2023
0a185ab
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Dec 1, 2023
41c3927
No longer copy file contents to a buffer
AaronBallman Dec 1, 2023
928846c
Don't need a const size_t &; NFC
AaronBallman Dec 1, 2023
eb46ed0
Refactor code for clarity based on review feedback; NFC
AaronBallman Dec 1, 2023
828e497
Improve test coverage
AaronBallman Dec 1, 2023
69bb3bd
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Dec 1, 2023
7cf6156
Rework the way we parse embed parameters, add tests
AaronBallman Dec 2, 2023
5499603
Fix parsing for __has_embed, add comprehensive tests
AaronBallman Dec 4, 2023
37cbc63
Remove copy pasta tests; NFC
AaronBallman Dec 4, 2023
7f793f2
Formatting fixes; NFC
AaronBallman Dec 4, 2023
e3a1a32
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Dec 4, 2023
ce1fc30
Add test coverage for unknown quoted file paths
AaronBallman Dec 4, 2023
c631f08
Fix handling of the limit() parameter and add tests
AaronBallman Dec 4, 2023
456201d
Correct the behavior of clang::offset and add more tests
AaronBallman Dec 4, 2023
2675f69
Properly diagnose duplicate parameters
AaronBallman Dec 4, 2023
dd62b3f
Emit an extension warning for clang::offset
AaronBallman Dec 4, 2023
ec97562
Support parameters with leading and trailing double underscores
AaronBallman Dec 4, 2023
0dd04f2
Add test coverage from examples in the standard
AaronBallman Dec 4, 2023
aa86a45
Update the C feature status page.
AaronBallman Dec 4, 2023
64ad63c
Add documentation
AaronBallman Dec 4, 2023
efd51ef
Diagnose use of 'defined' within clang::offset and limit
AaronBallman Dec 4, 2023
3bc8fac
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Dec 5, 2023
b594f41
Remove unused include; NFC
AaronBallman Dec 5, 2023
6cfb532
Back out unrelated change; NFC
AaronBallman Dec 5, 2023
99e7828
Remove incomplete code that isn't needed
AaronBallman Dec 5, 2023
83d7bbc
Add this diagnostic to a warning group
AaronBallman Dec 5, 2023
f0ece93
Remove unnecessary changes; NFC
AaronBallman Dec 5, 2023
35461ea
Fix behavior of offset in __has_embed
AaronBallman Dec 5, 2023
b43d16c
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Dec 5, 2023
140b65e
Fix comments based on review feedback; NFC
AaronBallman Dec 5, 2023
548bed4
Remove C++ feature test macro
AaronBallman Dec 5, 2023
578259a
Use a 64-bit bit-field instead of a 32-bit one
AaronBallman Dec 5, 2023
bdac0d8
Refactor the element iterator based on review feedback; NFC
AaronBallman Dec 5, 2023
117814b
Unify these diagnostics; NFC
AaronBallman Dec 5, 2023
aa0a08d
Use SourceRange rather than a pair of SourceLocations
AaronBallman Dec 5, 2023
0ce7899
Document this interface better; NFC
AaronBallman Dec 5, 2023
56cc314
Merge branch 'main' into thephd/embed-speed
AaronBallman Dec 5, 2023
03669ce
Merge remote-tracking branch 'origin/main' into thephd/embed-speed
AaronBallman Feb 2, 2024
e886b04
Merge branch 'main' into thephd/embed-speed
cor3ntin Feb 2, 2024
5432f41
Fix some diagnostics; NFC
AaronBallman Feb 2, 2024
8148041
Merge remote-tracking branch 'main' into thephd/embed-speed
h-vetinari Mar 24, 2024
a7a1638
Merge branch 'main' into thephd/embed-speed
Fznamznon Apr 16, 2024
0273781
Fix test
Fznamznon Apr 16, 2024
fc6c6a4
Improve generic #embed usage case
Fznamznon Mar 22, 2024
2b1c0a8
Merge branch 'main' into thephd/embed-speed
Fznamznon Apr 17, 2024
ff94a01
Fix format, remove unused variable
Fznamznon Apr 17, 2024
87dd643
Fix a couple of minor problems
Fznamznon Apr 18, 2024
b1b50c5
Remove ExpandSinglePPEmbedExpr
Fznamznon Apr 22, 2024
cc97fcd
Remove Expand* and Modify* functions
Fznamznon Apr 22, 2024
1509ffd
Merge branch 'main' into thephd/embed-speed
Fznamznon Apr 22, 2024
cfda22f
Merge PPEmbedExpr and EmbedSubscriptExpr into EmbedExpr
Fznamznon Apr 24, 2024
25c98d2
Merge branch 'main' into thephd/embed-speed
Fznamznon Apr 24, 2024
31a967b
Remove CheckExprListForPPEmbedExpr
Fznamznon Apr 24, 2024
757b54f
Minor cleanup
Fznamznon Apr 24, 2024
ca665b2
Add a couple of test cases
Fznamznon Apr 24, 2024
4fd08eb
Fix broken test case
Fznamznon Apr 24, 2024
8629e19
Cleanups
Fznamznon Apr 25, 2024
a17b0d0
Fix format concerns
Fznamznon May 3, 2024
ac6cc3b
Merge branch 'main' into thephd/embed-speed
Fznamznon May 3, 2024
4bd9965
Merge branch 'main' into thephd/embed-speed
Fznamznon May 14, 2024
b4513aa
Apply comments, cleanup EmbedExpr a bit
Fznamznon May 14, 2024
00990de
A couple of comments applied
Fznamznon May 15, 2024
179485d
Merge branch 'main' into thephd/embed-speed
Fznamznon May 21, 2024
2521ae3
Improve performance of constexpr evaluation
Fznamznon May 21, 2024
becb80b
Resolve review comments
Fznamznon May 23, 2024
27ce354
Revert "Emit an extension warning for clang::offset"
Fznamznon May 23, 2024
a39062e
Fix format
Fznamznon May 23, 2024
9f3d527
Merge branch 'main' into thephd/embed-speed
Fznamznon May 24, 2024
a3615ed
Expose -dE only as cc1 option, fix a couple of warnings
Fznamznon May 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions clang-tools-extra/test/pp-trace/pp-trace-macro.cpp
Expand Up @@ -31,6 +31,15 @@ X
// CHECK: MacroNameTok: __STDC_UTF_32__
// CHECK-NEXT: MacroDirective: MD_Define
// CHECK: - Callback: MacroDefined
// CHECK-NEXT: MacroNameTok: __STDC_EMBED_NOT_FOUND__
// CHECK-NEXT: MacroDirective: MD_Define
// CHECK: - Callback: MacroDefined
// CHECK-NEXT: MacroNameTok: __STDC_EMBED_FOUND__
// CHECK-NEXT: MacroDirective: MD_Define
// CHECK: - Callback: MacroDefined
// CHECK-NEXT: MacroNameTok: __STDC_EMBED_EMPTY__
// CHECK-NEXT: MacroDirective: MD_Define
// CHECK: - Callback: MacroDefined
// CHECK: - Callback: MacroDefined
// CHECK-NEXT: MacroNameTok: MACRO
// CHECK-NEXT: MacroDirective: MD_Define
Expand Down
26 changes: 25 additions & 1 deletion clang/docs/LanguageExtensions.rst
Expand Up @@ -1502,6 +1502,7 @@ Attributes on Structured Bindings __cpp_structured_bindings C+
Designated initializers (N494) C99 C89
Array & element qualification (N2607) C23 C89
Attributes (N2335) C23 C89
``#embed`` (N3017) C23 C89, C++
============================================ ================================ ============= =============

Type Trait Primitives
Expand Down Expand Up @@ -5602,4 +5603,27 @@ Compiling different TUs depending on these flags (including use of
``std::hardware_constructive_interference`` or
``std::hardware_destructive_interference``) with different compilers, macro
definitions, or architecture flags will lead to ODR violations and should be
avoided.
avoided.

``#embed`` Parameters
=====================

``clang::offset``
-----------------
The ``clang::offset`` embed parameter may appear zero or one time in the
embed parameter sequence. Its preprocessor argument clause shall be present and
have the form:

..code-block: text

( constant-expression )

and shall be an integer constant expression. The integer constant expression
shall not evaluate to a value less than 0. The token ``defined`` shall not
appear within the constant expression.

The offset will be used when reading the contents of the embedded resource to
specify the starting offset to begin embedding from. The resources is treated
as being empty if the specified offset is larger than the number of bytes in
the resource. The offset will be applied *before* any ``limit`` parameters are
applied.
160 changes: 160 additions & 0 deletions clang/include/clang/AST/Expr.h
Expand Up @@ -4799,6 +4799,166 @@ class SourceLocExpr final : public Expr {
friend class ASTStmtReader;
};

/// Stores data related to a single #embed directive.
struct EmbedDataStorage {
StringLiteral *Filename;
StringLiteral *BinaryData;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm fine shipping this-as is, but I am not sure a StringLiteral is actually the best fit here (we might want something more ad-hoc like an integer sequence)

size_t getDataElementCount() const { return BinaryData->getByteLength(); }
};

/// Represents a reference to #emded data. By default, this references the whole
/// range. Otherwise it represents a subrange of data imported by #embed
/// directive. Needed to handle nested initializer lists with #embed directives.
/// Example:
/// struct S {
/// int x, y;
/// };
///
/// struct T {
/// int x[2];
/// struct S s
/// };
///
/// struct T t[] = {
/// #embed "data" // data contains 10 elements;
/// };
///
/// The resulting semantic form of initializer list will contain (EE stands
AaronBallman marked this conversation as resolved.
Show resolved Hide resolved
/// for EmbedExpr):
/// { {EE(first two data elements), {EE(3rd element), EE(4th element) }},
/// { {EE(5th and 6th element), {EE(7th element), EE(8th element) }},
/// { {EE(9th and 10th element), { zeroinitializer }}}
///
/// EmbedExpr inside of a semantic initializer list and referencing more than
/// one element can only appear for arrays of scalars.
class EmbedExpr final : public Expr {
SourceLocation EmbedKeywordLoc;
IntegerLiteral *FakeChildNode = nullptr;
const ASTContext *Ctx = nullptr;
EmbedDataStorage *Data;
unsigned Begin = 0;
unsigned NumOfElements;

public:
EmbedExpr(const ASTContext &Ctx, SourceLocation Loc, EmbedDataStorage *Data,
unsigned Begin, unsigned NumOfElements);
explicit EmbedExpr(EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {}

SourceLocation getLocation() const { return EmbedKeywordLoc; }
SourceLocation getBeginLoc() const { return EmbedKeywordLoc; }
SourceLocation getEndLoc() const { return EmbedKeywordLoc; }

StringLiteral *getFilenameStringLiteral() const { return Data->Filename; }
StringLiteral *getDataStringLiteral() const { return Data->BinaryData; }
EmbedDataStorage *getData() const { return Data; }

unsigned getStartingElementPos() const { return Begin; }
size_t getDataElementCount() const { return NumOfElements; }

// Allows accessing every byte of EmbedExpr data and iterating over it.
// An Iterator knows the EmbedExpr that it refers to, and an offset value
// within the data.
// Dereferencing an Iterator results in construction of IntegerLiteral AST
// node filled with byte of data of the corresponding EmbedExpr within offset
// that the Iterator currently has.
template <bool Const>
class ChildElementIter
AaronBallman marked this conversation as resolved.
Show resolved Hide resolved
: public llvm::iterator_facade_base<
ChildElementIter<Const>, std::random_access_iterator_tag,
std::conditional_t<Const, const IntegerLiteral *,
IntegerLiteral *>> {
friend class EmbedExpr;

EmbedExpr *EExpr = nullptr;
unsigned long long CurOffset = ULLONG_MAX;
using BaseTy = typename ChildElementIter::iterator_facade_base;

ChildElementIter(EmbedExpr *E) : EExpr(E) {
if (E)
CurOffset = E->getStartingElementPos();
}

public:
ChildElementIter() : CurOffset(ULLONG_MAX) {}
typename BaseTy::reference operator*() const {
assert(EExpr && CurOffset != ULLONG_MAX &&
"trying to dereference an invalid iterator");
IntegerLiteral *N = EExpr->FakeChildNode;
StringRef DataRef = EExpr->Data->BinaryData->getBytes();
N->setValue(*EExpr->Ctx,
llvm::APInt(N->getValue().getBitWidth(), DataRef[CurOffset],
N->getType()->isSignedIntegerType()));
// We want to return a reference to the fake child node in the
// EmbedExpr, not the local variable N.
return const_cast<typename BaseTy::reference>(EExpr->FakeChildNode);
}
typename BaseTy::pointer operator->() const { return **this; }
using BaseTy::operator++;
ChildElementIter &operator++() {
assert(EExpr && "trying to increment an invalid iterator");
assert(CurOffset != ULLONG_MAX &&
"Already at the end of what we can iterate over");
if (++CurOffset >=
EExpr->getDataElementCount() + EExpr->getStartingElementPos()) {
CurOffset = ULLONG_MAX;
EExpr = nullptr;
}
return *this;
}
bool operator==(ChildElementIter Other) const {
return (EExpr == Other.EExpr && CurOffset == Other.CurOffset);
}
}; // class ChildElementIter

public:
using fake_child_range = llvm::iterator_range<ChildElementIter<false>>;
using const_fake_child_range = llvm::iterator_range<ChildElementIter<true>>;

fake_child_range underlying_data_elements() {
return fake_child_range(ChildElementIter<false>(this),
ChildElementIter<false>());
}

const_fake_child_range underlying_data_elements() const {
return const_fake_child_range(
ChildElementIter<true>(const_cast<EmbedExpr *>(this)),
ChildElementIter<true>());
}

child_range children() {
return child_range(child_iterator(), child_iterator());
}

const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}

static bool classof(const Stmt *T) {
return T->getStmtClass() == EmbedExprClass;
}

ChildElementIter<false> begin() { return ChildElementIter<false>(this); }

ChildElementIter<true> begin() const {
return ChildElementIter<true>(const_cast<EmbedExpr *>(this));
}

template <typename Call, typename... Targs>
bool doForEachDataElement(Call &&C, unsigned &StartingIndexInArray,
Targs &&...Fargs) const {
for (auto It : underlying_data_elements()) {
if (!std::invoke(std::forward<Call>(C), const_cast<IntegerLiteral *>(It),
StartingIndexInArray, std::forward<Targs>(Fargs)...))
return false;
StartingIndexInArray++;
}
return true;
}

private:
friend class ASTStmtReader;
};

/// Describes an C or C++ initializer list.
///
/// InitListExpr describes an initializer list, which can be used to
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Expand Up @@ -2860,6 +2860,11 @@ DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
DEF_TRAVERSE_STMT(StmtExpr, {})
DEF_TRAVERSE_STMT(SourceLocExpr, {})
DEF_TRAVERSE_STMT(EmbedExpr, {
for (IntegerLiteral *IL : S->underlying_data_elements()) {
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(IL);
}
})

DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/TextNodeDumper.h
Expand Up @@ -405,6 +405,7 @@ class TextNodeDumper
VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D);
void VisitHLSLBufferDecl(const HLSLBufferDecl *D);
void VisitOpenACCConstructStmt(const OpenACCConstructStmt *S);
void VisitEmbedExpr(const EmbedExpr *S);
};

} // namespace clang
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticCommonKinds.td
Expand Up @@ -275,6 +275,9 @@ def err_too_large_for_fixed_point : Error<
def err_unimplemented_conversion_with_fixed_point_type : Error<
"conversion between fixed point and %0 is not yet supported">;

def err_requires_positive_value : Error<
"%select{invalid value '%0'; must be positive|value '%0' is too large}1">;

// SEH
def err_seh_expected_handler : Error<
"expected '__except' or '__finally' block">;
Expand Down
13 changes: 13 additions & 0 deletions clang/include/clang/Basic/DiagnosticLexKinds.td
Expand Up @@ -428,6 +428,14 @@ def warn_cxx23_compat_warning_directive : Warning<
def warn_c23_compat_warning_directive : Warning<
"#warning is incompatible with C standards before C23">,
InGroup<CPre23Compat>, DefaultIgnore;
def ext_pp_embed_directive : ExtWarn<
AaronBallman marked this conversation as resolved.
Show resolved Hide resolved
"'%select{#embed|__has_embed}0' is a %select{C23|Clang}1 extension">,
InGroup<C23>;
def warn_compat_pp_embed_directive : Warning<
"'%select{#embed|__has_embed}0' is incompatible with C standards before C23">,
InGroup<CPre23Compat>, DefaultIgnore;
def err_pp_embed_dup_params : Error<
"cannot specify parameter '%0' twice in the same '#embed' directive">;

def ext_pp_extra_tokens_at_eol : ExtWarn<
"extra tokens at end of #%0 directive">, InGroup<ExtraTokens>;
Expand Down Expand Up @@ -497,6 +505,9 @@ def err_pp_invalid_directive : Error<
"invalid preprocessing directive%select{|, did you mean '#%1'?}0">;
def warn_pp_invalid_directive : Warning<
err_pp_invalid_directive.Summary>, InGroup<DiagGroup<"unknown-directives">>;
def warn_pp_unknown_parameter_ignored : Warning<
"unknown%select{ | embed}0 preprocessor parameter '%1' ignored">,
InGroup<DiagGroup<"unknown-directive-parameters">>;
def err_pp_directive_required : Error<
"%0 must be used within a preprocessing directive">;
def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;
Expand Down Expand Up @@ -711,6 +722,8 @@ def err_pp_module_build_missing_end : Error<
"no matching '#pragma clang module endbuild' for this '#pragma clang module build'">;

def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
def err_defined_in_pp_embed : Error<
"'defined' cannot appear within this context">;
def err_paste_at_start : Error<
"'##' cannot appear at start of macro expansion">;
def err_paste_at_end : Error<"'##' cannot appear at end of macro expansion">;
Expand Down
2 changes: 0 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Expand Up @@ -1095,8 +1095,6 @@ def note_surrounding_namespace_starts_here : Note<
"surrounding namespace with visibility attribute starts here">;
def err_pragma_loop_invalid_argument_type : Error<
"invalid argument of type %0; expected an integer type">;
def err_pragma_loop_invalid_argument_value : Error<
"%select{invalid value '%0'; must be positive|value '%0' is too large}1">;
def err_pragma_loop_compatibility : Error<
"%select{incompatible|duplicate}0 directives '%1' and '%2'">;
def err_pragma_loop_precedes_nonloop : Error<
Expand Down
11 changes: 7 additions & 4 deletions clang/include/clang/Basic/FileManager.h
Expand Up @@ -286,12 +286,15 @@ class FileManager : public RefCountedBase<FileManager> {
/// MemoryBuffer if successful, otherwise returning null.
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFile(FileEntryRef Entry, bool isVolatile = false,
bool RequiresNullTerminator = true);
bool RequiresNullTerminator = true,
std::optional<int64_t> MaybeLimit = std::nullopt);
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFile(StringRef Filename, bool isVolatile = false,
bool RequiresNullTerminator = true) const {
return getBufferForFileImpl(Filename, /*FileSize=*/-1, isVolatile,
RequiresNullTerminator);
bool RequiresNullTerminator = true,
std::optional<int64_t> MaybeLimit = std::nullopt) const {
return getBufferForFileImpl(Filename,
/*FileSize=*/(MaybeLimit ? *MaybeLimit : -1),
isVolatile, RequiresNullTerminator);
}

private:
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/StmtNodes.td
Expand Up @@ -204,6 +204,7 @@ def OpaqueValueExpr : StmtNode<Expr>;
def TypoExpr : StmtNode<Expr>;
def RecoveryExpr : StmtNode<Expr>;
def BuiltinBitCastExpr : StmtNode<ExplicitCastExpr>;
def EmbedExpr : StmtNode<Expr>;

// Microsoft Extensions.
def MSPropertyRefExpr : StmtNode<Expr>;
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/TokenKinds.def
Expand Up @@ -126,6 +126,9 @@ PPKEYWORD(error)
// C99 6.10.6 - Pragma Directive.
PPKEYWORD(pragma)

// C23 & C++26 #embed
PPKEYWORD(embed)

// GNU Extensions.
PPKEYWORD(import)
PPKEYWORD(include_next)
Expand Down Expand Up @@ -997,6 +1000,9 @@ ANNOTATION(header_unit)
// Annotation for end of input in clang-repl.
ANNOTATION(repl_input_end)

// Annotation for #embed
ANNOTATION(embed)
AaronBallman marked this conversation as resolved.
Show resolved Hide resolved

#undef PRAGMA_ANNOTATION
#undef ANNOTATION
#undef TESTING_KEYWORD
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Driver/Options.td
Expand Up @@ -868,6 +868,9 @@ will be ignored}]>;
def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>, Group<Link_Group>,
Visibility<[ClangOption, FlangOption]>,
MetaVarName<"<dir>">, HelpText<"Add directory to library search path">;
def embed_dir_EQ : Joined<["--"], "embed-dir=">, Group<Preprocessor_Group>,
Visibility<[ClangOption, CC1Option]>, MetaVarName<"<dir>">,
HelpText<"Add directory to embed search path">;
def MD : Flag<["-"], "MD">, Group<M_Group>,
HelpText<"Write a depfile containing user and system headers">;
def MMD : Flag<["-"], "MMD">, Group<M_Group>,
Expand Down Expand Up @@ -1455,6 +1458,9 @@ def dD : Flag<["-"], "dD">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>
def dI : Flag<["-"], "dI">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Print include directives in -E mode in addition to normal output">,
MarshallingInfoFlag<PreprocessorOutputOpts<"ShowIncludeDirectives">>;
def dE : Flag<["-"], "dE">, Group<d_Group>, Visibility<[CC1Option]>,
HelpText<"Print embed directives in -E mode in addition to normal output">,
MarshallingInfoFlag<PreprocessorOutputOpts<"ShowEmbedDirectives">>;
def dM : Flag<["-"], "dM">, Group<d_Group>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Print macro definitions in -E mode instead of normal output">;
def dead__strip : Flag<["-"], "dead_strip">;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Frontend/PreprocessorOutputOptions.h
Expand Up @@ -32,6 +32,8 @@ class PreprocessorOutputOptions {
LLVM_PREFERRED_TYPE(bool)
unsigned ShowIncludeDirectives : 1; ///< Print includes, imports etc. within preprocessed output.
LLVM_PREFERRED_TYPE(bool)
unsigned ShowEmbedDirectives : 1; ///< Print embeds, etc. within preprocessed
LLVM_PREFERRED_TYPE(bool)
unsigned RewriteIncludes : 1; ///< Preprocess include directives only.
LLVM_PREFERRED_TYPE(bool)
unsigned RewriteImports : 1; ///< Include contents of transitively-imported modules.
Expand All @@ -51,6 +53,7 @@ class PreprocessorOutputOptions {
ShowMacroComments = 0;
ShowMacros = 0;
ShowIncludeDirectives = 0;
ShowEmbedDirectives = 0;
RewriteIncludes = 0;
RewriteImports = 0;
MinimizeWhitespace = 0;
Expand Down