Files
swift-mirror/lib/AST/FreestandingMacroExpansion.cpp
Doug Gregor b31133e67d Ensure that freestanding macros get consistent discriminators
Due to the duality between the expression and declaration forms of
freestanding macros, we could end up assigning two different discriminators
to what is effectively the same freestanding macro expansion. Across
different source files, this could lead to inconsistent discriminators in
different translation units. Unify the storage of the discriminator to
avoid this issue.

Fixes rdar://116259748
2024-01-11 08:18:28 -08:00

76 lines
2.7 KiB
C++

//===--- FreestandingMacroExpansion.cpp -----------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "swift/AST/FreestandingMacroExpansion.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/MacroDiscriminatorContext.h"
using namespace swift;
SourceRange MacroExpansionInfo::getSourceRange() const {
SourceLoc endLoc;
if (ArgList && !ArgList->isImplicit())
endLoc = ArgList->getEndLoc();
else if (RightAngleLoc.isValid())
endLoc = RightAngleLoc;
else
endLoc = MacroNameLoc.getEndLoc();
return SourceRange(SigilLoc, endLoc);
}
#define FORWARD_VARIANT(NAME) \
switch (getFreestandingMacroKind()) { \
case FreestandingMacroKind::Expr: \
return cast<MacroExpansionExpr>(this)->NAME(); \
case FreestandingMacroKind::Decl: \
return cast<MacroExpansionDecl>(this)->NAME(); \
}
DeclContext *FreestandingMacroExpansion::getDeclContext() const {
FORWARD_VARIANT(getDeclContext);
}
SourceRange FreestandingMacroExpansion::getSourceRange() const {
FORWARD_VARIANT(getSourceRange);
}
unsigned FreestandingMacroExpansion::getDiscriminator() const {
auto info = getExpansionInfo();
if (info->Discriminator != MacroExpansionInfo::InvalidDiscriminator)
return info->Discriminator;
auto mutableThis = const_cast<FreestandingMacroExpansion *>(this);
auto dc = getDeclContext();
ASTContext &ctx = dc->getASTContext();
auto discriminatorContext =
MacroDiscriminatorContext::getParentOf(mutableThis);
info->Discriminator = ctx.getNextMacroDiscriminator(
discriminatorContext, getMacroName().getBaseName());
assert(info->Discriminator != MacroExpansionInfo::InvalidDiscriminator);
return info->Discriminator;
}
unsigned FreestandingMacroExpansion::getRawDiscriminator() const {
return getExpansionInfo()->Discriminator;
}
ASTNode FreestandingMacroExpansion::getASTNode() {
switch (getFreestandingMacroKind()) {
case FreestandingMacroKind::Expr:
return cast<MacroExpansionExpr>(this);
case FreestandingMacroKind::Decl:
return cast<MacroExpansionDecl>(this);
}
}