Skip to content

Commit

Permalink
Add new #pragma cheerp env to change default cheerp section
Browse files Browse the repository at this point in the history
  • Loading branch information
yuri91 committed Oct 22, 2024
1 parent 77f19d5 commit a893bad
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 1 deletion.
1 change: 1 addition & 0 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
std::unique_ptr<PragmaHandler> CheerpEnvHandler;

std::unique_ptr<CommentHandler> CommentSemaHandler;

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -10700,6 +10700,9 @@ class Sema final {
/// Called on well formed \#pragma clang optimize.
void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc);

/// Called on well formed \#pragma cheerp env.
void ActOnPragmaCheerpEnv(LangOptions::CheerpDefaultEnvMode Mode, SourceLocation PragmaLoc);

/// #pragma optimize("[optimization-list]", on | off).
void ActOnPragmaMSOptimize(SourceLocation Loc, bool IsOn);

Expand Down
61 changes: 61 additions & 0 deletions clang/lib/Parse/ParsePragma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,17 @@ struct PragmaOptimizeHandler : public PragmaHandler {
Sema &Actions;
};

/// PragmaCheerpEnvHandler - "\#pragma cheerp env genericjs/wasm/none/reset".
struct PragmaCheerpEnvHandler : public PragmaHandler {
PragmaCheerpEnvHandler(Sema &S)
: PragmaHandler("env"), Actions(S) {}
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
Token &FirstToken) override;

private:
Sema &Actions;
};

struct PragmaLoopHintHandler : public PragmaHandler {
PragmaLoopHintHandler() : PragmaHandler("loop") {}
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
Expand Down Expand Up @@ -472,6 +483,11 @@ void Parser::initializePragmaHandlers() {
PP.AddPragmaHandler("clang", CUDAForceHostDeviceHandler.get());
}

if (getLangOpts().Cheerp) {
CheerpEnvHandler = std::make_unique<PragmaCheerpEnvHandler>(Actions);
PP.AddPragmaHandler("cheerp", CheerpEnvHandler.get());
}

OptimizeHandler = std::make_unique<PragmaOptimizeHandler>(Actions);
PP.AddPragmaHandler("clang", OptimizeHandler.get());

Expand Down Expand Up @@ -606,6 +622,10 @@ void Parser::resetPragmaHandlers() {
PP.RemovePragmaHandler("STDC", STDCUnknownHandler.get());
STDCUnknownHandler.reset();

if (getLangOpts().Cheerp) {
PP.RemovePragmaHandler("cheerp", CheerpEnvHandler.get());
CheerpEnvHandler.reset();
}
PP.RemovePragmaHandler("clang", OptimizeHandler.get());
OptimizeHandler.reset();

Expand Down Expand Up @@ -3166,6 +3186,47 @@ void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
}

// #pragma cheerp env genericjs/wasm/reset
void PragmaCheerpEnvHandler::HandlePragma(Preprocessor &PP,
PragmaIntroducer Introducer,
Token &FirstToken) {
Token Tok;
PP.Lex(Tok);
if (Tok.is(tok::eod)) {
PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
<< "cheerp env" << /*Expected=*/true << "'genericjs', 'wasm', 'none', or 'reset'";
return;
}
if (Tok.isNot(tok::identifier)) {
PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
<< PP.getSpelling(Tok);
return;
}
const IdentifierInfo *II = Tok.getIdentifierInfo();
// The only accepted values are 'genericjs', 'wasm', 'none', or 'reset'.
LangOptions::CheerpDefaultEnvMode Mode = LangOptions::CheerpDefaultEnvMode::None;
if (II->isStr("genericjs")) {
Mode = LangOptions::CheerpDefaultEnvMode::GenericJS;
} else if (II->isStr("wasm")) {
Mode = LangOptions::CheerpDefaultEnvMode::Wasm;
} else if (II->isStr("reset")) {
Mode = Actions.getLangOpts().getCheerpDefaultEnv();
} else if (!II->isStr("none")) {
PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
<< PP.getSpelling(Tok);
return;
}
PP.Lex(Tok);

if (Tok.isNot(tok::eod)) {
PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
<< PP.getSpelling(Tok);
return;
}

Actions.ActOnPragmaCheerpEnv(Mode, FirstToken.getLocation());
}

namespace {
/// Used as the annotation value for tok::annot_pragma_fp.
struct TokFPAnnotValue {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,

CurFPFeatures.setFPEvalMethod(PP.getCurrentFPEvalMethod());

CurCheerpEnv = getLangOpts().getCheerpDefaultEnv();
ActOnPragmaCheerpEnv(getLangOpts().getCheerpDefaultEnv(), SourceLocation());
}

// Anchor Sema's type info to this TU.
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Sema/SemaAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,10 @@ void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
OptimizeOffPragmaLocation = PragmaLoc;
}

void Sema::ActOnPragmaCheerpEnv(LangOptions::CheerpDefaultEnvMode Mode, SourceLocation PragmaLoc) {
CurCheerpEnv = Mode;
}

void Sema::ActOnPragmaMSOptimize(SourceLocation Loc, bool IsOn) {
if (!CurContext->getRedeclContext()->isFileContext()) {
Diag(Loc, diag::err_pragma_expected_file_scope) << "optimize";
Expand Down

0 comments on commit a893bad

Please sign in to comment.