@@ -148,15 +148,19 @@ MacroDefinition MacroDefinitionRequest::evaluate(
148148 BridgedStringRef externalMacroName{nullptr , 0 };
149149 ptrdiff_t *replacements = nullptr ;
150150 ptrdiff_t numReplacements = 0 ;
151+ ptrdiff_t *genericReplacements = nullptr ;
152+ ptrdiff_t numGenericReplacements = 0 ;
151153 auto checkResult = swift_ASTGen_checkMacroDefinition (
152154 &ctx.Diags , sourceFile->getExportedSourceFile (),
153155 macro->getLoc ().getOpaquePointerValue (), &externalMacroName,
154- &replacements, &numReplacements);
156+ &replacements, &numReplacements,
157+ &genericReplacements, &numGenericReplacements);
155158
156159 // Clean up after the call.
157160 SWIFT_DEFER {
158161 swift_ASTGen_freeBridgedString (externalMacroName);
159162 swift_ASTGen_freeExpansionReplacements (replacements, numReplacements);
163+ // swift_ASTGen_freeExpansionGenericReplacements(genericReplacements, numGenericReplacements); // FIXME: !!!!!!
160164 };
161165
162166 if (checkResult < 0 && ctx.CompletionCallback ) {
@@ -177,6 +181,7 @@ MacroDefinition MacroDefinitionRequest::evaluate(
177181 case BridgedExternalMacro: {
178182 // An external macro described as ModuleName.TypeName. Get both identifiers.
179183 assert (!replacements && " External macro doesn't have replacements" );
184+ assert (!genericReplacements && " External macro doesn't have genericReplacements" );
180185 StringRef externalMacroStr = externalMacroName.unbridged ();
181186 StringRef externalModuleName, externalTypeName;
182187 std::tie (externalModuleName, externalTypeName) = externalMacroStr.split (' .' );
@@ -232,8 +237,16 @@ MacroDefinition MacroDefinitionRequest::evaluate(
232237 static_cast <unsigned >(replacements[3 *i+1 ]),
233238 static_cast <unsigned >(replacements[3 *i+2 ])});
234239 }
240+ // Copy over the genericReplacements.
241+ SmallVector<ExpandedMacroReplacement, 2 > genericReplacementsVec;
242+ for (unsigned i: range (0 , numGenericReplacements)) {
243+ genericReplacementsVec.push_back (
244+ { static_cast <unsigned >(genericReplacements[3 *i]),
245+ static_cast <unsigned >(genericReplacements[3 *i+1 ]),
246+ static_cast <unsigned >(genericReplacements[3 *i+2 ])});
247+ }
235248
236- return MacroDefinition::forExpanded (ctx, expansionText, replacementsVec);
249+ return MacroDefinition::forExpanded (ctx, expansionText, replacementsVec, genericReplacementsVec );
237250#else
238251 macro->diagnose (diag::macro_unsupported);
239252 return MacroDefinition::forInvalid ();
@@ -781,24 +794,68 @@ static bool isFromExpansionOfMacro(SourceFile *sourceFile, MacroDecl *macro,
781794
782795// / Expand a macro definition.
783796static std::string expandMacroDefinition (
784- ExpandedMacroDefinition def, MacroDecl *macro, ArgumentList *args) {
797+ ExpandedMacroDefinition def, MacroDecl *macro,
798+ SubstitutionMap subs,
799+ ArgumentList *args) {
785800 ASTContext &ctx = macro->getASTContext ();
786801
787802 std::string expandedResult;
788803
789804 StringRef originalText = def.getExpansionText ();
805+
790806 unsigned startIdx = 0 ;
791- for (const auto replacement: def.getReplacements ()) {
807+ unsigned replacementsIdx = 0 ;
808+ unsigned genericReplacementsIdx = 0 ;
809+ auto totalReplacementsCount =
810+ def.getReplacements ().size () + def.getGenericReplacements ().size ();
811+
812+ while (replacementsIdx + genericReplacementsIdx < totalReplacementsCount) {
813+ ExpandedMacroReplacement replacement;
814+ bool isExpressionReplacement = true ;
815+
816+ // Pick the "next" replacement, in order as they appear in the source text
817+ auto canPickExpressionReplacement = replacementsIdx < def.getReplacements ().size ();
818+ auto canPickGenericReplacement = genericReplacementsIdx < def.getGenericReplacements ().size ();
819+ if (canPickExpressionReplacement && canPickGenericReplacement) {
820+ auto expressionReplacement = def.getReplacements ()[replacementsIdx];
821+ auto genericReplacement =
822+ def.getGenericReplacements ()[genericReplacementsIdx];
823+ isExpressionReplacement =
824+ expressionReplacement.startOffset < genericReplacement.startOffset ;
825+ replacement =
826+ isExpressionReplacement ? expressionReplacement : genericReplacement;
827+ } else if (canPickExpressionReplacement) {
828+ isExpressionReplacement = true ;
829+ replacement = def.getReplacements ()[replacementsIdx];
830+ } else if (canPickGenericReplacement) {
831+ isExpressionReplacement = false ;
832+ replacement = def.getGenericReplacements ()[replacementsIdx];
833+ } else {
834+ assert (false && " should always select a requirement explicitly rather "
835+ " than fall through" );
836+ }
837+
838+ replacementsIdx += isExpressionReplacement ? 1 : 0 ;
839+ genericReplacementsIdx += isExpressionReplacement ? 0 : 1 ;
840+
792841 // Add the original text up to the first replacement.
793- expandedResult.append (
794- originalText.begin () + startIdx,
795- originalText.begin () + replacement.startOffset );
842+ expandedResult.append (originalText.begin () + startIdx,
843+ originalText.begin () + replacement.startOffset );
796844
797845 // Add the replacement text.
798- auto argExpr = args->getArgExprs ()[replacement.parameterIndex ];
799- SmallString<32 > argTextBuffer;
800- auto argText = extractInlinableText (ctx.SourceMgr , argExpr, argTextBuffer);
801- expandedResult.append (argText);
846+ if (isExpressionReplacement) {
847+ auto argExpr = args->getArgExprs ()[replacement.parameterIndex ];
848+ SmallString<32 > argTextBuffer;
849+ auto argText =
850+ extractInlinableText (ctx.SourceMgr , argExpr, argTextBuffer);
851+ expandedResult.append (argText);
852+ } else {
853+ auto typeArgType = subs.getReplacementTypes ()[replacement.parameterIndex ];
854+ std::string typeNameString;
855+ llvm::raw_string_ostream os (typeNameString);
856+ typeArgType.print (os);
857+ expandedResult.append (typeNameString);
858+ }
802859
803860 // Update the starting position.
804861 startIdx = replacement.endOffset ;
@@ -1093,6 +1150,7 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion,
10931150 case MacroDefinition::Kind::Expanded: {
10941151 // Expand the definition with the given arguments.
10951152 auto result = expandMacroDefinition (macroDef.getExpanded (), macro,
1153+ expansion->getMacroRef ().getSubstitutions (),
10961154 expansion->getArgs ());
10971155 evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy (
10981156 result, adjustMacroExpansionBufferName (*discriminator));
@@ -1397,7 +1455,9 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo,
13971455 case MacroDefinition::Kind::Expanded: {
13981456 // Expand the definition with the given arguments.
13991457 auto result = expandMacroDefinition (
1400- macroDef.getExpanded (), macro, attr->getArgs ());
1458+ macroDef.getExpanded (), macro,
1459+ /* genericArgs=*/ {}, // attached macros don't have generic parameters
1460+ attr->getArgs ());
14011461 evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy (
14021462 result, adjustMacroExpansionBufferName (*discriminator));
14031463 break ;
0 commit comments