mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Macros] Requestify MacroExpansionExpr expansion
The request returns the expanded buffer ID even if it failed to typecheck the expanded buffer. This makes refactoring 'Expand Macro' work regardless of the typechecking results. rdar://108530760
This commit is contained in:
@@ -3930,6 +3930,26 @@ public:
|
|||||||
void noteCycleStep(DiagnosticEngine &diags) const;
|
void noteCycleStep(DiagnosticEngine &diags) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Expand a 'MacroExpansionExpr',
|
||||||
|
class ExpandMacroExpansionExprRequest
|
||||||
|
: public SimpleRequest<ExpandMacroExpansionExprRequest,
|
||||||
|
Optional<unsigned>(MacroExpansionExpr *),
|
||||||
|
RequestFlags::Cached> {
|
||||||
|
public:
|
||||||
|
using SimpleRequest::SimpleRequest;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend SimpleRequest;
|
||||||
|
|
||||||
|
Optional<unsigned>
|
||||||
|
evaluate(Evaluator &evaluator, MacroExpansionExpr *mee) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool isCached() const { return true; }
|
||||||
|
void diagnoseCycle(DiagnosticEngine &diags) const;
|
||||||
|
void noteCycleStep(DiagnosticEngine &diags) const;
|
||||||
|
};
|
||||||
|
|
||||||
/// Expand all accessor macros attached to the given declaration.
|
/// Expand all accessor macros attached to the given declaration.
|
||||||
///
|
///
|
||||||
/// Produces the set of macro expansion buffer IDs.
|
/// Produces the set of macro expansion buffer IDs.
|
||||||
|
|||||||
@@ -439,6 +439,9 @@ SWIFT_REQUEST(TypeChecker, ExternalMacroDefinitionRequest,
|
|||||||
SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
|
SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
|
||||||
ArrayRef<Decl *>(MacroExpansionDecl *),
|
ArrayRef<Decl *>(MacroExpansionDecl *),
|
||||||
Cached, NoLocationInfo)
|
Cached, NoLocationInfo)
|
||||||
|
SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionExprRequest,
|
||||||
|
ArrayRef<Decl *>(MacroExpansionExpr *),
|
||||||
|
Cached, NoLocationInfo)
|
||||||
SWIFT_REQUEST(TypeChecker, ExpandMemberAttributeMacros,
|
SWIFT_REQUEST(TypeChecker, ExpandMemberAttributeMacros,
|
||||||
ArrayRef<unsigned>(Decl *),
|
ArrayRef<unsigned>(Decl *),
|
||||||
Cached, NoLocationInfo)
|
Cached, NoLocationInfo)
|
||||||
|
|||||||
@@ -1833,6 +1833,22 @@ void ExpandMacroExpansionDeclRequest::noteCycleStep(DiagnosticEngine &diags) con
|
|||||||
decl->getMacroName().getFullName());
|
decl->getMacroName().getFullName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExpandMacroExpansionExprRequest::diagnoseCycle(DiagnosticEngine &diags) const {
|
||||||
|
auto expr = std::get<0>(getStorage());
|
||||||
|
diags.diagnose(expr->getStartLoc(),
|
||||||
|
diag::macro_expand_circular_reference,
|
||||||
|
"freestanding",
|
||||||
|
expr->getMacroName().getFullName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpandMacroExpansionExprRequest::noteCycleStep(DiagnosticEngine &diags) const {
|
||||||
|
auto expr = std::get<0>(getStorage());
|
||||||
|
diags.diagnose(expr->getStartLoc(),
|
||||||
|
diag::macro_expand_circular_reference_through,
|
||||||
|
"freestanding",
|
||||||
|
expr->getMacroName().getFullName());
|
||||||
|
}
|
||||||
|
|
||||||
void ExpandAccessorMacros::diagnoseCycle(DiagnosticEngine &diags) const {
|
void ExpandAccessorMacros::diagnoseCycle(DiagnosticEngine &diags) const {
|
||||||
auto decl = std::get<0>(getStorage());
|
auto decl = std::get<0>(getStorage());
|
||||||
diags.diagnose(decl->getLoc(),
|
diags.diagnose(decl->getLoc(),
|
||||||
|
|||||||
@@ -8622,11 +8622,9 @@ bool RefactoringActionAddAsyncWrapper::performChange() {
|
|||||||
/// expression.
|
/// expression.
|
||||||
static Optional<unsigned> getMacroExpansionBuffer(
|
static Optional<unsigned> getMacroExpansionBuffer(
|
||||||
SourceManager &sourceMgr, MacroExpansionExpr *expansion) {
|
SourceManager &sourceMgr, MacroExpansionExpr *expansion) {
|
||||||
if (auto rewritten = expansion->getRewritten()) {
|
return evaluateOrDefault(
|
||||||
return sourceMgr.findBufferContainingLoc(rewritten->getStartLoc());
|
expansion->getDeclContext()->getASTContext().evaluator,
|
||||||
}
|
ExpandMacroExpansionExprRequest{expansion}, {});
|
||||||
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the macro expansion buffer for the given macro expansion
|
/// Retrieve the macro expansion buffer for the given macro expansion
|
||||||
|
|||||||
@@ -2937,13 +2937,14 @@ namespace {
|
|||||||
|
|
||||||
auto macro = cast<MacroDecl>(overload.choice.getDecl());
|
auto macro = cast<MacroDecl>(overload.choice.getDecl());
|
||||||
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
|
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
|
||||||
if (auto newExpr = expandMacroExpr(dc, expr, macroRef, expandedType)) {
|
auto expansion = new (ctx) MacroExpansionExpr(
|
||||||
auto expansion = new (ctx) MacroExpansionExpr(
|
dc, expr->getStartLoc(), DeclNameRef(macro->getName()),
|
||||||
dc, expr->getStartLoc(), DeclNameRef(macro->getName()),
|
DeclNameLoc(expr->getLoc()), SourceLoc(), {}, SourceLoc(), nullptr,
|
||||||
DeclNameLoc(expr->getLoc()), SourceLoc(), { }, SourceLoc(),
|
MacroRole::Expression, /*isImplicit=*/true, expandedType);
|
||||||
nullptr, MacroRole::Expression, /*isImplicit=*/true, expandedType);
|
expansion->setMacroRef(macroRef);
|
||||||
expansion->setMacroRef(macroRef);
|
(void)evaluateOrDefault(
|
||||||
expansion->setRewritten(newExpr);
|
ctx.evaluator, ExpandMacroExpansionExprRequest{expansion}, None);
|
||||||
|
if (expansion->getRewritten()) {
|
||||||
cs.cacheExprTypes(expansion);
|
cs.cacheExprTypes(expansion);
|
||||||
return expansion;
|
return expansion;
|
||||||
}
|
}
|
||||||
@@ -5386,23 +5387,11 @@ namespace {
|
|||||||
auto macro = cast<MacroDecl>(overload.choice.getDecl());
|
auto macro = cast<MacroDecl>(overload.choice.getDecl());
|
||||||
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
|
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
|
||||||
E->setMacroRef(macroRef);
|
E->setMacroRef(macroRef);
|
||||||
|
E->setType(expandedType);
|
||||||
|
|
||||||
if (!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions)) {
|
if (!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions)) {
|
||||||
if (macro->getMacroRoles().contains(MacroRole::Expression)) {
|
(void)evaluateOrDefault(cs.getASTContext().evaluator,
|
||||||
if (auto newExpr = expandMacroExpr(dc, E, macroRef, expandedType)) {
|
ExpandMacroExpansionExprRequest{E}, None);
|
||||||
E->setRewritten(newExpr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// For a non-expression macro, expand it as a declaration.
|
|
||||||
else if (macro->getMacroRoles().contains(MacroRole::Declaration) ||
|
|
||||||
macro->getMacroRoles().contains(MacroRole::CodeItem)) {
|
|
||||||
if (!E->getSubstituteDecl()) {
|
|
||||||
auto *med = E->createSubstituteDecl();
|
|
||||||
TypeChecker::typeCheckDecl(med);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Other macro roles may also be encountered here, as they use
|
|
||||||
// `MacroExpansionExpr` for resolution. In those cases, do not expand.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cs.cacheExprTypes(E);
|
cs.cacheExprTypes(E);
|
||||||
|
|||||||
@@ -456,6 +456,35 @@ static std::string adjustMacroExpansionBufferName(StringRef name) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<unsigned>
|
||||||
|
ExpandMacroExpansionExprRequest::evaluate(Evaluator &evaluator,
|
||||||
|
MacroExpansionExpr *mee) const {
|
||||||
|
ConcreteDeclRef macroRef = mee->getMacroRef();
|
||||||
|
assert(macroRef && isa<MacroDecl>(macroRef.getDecl()) &&
|
||||||
|
"MacroRef should be set before expansion");
|
||||||
|
|
||||||
|
auto *macro = cast<MacroDecl>(macroRef.getDecl());
|
||||||
|
if (macro->getMacroRoles().contains(MacroRole::Expression)) {
|
||||||
|
return expandMacroExpr(mee);
|
||||||
|
}
|
||||||
|
// For a non-expression macro, expand it as a declaration.
|
||||||
|
else if (macro->getMacroRoles().contains(MacroRole::Declaration) ||
|
||||||
|
macro->getMacroRoles().contains(MacroRole::CodeItem)) {
|
||||||
|
if (!mee->getSubstituteDecl()) {
|
||||||
|
auto *med = mee->createSubstituteDecl();
|
||||||
|
TypeChecker::typeCheckDecl(med);
|
||||||
|
}
|
||||||
|
// Return the expanded buffer ID.
|
||||||
|
return evaluateOrDefault(
|
||||||
|
evaluator, ExpandMacroExpansionDeclRequest(mee->getSubstituteDecl()),
|
||||||
|
None);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other macro roles may also be encountered here, as they use
|
||||||
|
// `MacroExpansionExpr` for resolution. In those cases, do not expand.
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
ArrayRef<unsigned> ExpandMemberAttributeMacros::evaluate(Evaluator &evaluator,
|
ArrayRef<unsigned> ExpandMemberAttributeMacros::evaluate(Evaluator &evaluator,
|
||||||
Decl *decl) const {
|
Decl *decl) const {
|
||||||
if (decl->isImplicit())
|
if (decl->isImplicit())
|
||||||
@@ -666,22 +695,24 @@ static std::string expandMacroDefinition(
|
|||||||
return expandedResult;
|
return expandedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr *swift::expandMacroExpr(
|
Optional<unsigned>
|
||||||
DeclContext *dc, Expr *expr, ConcreteDeclRef macroRef, Type expandedType
|
swift::expandMacroExpr(MacroExpansionExpr *mee) {
|
||||||
) {
|
DeclContext *dc = mee->getDeclContext();
|
||||||
ASTContext &ctx = dc->getASTContext();
|
ASTContext &ctx = dc->getASTContext();
|
||||||
SourceManager &sourceMgr = ctx.SourceMgr;
|
SourceManager &sourceMgr = ctx.SourceMgr;
|
||||||
|
ConcreteDeclRef macroRef = mee->getMacroRef();
|
||||||
|
Type expandedType = mee->getType();
|
||||||
|
|
||||||
auto moduleDecl = dc->getParentModule();
|
auto moduleDecl = dc->getParentModule();
|
||||||
auto sourceFile = moduleDecl->getSourceFileContainingLocation(expr->getLoc());
|
auto sourceFile = moduleDecl->getSourceFileContainingLocation(mee->getLoc());
|
||||||
if (!sourceFile)
|
if (!sourceFile)
|
||||||
return nullptr;
|
return None;
|
||||||
|
|
||||||
MacroDecl *macro = cast<MacroDecl>(macroRef.getDecl());
|
MacroDecl *macro = cast<MacroDecl>(macroRef.getDecl());
|
||||||
|
|
||||||
if (isFromExpansionOfMacro(sourceFile, macro, MacroRole::Expression)) {
|
if (isFromExpansionOfMacro(sourceFile, macro, MacroRole::Expression)) {
|
||||||
ctx.Diags.diagnose(expr->getLoc(), diag::macro_recursive, macro->getName());
|
ctx.Diags.diagnose(mee->getLoc(), diag::macro_recursive, macro->getName());
|
||||||
return nullptr;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the macro.
|
// Evaluate the macro.
|
||||||
@@ -690,12 +721,11 @@ Expr *swift::expandMacroExpr(
|
|||||||
/// The discriminator used for the macro.
|
/// The discriminator used for the macro.
|
||||||
LazyValue<std::string> discriminator([&]() -> std::string {
|
LazyValue<std::string> discriminator([&]() -> std::string {
|
||||||
#if SWIFT_SWIFT_PARSER
|
#if SWIFT_SWIFT_PARSER
|
||||||
if (auto expansionExpr = dyn_cast<MacroExpansionExpr>(expr)) {
|
Mangle::ASTMangler mangler;
|
||||||
Mangle::ASTMangler mangler;
|
return mangler.mangleMacroExpansion(mee);
|
||||||
return mangler.mangleMacroExpansion(expansionExpr);
|
#else
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return "";
|
return "";
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
auto macroDef = macro->getDefinition();
|
auto macroDef = macro->getDefinition();
|
||||||
@@ -703,21 +733,21 @@ Expr *swift::expandMacroExpr(
|
|||||||
case MacroDefinition::Kind::Undefined:
|
case MacroDefinition::Kind::Undefined:
|
||||||
case MacroDefinition::Kind::Invalid:
|
case MacroDefinition::Kind::Invalid:
|
||||||
// Already diagnosed as an error elsewhere.
|
// Already diagnosed as an error elsewhere.
|
||||||
return nullptr;
|
return None;
|
||||||
|
|
||||||
case MacroDefinition::Kind::Builtin: {
|
case MacroDefinition::Kind::Builtin: {
|
||||||
switch (macroDef.getBuiltinKind()) {
|
switch (macroDef.getBuiltinKind()) {
|
||||||
case BuiltinMacroKind::ExternalMacro:
|
case BuiltinMacroKind::ExternalMacro:
|
||||||
ctx.Diags.diagnose(
|
ctx.Diags.diagnose(
|
||||||
expr->getLoc(), diag::external_macro_outside_macro_definition);
|
mee->getLoc(), diag::external_macro_outside_macro_definition);
|
||||||
return nullptr;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case MacroDefinition::Kind::Expanded: {
|
case MacroDefinition::Kind::Expanded: {
|
||||||
// Expand the definition with the given arguments.
|
// Expand the definition with the given arguments.
|
||||||
auto result = expandMacroDefinition(
|
auto result = expandMacroDefinition(
|
||||||
macroDef.getExpanded(), macro, expr->getArgs());
|
macroDef.getExpanded(), macro, mee->getArgs());
|
||||||
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
|
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
|
||||||
result, adjustMacroExpansionBufferName(*discriminator));
|
result, adjustMacroExpansionBufferName(*discriminator));
|
||||||
break;
|
break;
|
||||||
@@ -732,22 +762,22 @@ Expr *swift::expandMacroExpr(
|
|||||||
auto externalDef = evaluateOrDefault(ctx.evaluator, request, None);
|
auto externalDef = evaluateOrDefault(ctx.evaluator, request, None);
|
||||||
if (!externalDef) {
|
if (!externalDef) {
|
||||||
ctx.Diags.diagnose(
|
ctx.Diags.diagnose(
|
||||||
expr->getLoc(), diag::external_macro_not_found,
|
mee->getLoc(), diag::external_macro_not_found,
|
||||||
external.moduleName.str(),
|
external.moduleName.str(),
|
||||||
external.macroTypeName.str(),
|
external.macroTypeName.str(),
|
||||||
macro->getName()
|
macro->getName()
|
||||||
);
|
);
|
||||||
macro->diagnose(diag::decl_declared_here, macro->getName());
|
macro->diagnose(diag::decl_declared_here, macro->getName());
|
||||||
return nullptr;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SWIFT_SWIFT_PARSER
|
#if SWIFT_SWIFT_PARSER
|
||||||
PrettyStackTraceExpr debugStack(ctx, "expanding macro", expr);
|
PrettyStackTraceExpr debugStack(ctx, "expanding macro", mee);
|
||||||
|
|
||||||
// Builtin macros are handled via ASTGen.
|
// Builtin macros are handled via ASTGen.
|
||||||
auto astGenSourceFile = sourceFile->exportedSourceFile;
|
auto astGenSourceFile = sourceFile->exportedSourceFile;
|
||||||
if (!astGenSourceFile)
|
if (!astGenSourceFile)
|
||||||
return nullptr;
|
return None;
|
||||||
|
|
||||||
const char *evaluatedSourceAddress;
|
const char *evaluatedSourceAddress;
|
||||||
ptrdiff_t evaluatedSourceLength;
|
ptrdiff_t evaluatedSourceLength;
|
||||||
@@ -755,18 +785,18 @@ Expr *swift::expandMacroExpr(
|
|||||||
&ctx.Diags, externalDef->opaqueHandle,
|
&ctx.Diags, externalDef->opaqueHandle,
|
||||||
static_cast<uint32_t>(externalDef->kind), discriminator->data(),
|
static_cast<uint32_t>(externalDef->kind), discriminator->data(),
|
||||||
discriminator->size(), astGenSourceFile,
|
discriminator->size(), astGenSourceFile,
|
||||||
expr->getStartLoc().getOpaquePointerValue(), &evaluatedSourceAddress,
|
mee->getStartLoc().getOpaquePointerValue(), &evaluatedSourceAddress,
|
||||||
&evaluatedSourceLength);
|
&evaluatedSourceLength);
|
||||||
if (!evaluatedSourceAddress)
|
if (!evaluatedSourceAddress)
|
||||||
return nullptr;
|
return None;
|
||||||
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
|
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
|
||||||
{evaluatedSourceAddress, (size_t)evaluatedSourceLength},
|
{evaluatedSourceAddress, (size_t)evaluatedSourceLength},
|
||||||
adjustMacroExpansionBufferName(*discriminator));
|
adjustMacroExpansionBufferName(*discriminator));
|
||||||
free((void *)evaluatedSourceAddress);
|
free((void *)evaluatedSourceAddress);
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
ctx.Diags.diagnose(expr->getLoc(), diag::macro_unsupported);
|
ctx.Diags.diagnose(mee->getLoc(), diag::macro_unsupported);
|
||||||
return nullptr;
|
return None;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -787,9 +817,9 @@ Expr *swift::expandMacroExpr(
|
|||||||
GeneratedSourceInfo sourceInfo{
|
GeneratedSourceInfo sourceInfo{
|
||||||
GeneratedSourceInfo::ExpressionMacroExpansion,
|
GeneratedSourceInfo::ExpressionMacroExpansion,
|
||||||
Lexer::getCharSourceRangeFromSourceRange(
|
Lexer::getCharSourceRangeFromSourceRange(
|
||||||
sourceMgr, expr->getSourceRange()),
|
sourceMgr, mee->getSourceRange()),
|
||||||
macroBufferRange,
|
macroBufferRange,
|
||||||
ASTNode(expr).getOpaqueValue(),
|
ASTNode(mee).getOpaqueValue(),
|
||||||
dc
|
dc
|
||||||
};
|
};
|
||||||
sourceMgr.setGeneratedSourceInfo(macroBufferID, sourceInfo);
|
sourceMgr.setGeneratedSourceInfo(macroBufferID, sourceInfo);
|
||||||
@@ -807,7 +837,7 @@ Expr *swift::expandMacroExpr(
|
|||||||
if (topLevelItems.size() != 1) {
|
if (topLevelItems.size() != 1) {
|
||||||
ctx.Diags.diagnose(
|
ctx.Diags.diagnose(
|
||||||
macroBufferRange.getStart(), diag::expected_macro_expansion_expr);
|
macroBufferRange.getStart(), diag::expected_macro_expansion_expr);
|
||||||
return nullptr;
|
return macroBufferID;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto codeItem = topLevelItems.front();
|
auto codeItem = topLevelItems.front();
|
||||||
@@ -817,7 +847,7 @@ Expr *swift::expandMacroExpr(
|
|||||||
if (!expandedExpr) {
|
if (!expandedExpr) {
|
||||||
ctx.Diags.diagnose(
|
ctx.Diags.diagnose(
|
||||||
macroBufferRange.getStart(), diag::expected_macro_expansion_expr);
|
macroBufferRange.getStart(), diag::expected_macro_expansion_expr);
|
||||||
return nullptr;
|
return macroBufferID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type-check the expanded expression.
|
// Type-check the expanded expression.
|
||||||
@@ -834,12 +864,15 @@ Expr *swift::expandMacroExpr(
|
|||||||
Type realExpandedType = TypeChecker::typeCheckExpression(
|
Type realExpandedType = TypeChecker::typeCheckExpression(
|
||||||
expandedExpr, dc, contextualType);
|
expandedExpr, dc, contextualType);
|
||||||
if (!realExpandedType)
|
if (!realExpandedType)
|
||||||
return nullptr;
|
return macroBufferID;
|
||||||
|
|
||||||
assert((expandedType->isEqual(realExpandedType) ||
|
assert((expandedType->isEqual(realExpandedType) ||
|
||||||
realExpandedType->hasError()) &&
|
realExpandedType->hasError()) &&
|
||||||
"Type checking changed the result type?");
|
"Type checking changed the result type?");
|
||||||
return expandedExpr;
|
|
||||||
|
mee->setRewritten(expandedExpr);
|
||||||
|
|
||||||
|
return macroBufferID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expands the given macro expansion declaration.
|
/// Expands the given macro expansion declaration.
|
||||||
|
|||||||
@@ -29,16 +29,15 @@ namespace swift {
|
|||||||
class CustomAttr;
|
class CustomAttr;
|
||||||
class Expr;
|
class Expr;
|
||||||
class MacroDecl;
|
class MacroDecl;
|
||||||
|
class MacroExpansionExpr;
|
||||||
class MacroExpansionDecl;
|
class MacroExpansionDecl;
|
||||||
class TypeRepr;
|
class TypeRepr;
|
||||||
|
|
||||||
/// Expands the given macro expression and type-check the result with
|
/// Expands the given macro expression and type-check the result with
|
||||||
/// the given expanded type.
|
/// the given expanded type.
|
||||||
///
|
///
|
||||||
/// \returns the type-checked replacement expression, or NULL if the
|
/// \returns Expansion buffer ID if expansion succeeded, \p None if failed.
|
||||||
// macro could not be expanded.
|
Optional<unsigned> expandMacroExpr(MacroExpansionExpr *mee);
|
||||||
Expr *expandMacroExpr(
|
|
||||||
DeclContext *dc, Expr *expr, ConcreteDeclRef macroRef, Type expandedType);
|
|
||||||
|
|
||||||
/// Expands the given macro expansion declaration.
|
/// Expands the given macro expansion declaration.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ macro anonymousTypes(_: () -> String) = #externalMacro(module: "MacroDefinition"
|
|||||||
|
|
||||||
#anonymousTypes { "hello" }
|
#anonymousTypes { "hello" }
|
||||||
|
|
||||||
|
// This should fails to typecheck because `#assert("foo")` is expanded to `assert("foo")`, but `assert(_:)` expects 'Bool' argument
|
||||||
|
@freestanding(expression) macro assert(_: String) = #externalMacro(module: "MacroDefinition", type: "AssertMacro")
|
||||||
|
#assert("foobar")
|
||||||
|
|
||||||
// REQUIRES: swift_swift_parser, executable_test, shell
|
// REQUIRES: swift_swift_parser, executable_test, shell
|
||||||
|
|
||||||
// RUN: %empty-directory(%t)
|
// RUN: %empty-directory(%t)
|
||||||
@@ -265,3 +269,6 @@ macro anonymousTypes(_: () -> String) = #externalMacro(module: "MacroDefinition"
|
|||||||
// RUN: %sourcekitd-test -req=format -line=23 -length=1 %s | %FileCheck -check-prefix=FORMATTED %s
|
// RUN: %sourcekitd-test -req=format -line=23 -length=1 %s | %FileCheck -check-prefix=FORMATTED %s
|
||||||
// FORMATTED: " var x: Int"
|
// FORMATTED: " var x: Int"
|
||||||
|
|
||||||
|
//##-- Expansion on "fails to typecheck" macro expression
|
||||||
|
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=61:2 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=ERRONEOUS_EXPAND %s
|
||||||
|
// ERRONEOUS_EXPAND: 61:1-61:18 (@__swiftmacro_9MacroUser6assertfMf_.swift) "assert("foobar")"
|
||||||
|
|||||||
Reference in New Issue
Block a user