aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseInit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/ParseInit.cpp')
-rw-r--r--clang/lib/Parse/ParseInit.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index 432ddc7..0a9a359 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -428,6 +428,34 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator(
return ExprError();
}
+ExprResult Parser::createEmbedExpr() {
+ assert(Tok.getKind() == tok::annot_embed);
+ EmbedAnnotationData *Data =
+ reinterpret_cast<EmbedAnnotationData *>(Tok.getAnnotationValue());
+ ExprResult Res;
+ ASTContext &Context = Actions.getASTContext();
+ SourceLocation StartLoc = ConsumeAnnotationToken();
+ if (Data->BinaryData.size() == 1) {
+ Res = IntegerLiteral::Create(Context,
+ llvm::APInt(CHAR_BIT, Data->BinaryData.back()),
+ Context.UnsignedCharTy, StartLoc);
+ } else {
+ auto CreateStringLiteralFromStringRef = [&](StringRef Str, QualType Ty) {
+ llvm::APSInt ArraySize =
+ Context.MakeIntValue(Str.size(), Context.getSizeType());
+ QualType ArrayTy = Context.getConstantArrayType(
+ Ty, ArraySize, nullptr, ArraySizeModifier::Normal, 0);
+ return StringLiteral::Create(Context, Str, StringLiteralKind::Ordinary,
+ false, ArrayTy, StartLoc);
+ };
+
+ StringLiteral *BinaryDataArg = CreateStringLiteralFromStringRef(
+ Data->BinaryData, Context.UnsignedCharTy);
+ Res = Actions.ActOnEmbedExpr(StartLoc, BinaryDataArg);
+ }
+ return Res;
+}
+
/// ParseBraceInitializer - Called when parsing an initializer that has a
/// leading open brace.
///
@@ -501,6 +529,8 @@ ExprResult Parser::ParseBraceInitializer() {
ExprResult SubElt;
if (MayBeDesignationStart())
SubElt = ParseInitializerWithPotentialDesignator(DesignatorCompletion);
+ else if (Tok.getKind() == tok::annot_embed)
+ SubElt = createEmbedExpr();
else
SubElt = ParseInitializer();