Skip to content

Commit 9eb1adf

Browse files
committed
[PP-EXT] Add support for extended variant creation
1 parent e899b51 commit 9eb1adf

File tree

2 files changed

+55
-13
lines changed

2 files changed

+55
-13
lines changed

clang/lib/Parse/ParseDecl.cpp

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4413,6 +4413,38 @@ void Parser::ParseStructDeclaration(
44134413
}
44144414
}
44154415

4416+
static std::string GetMangledName(const std::string& Base, const std::string& Variant) {
4417+
return std::string("__pp_struct_")
4418+
+ Base + "__"
4419+
+ Variant;
4420+
}
4421+
4422+
static std::string GetVariantName(Parser& P, const std::string& CurTokName, const Token& NextTok) {
4423+
if (!P.getCurToken().is(tok::identifier)) {
4424+
llvm_unreachable("pp-ext-expected-token-identifier");
4425+
return "<pp-ext-expected-token-identifier>";
4426+
}
4427+
4428+
std::string MangledName;
4429+
switch (NextTok.getKind())
4430+
{
4431+
case tok::comma:
4432+
case tok::greater:
4433+
return CurTokName;
4434+
break;
4435+
case tok::less:
4436+
P.ConsumeToken(); // gen identifier
4437+
P.ConsumeToken(); // less
4438+
MangledName = GetMangledName(CurTokName, GetVariantName(P, CurTokName, P.NextToken()));
4439+
P.ConsumeToken(); // variant identifier
4440+
return MangledName;
4441+
default:
4442+
llvm_unreachable("pp-ext-error-name");
4443+
break;
4444+
}
4445+
return "<pp-ext-error-name>";
4446+
}
4447+
44164448
Parser::SpecsVec Parser::TryParsePPExt(Decl *TagDecl,
44174449
SmallVector<Decl *, 32>& FieldDecls,
44184450
const ParsedAttributes& Attrs) {
@@ -4421,27 +4453,28 @@ Parser::SpecsVec Parser::TryParsePPExt(Decl *TagDecl,
44214453
return Result;
44224454
}
44234455

4424-
auto DeclGenerator = [&](StringRef Name) {
4425-
auto* RD = cast<RecordDecl>(TagDecl);
4426-
auto MangledName = std::string("__pp_struct_")
4427-
+ RD->getDeclName().getAsString() + "__"
4428-
+ Name.str();
4429-
auto TestName = &PP.getIdentifierTable().get(MangledName);
4456+
auto DeclGenerator = [&](std::string BaseName, std::string VarName) {
4457+
auto IdentifierName = &PP.getIdentifierTable().get(VarName);
44304458

44314459
// TODO: Fill Fields
44324460
FieldList Fields;
44334461

4434-
return std::tuple<std::string, IdentifierInfo*, FieldList>{Name.str(), TestName, Fields};
4462+
return std::tuple<std::string, IdentifierInfo*, FieldList>{BaseName, IdentifierName, Fields};
44354463
};
44364464

44374465
printf("\n[PPMC] Parse extension\n");
44384466
ConsumeAnyToken();
4467+
auto* RD = cast<RecordDecl>(TagDecl);
4468+
const auto GenName = RD->getDeclName().getAsString();
44394469
while (Tok.isNot(clang::tok::greater)) {
44404470
printf(" Token -> Kind: [%s]", Tok.getName());
44414471
if (Tok.is(clang::tok::identifier)) {
4442-
auto Name = Tok.getIdentifierInfo()->getName().str();
4443-
printf(", Name:[%s]", Name.c_str());
4444-
auto D = DeclGenerator(Tok.getIdentifierInfo()->getName());
4472+
const auto TokName = Tok.getIdentifierInfo()->getName().str();
4473+
auto Name = GetVariantName(*this,
4474+
GetMangledName(GenName, TokName),
4475+
NextToken());// Tok.getIdentifierInfo()->getName().str();
4476+
printf(", Name:[%s]", TokName.c_str());
4477+
auto D = DeclGenerator(TokName, Name);
44454478
Result.push_back(D);
44464479
}
44474480
printf("\n");
@@ -4642,6 +4675,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
46424675
auto VariantName = std::get<0>(SpecializationTuple);
46434676
auto VariantNameIdentifier = &PP.getIdentifierTable().get(VariantName);
46444677
auto TestName = std::get<1>(SpecializationTuple);
4678+
printf("[] Test name: %s, Variant Name: %s\n", TestName->getNameStart(), VariantName.c_str());
46454679
ParsingDeclSpec PDS(*this);
46464680
auto VariantDecl = Actions.ActOnTag(getCurScope(), clang::TST_struct, clang::Sema::TUK_Reference,
46474681
TestLocation, TestSS, VariantNameIdentifier, TestLocation, TestAttrs, clang::AS_none, TestLocation,

clang/test/CodeGen/pp-generalization.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ int test_vars() {
7474
return get_spec_field1(gb1) + get_spec_field2(gb2);
7575
}
7676

77-
// struct Base_gen1 { struct Generalization<Base1> b; };
78-
// struct Base_gen2 { struct Generalization<Base2> b; };
79-
// struct Generalization_extended { double additional_field; } < Generalization<Base1>, Generalization<Base2> >;
77+
struct Base_gen1 { struct Generalization<Base1> b; };
78+
struct Base_gen2 { struct Generalization<Base2> b; };
79+
// struct Generalization_nested { double additional_field; } < Generalization<Base1>, Generalization<Base2> >;
80+
struct Generalization_extended { double other_field; } < Base_gen1, Base_gen2 >;
81+
82+
int test_nested_vars() {
83+
// struct Generalization_nested<Generalization<Base1>> gn1;
84+
// gn1<><i> = 4;
85+
struct Generalization_extended<Base_gen1> ge1;
86+
// ge1<b><i> = 5;
87+
}

0 commit comments

Comments
 (0)