forked from OSchip/llvm-project
[modules] Stop trying to fake up a linear MacroDirective history.
Modules builds fundamentally have a non-linear macro history. In the interest of better source fidelity, represent the macro definition information faithfully: we have a linear macro directive history within each module, and at any point we have a unique "latest" local macro directive and a collection of visible imported directives. This also removes the attendent complexity of attempting to create a correct MacroDirective history (which we got wrong in the general case). No functionality change intended. llvm-svn: 236176
This commit is contained in:
parent
bf0a42ac09
commit
20e883e59b
|
@ -216,6 +216,9 @@ public:
|
|||
/// of that name in objective-c.
|
||||
StringRef GetNSIntegralKind(QualType T) const;
|
||||
|
||||
/// \brief Returns \c true if \p Id is currently defined as a macro.
|
||||
bool isMacroDefined(StringRef Id) const;
|
||||
|
||||
private:
|
||||
bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
|
||||
bool isObjCEnumerator(const Expr *E,
|
||||
|
|
|
@ -124,6 +124,7 @@ public:
|
|||
}
|
||||
|
||||
/// \brief Return true if this identifier is \#defined to some other value.
|
||||
/// \note The current definition may be in a module and not currently visible.
|
||||
bool hasMacroDefinition() const {
|
||||
return HasMacro;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ class FileEntry;
|
|||
class FileManager;
|
||||
class HeaderSearchOptions;
|
||||
class IdentifierInfo;
|
||||
class Preprocessor;
|
||||
|
||||
/// \brief The preprocessor keeps track of this information for each
|
||||
/// file that is \#included.
|
||||
|
@ -419,8 +420,8 @@ public:
|
|||
///
|
||||
/// \return false if \#including the file will have no effect or true
|
||||
/// if we should include it.
|
||||
bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
|
||||
|
||||
bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
|
||||
bool isImport);
|
||||
|
||||
/// \brief Return whether the specified file is a normal header,
|
||||
/// a system header, or a C++ friendly system header.
|
||||
|
|
|
@ -386,7 +386,8 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
|
|||
class MacroState {
|
||||
mutable llvm::PointerUnion<MacroDirective *, ModuleMacroInfo *> State;
|
||||
|
||||
ModuleMacroInfo *getModuleInfo(Preprocessor &PP, IdentifierInfo *II) const {
|
||||
ModuleMacroInfo *getModuleInfo(Preprocessor &PP,
|
||||
const IdentifierInfo *II) const {
|
||||
// FIXME: Find a spare bit on IdentifierInfo and store a
|
||||
// HasModuleMacros flag.
|
||||
if (!II->hasMacroDefinition() || !PP.getLangOpts().Modules ||
|
||||
|
@ -434,12 +435,12 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
|
|||
State = MD;
|
||||
}
|
||||
|
||||
bool isAmbiguous(Preprocessor &PP, IdentifierInfo *II) const {
|
||||
bool isAmbiguous(Preprocessor &PP, const IdentifierInfo *II) const {
|
||||
auto *Info = getModuleInfo(PP, II);
|
||||
return Info ? Info->IsAmbiguous : false;
|
||||
}
|
||||
ArrayRef<ModuleMacro *> getActiveModuleMacros(Preprocessor &PP,
|
||||
IdentifierInfo *II) const {
|
||||
ArrayRef<ModuleMacro *>
|
||||
getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const {
|
||||
if (auto *Info = getModuleInfo(PP, II))
|
||||
return Info->ActiveModuleMacros;
|
||||
return None;
|
||||
|
@ -755,33 +756,119 @@ public:
|
|||
}
|
||||
/// \}
|
||||
|
||||
/// \brief Given an identifier, return its latest MacroDirective if it is
|
||||
/// \#defined or null if it isn't \#define'd.
|
||||
MacroDirective *getMacroDirective(IdentifierInfo *II) const {
|
||||
/// \brief A description of the current definition of a macro.
|
||||
class MacroDefinition {
|
||||
llvm::PointerIntPair<DefMacroDirective*, 1, bool> LatestLocalAndAmbiguous;
|
||||
ArrayRef<ModuleMacro*> ModuleMacros;
|
||||
public:
|
||||
MacroDefinition() : LatestLocalAndAmbiguous(), ModuleMacros() {}
|
||||
MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs,
|
||||
bool IsAmbiguous)
|
||||
: LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {}
|
||||
|
||||
/// \brief Determine whether there is a definition of this macro.
|
||||
explicit operator bool() const {
|
||||
return getLocalDirective() || !ModuleMacros.empty();
|
||||
}
|
||||
|
||||
/// \brief Get the MacroInfo that should be used for this definition.
|
||||
MacroInfo *getMacroInfo() const {
|
||||
if (!ModuleMacros.empty())
|
||||
return ModuleMacros.back()->getMacroInfo();
|
||||
if (auto *MD = getLocalDirective())
|
||||
return MD->getMacroInfo();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// \brief \c true if the definition is ambiguous, \c false otherwise.
|
||||
bool isAmbiguous() const { return LatestLocalAndAmbiguous.getInt(); }
|
||||
|
||||
/// \brief Get the latest non-imported, non-\#undef'd macro definition
|
||||
/// for this macro.
|
||||
DefMacroDirective *getLocalDirective() const {
|
||||
return LatestLocalAndAmbiguous.getPointer();
|
||||
}
|
||||
|
||||
/// \brief Get the active module macros for this macro.
|
||||
ArrayRef<ModuleMacro *> getModuleMacros() const {
|
||||
return ModuleMacros;
|
||||
}
|
||||
|
||||
template<typename Fn> void forAllDefinitions(Fn F) const {
|
||||
if (auto *MD = getLocalDirective())
|
||||
F(MD->getMacroInfo());
|
||||
for (auto *MM : getModuleMacros())
|
||||
F(MM->getMacroInfo());
|
||||
}
|
||||
};
|
||||
|
||||
bool isMacroDefined(StringRef Id) {
|
||||
return isMacroDefined(&Identifiers.get(Id));
|
||||
}
|
||||
bool isMacroDefined(const IdentifierInfo *II) {
|
||||
return II->hasMacroDefinition() &&
|
||||
(!getLangOpts().Modules || (bool)getMacroDefinition(II));
|
||||
}
|
||||
|
||||
MacroDefinition getMacroDefinition(const IdentifierInfo *II) {
|
||||
if (!II->hasMacroDefinition())
|
||||
return MacroDefinition();
|
||||
|
||||
MacroState &S = Macros[II];
|
||||
auto *MD = S.getLatest();
|
||||
while (MD && isa<VisibilityMacroDirective>(MD))
|
||||
MD = MD->getPrevious();
|
||||
return MacroDefinition(dyn_cast_or_null<DefMacroDirective>(MD),
|
||||
S.getActiveModuleMacros(*this, II),
|
||||
S.isAmbiguous(*this, II));
|
||||
}
|
||||
|
||||
MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II,
|
||||
SourceLocation Loc) {
|
||||
if (!II->hadMacroDefinition())
|
||||
return MacroDefinition();
|
||||
|
||||
MacroState &S = Macros[II];
|
||||
MacroDirective::DefInfo DI;
|
||||
if (auto *MD = S.getLatest())
|
||||
DI = MD->findDirectiveAtLoc(Loc, getSourceManager());
|
||||
// FIXME: Compute the set of active module macros at the specified location.
|
||||
return MacroDefinition(DI.getDirective(),
|
||||
S.getActiveModuleMacros(*this, II),
|
||||
S.isAmbiguous(*this, II));
|
||||
}
|
||||
|
||||
/// \brief Given an identifier, return its latest non-imported MacroDirective
|
||||
/// if it is \#define'd and not \#undef'd, or null if it isn't \#define'd.
|
||||
MacroDirective *getLocalMacroDirective(const IdentifierInfo *II) const {
|
||||
if (!II->hasMacroDefinition())
|
||||
return nullptr;
|
||||
|
||||
MacroDirective *MD = getMacroDirectiveHistory(II);
|
||||
assert(MD->isDefined() && "Macro is undefined!");
|
||||
auto *MD = getLocalMacroDirectiveHistory(II);
|
||||
if (!MD || MD->getDefinition().isUndefined())
|
||||
return nullptr;
|
||||
|
||||
return MD;
|
||||
}
|
||||
|
||||
const MacroInfo *getMacroInfo(IdentifierInfo *II) const {
|
||||
const MacroInfo *getMacroInfo(const IdentifierInfo *II) const {
|
||||
return const_cast<Preprocessor*>(this)->getMacroInfo(II);
|
||||
}
|
||||
|
||||
MacroInfo *getMacroInfo(IdentifierInfo *II) {
|
||||
if (MacroDirective *MD = getMacroDirective(II))
|
||||
return MD->getMacroInfo();
|
||||
MacroInfo *getMacroInfo(const IdentifierInfo *II) {
|
||||
if (!II->hasMacroDefinition())
|
||||
return nullptr;
|
||||
if (auto MD = getMacroDefinition(II))
|
||||
return MD.getMacroInfo();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// \brief Given an identifier, return the (probably #undef'd) MacroInfo
|
||||
/// representing the most recent macro definition.
|
||||
/// \brief Given an identifier, return the latest non-imported macro
|
||||
/// directive for that identifier.
|
||||
///
|
||||
/// One can iterate over all previous macro definitions from the most recent
|
||||
/// one. This should only be called for identifiers that hadMacroDefinition().
|
||||
MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
|
||||
/// One can iterate over all previous macro directives from the most recent
|
||||
/// one.
|
||||
MacroDirective *getLocalMacroDirectiveHistory(const IdentifierInfo *II) const;
|
||||
|
||||
/// \brief Add a directive to the macro directive history for this identifier.
|
||||
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
|
||||
|
@ -1580,7 +1667,7 @@ private:
|
|||
|
||||
/// Update the set of active module macros and ambiguity flag for a module
|
||||
/// macro name.
|
||||
void updateModuleMacroInfo(IdentifierInfo *II, ModuleMacroInfo &Info);
|
||||
void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info);
|
||||
|
||||
/// \brief Allocate a new MacroInfo object.
|
||||
MacroInfo *AllocateMacroInfo();
|
||||
|
@ -1644,7 +1731,7 @@ private:
|
|||
/// If an identifier token is read that is to be expanded as a macro, handle
|
||||
/// it and return the next token as 'Tok'. If we lexed a token, return true;
|
||||
/// otherwise the caller should lex again.
|
||||
bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD);
|
||||
bool HandleMacroExpandedIdentifier(Token &Tok, const MacroDefinition &MD);
|
||||
|
||||
/// \brief Cache macro expanded tokens for TokenLexers.
|
||||
//
|
||||
|
|
|
@ -576,54 +576,8 @@ private:
|
|||
/// global submodule ID to produce a local ID.
|
||||
GlobalSubmoduleMapType GlobalSubmoduleMap;
|
||||
|
||||
/// \brief Information on a macro definition or undefinition that is visible
|
||||
/// at the end of a submodule.
|
||||
struct ModuleMacroInfo;
|
||||
|
||||
/// \brief An entity that has been hidden.
|
||||
class HiddenName {
|
||||
public:
|
||||
enum NameKind {
|
||||
Declaration,
|
||||
Macro
|
||||
} Kind;
|
||||
|
||||
private:
|
||||
union {
|
||||
Decl *D;
|
||||
ModuleMacroInfo *MMI;
|
||||
};
|
||||
|
||||
IdentifierInfo *Id;
|
||||
|
||||
public:
|
||||
HiddenName(Decl *D) : Kind(Declaration), D(D), Id() { }
|
||||
|
||||
HiddenName(IdentifierInfo *II, ModuleMacroInfo *MMI)
|
||||
: Kind(Macro), MMI(MMI), Id(II) { }
|
||||
|
||||
NameKind getKind() const { return Kind; }
|
||||
|
||||
Decl *getDecl() const {
|
||||
assert(getKind() == Declaration && "Hidden name is not a declaration");
|
||||
return D;
|
||||
}
|
||||
|
||||
std::pair<IdentifierInfo *, ModuleMacroInfo *> getMacro() const {
|
||||
assert(getKind() == Macro && "Hidden name is not a macro!");
|
||||
return std::make_pair(Id, MMI);
|
||||
}
|
||||
};
|
||||
|
||||
typedef llvm::SmallDenseMap<IdentifierInfo*,
|
||||
ModuleMacroInfo*> HiddenMacrosMap;
|
||||
|
||||
/// \brief A set of hidden declarations.
|
||||
struct HiddenNames {
|
||||
SmallVector<Decl*, 2> HiddenDecls;
|
||||
HiddenMacrosMap HiddenMacros;
|
||||
};
|
||||
|
||||
typedef SmallVector<Decl*, 2> HiddenNames;
|
||||
typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
|
||||
|
||||
/// \brief A mapping from each of the hidden submodules to the deserialized
|
||||
|
@ -1850,20 +1804,6 @@ public:
|
|||
|
||||
void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
|
||||
|
||||
void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo &MMI,
|
||||
Module *Owner);
|
||||
|
||||
typedef llvm::TinyPtrVector<DefMacroDirective *> AmbiguousMacros;
|
||||
llvm::DenseMap<IdentifierInfo*, AmbiguousMacros> AmbiguousMacroDefs;
|
||||
|
||||
void removeOverriddenMacros(IdentifierInfo *II, SourceLocation Loc,
|
||||
AmbiguousMacros &Ambig,
|
||||
ArrayRef<ModuleMacro *> Overrides);
|
||||
|
||||
AmbiguousMacros *removeOverriddenMacros(IdentifierInfo *II,
|
||||
SourceLocation Loc,
|
||||
ArrayRef<ModuleMacro *> Overrides);
|
||||
|
||||
/// \brief Retrieve the macro with the given ID.
|
||||
MacroInfo *getMacro(serialization::MacroID ID);
|
||||
|
||||
|
|
|
@ -468,7 +468,7 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter,
|
|||
ASTContext &Context = NS.getASTContext();
|
||||
bool LParenAdded = false;
|
||||
std::string PropertyString = "@property ";
|
||||
if (UseNsIosOnlyMacro && Context.Idents.get("NS_NONATOMIC_IOSONLY").hasMacroDefinition()) {
|
||||
if (UseNsIosOnlyMacro && NS.isMacroDefined("NS_NONATOMIC_IOSONLY")) {
|
||||
PropertyString += "(NS_NONATOMIC_IOSONLY";
|
||||
LParenAdded = true;
|
||||
} else if (!Atomic) {
|
||||
|
@ -1277,7 +1277,7 @@ void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx,
|
|||
|
||||
QualType RT = OM->getReturnType();
|
||||
if (!TypeIsInnerPointer(RT) ||
|
||||
!Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
|
||||
!NSAPIObj->isMacroDefined("NS_RETURNS_INNER_POINTER"))
|
||||
return;
|
||||
|
||||
edit::Commit commit(*Editor);
|
||||
|
@ -1288,9 +1288,9 @@ void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx,
|
|||
void ObjCMigrateASTConsumer::migratePropertyNsReturnsInnerPointer(ASTContext &Ctx,
|
||||
ObjCPropertyDecl *P) {
|
||||
QualType T = P->getType();
|
||||
|
||||
|
||||
if (!TypeIsInnerPointer(T) ||
|
||||
!Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
|
||||
!NSAPIObj->isMacroDefined("NS_RETURNS_INNER_POINTER"))
|
||||
return;
|
||||
edit::Commit commit(*Editor);
|
||||
commit.insertBefore(P->getLocEnd(), " NS_RETURNS_INNER_POINTER ");
|
||||
|
@ -1408,7 +1408,7 @@ static bool AuditedType (QualType AT) {
|
|||
void ObjCMigrateASTConsumer::AnnotateImplicitBridging(ASTContext &Ctx) {
|
||||
if (CFFunctionIBCandidates.empty())
|
||||
return;
|
||||
if (!Ctx.Idents.get("CF_IMPLICIT_BRIDGING_ENABLED").hasMacroDefinition()) {
|
||||
if (!NSAPIObj->isMacroDefined("CF_IMPLICIT_BRIDGING_ENABLED")) {
|
||||
CFFunctionIBCandidates.clear();
|
||||
FileId = FileID();
|
||||
return;
|
||||
|
@ -1483,16 +1483,14 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
|
|||
RetEffect Ret = CE.getReturnValue();
|
||||
const char *AnnotationString = nullptr;
|
||||
if (Ret.getObjKind() == RetEffect::CF) {
|
||||
if (Ret.isOwned() &&
|
||||
Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
|
||||
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
|
||||
AnnotationString = " CF_RETURNS_RETAINED";
|
||||
else if (Ret.notOwned() &&
|
||||
Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition())
|
||||
NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
|
||||
AnnotationString = " CF_RETURNS_NOT_RETAINED";
|
||||
}
|
||||
else if (Ret.getObjKind() == RetEffect::ObjC) {
|
||||
if (Ret.isOwned() &&
|
||||
Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
|
||||
if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED"))
|
||||
AnnotationString = " NS_RETURNS_RETAINED";
|
||||
}
|
||||
|
||||
|
@ -1509,13 +1507,13 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
|
|||
const ParmVarDecl *pd = *pi;
|
||||
ArgEffect AE = AEArgs[i];
|
||||
if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
|
||||
Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
|
||||
NSAPIObj->isMacroDefined("CF_CONSUMED")) {
|
||||
edit::Commit commit(*Editor);
|
||||
commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
|
||||
Editor->commit(commit);
|
||||
}
|
||||
else if (AE == DecRefMsg && !pd->hasAttr<NSConsumedAttr>() &&
|
||||
Ctx.Idents.get("NS_CONSUMED").hasMacroDefinition()) {
|
||||
NSAPIObj->isMacroDefined("NS_CONSUMED")) {
|
||||
edit::Commit commit(*Editor);
|
||||
commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
|
||||
Editor->commit(commit);
|
||||
|
@ -1600,11 +1598,10 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
|
|||
RetEffect Ret = CE.getReturnValue();
|
||||
const char *AnnotationString = nullptr;
|
||||
if (Ret.getObjKind() == RetEffect::CF) {
|
||||
if (Ret.isOwned() &&
|
||||
Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
|
||||
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
|
||||
AnnotationString = " CF_RETURNS_RETAINED";
|
||||
else if (Ret.notOwned() &&
|
||||
Ctx.Idents.get("CF_RETURNS_NOT_RETAINED").hasMacroDefinition())
|
||||
NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
|
||||
AnnotationString = " CF_RETURNS_NOT_RETAINED";
|
||||
}
|
||||
else if (Ret.getObjKind() == RetEffect::ObjC) {
|
||||
|
@ -1618,8 +1615,7 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
|
|||
break;
|
||||
|
||||
default:
|
||||
if (Ret.isOwned() &&
|
||||
Ctx.Idents.get("NS_RETURNS_RETAINED").hasMacroDefinition())
|
||||
if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED"))
|
||||
AnnotationString = " NS_RETURNS_RETAINED";
|
||||
break;
|
||||
}
|
||||
|
@ -1638,7 +1634,7 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
|
|||
const ParmVarDecl *pd = *pi;
|
||||
ArgEffect AE = AEArgs[i];
|
||||
if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
|
||||
Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
|
||||
NSAPIObj->isMacroDefined("CF_CONSUMED")) {
|
||||
edit::Commit commit(*Editor);
|
||||
commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
|
||||
Editor->commit(commit);
|
||||
|
@ -1658,12 +1654,12 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
|
|||
MethodDecl->hasAttr<NSReturnsRetainedAttr>() ||
|
||||
MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
|
||||
MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
|
||||
|
||||
if (CE.getReceiver() == DecRefMsg &&
|
||||
|
||||
if (CE.getReceiver() == DecRefMsg &&
|
||||
!MethodDecl->hasAttr<NSConsumesSelfAttr>() &&
|
||||
MethodDecl->getMethodFamily() != OMF_init &&
|
||||
MethodDecl->getMethodFamily() != OMF_release &&
|
||||
Ctx.Idents.get("NS_CONSUMES_SELF").hasMacroDefinition()) {
|
||||
NSAPIObj->isMacroDefined("NS_CONSUMES_SELF")) {
|
||||
edit::Commit commit(*Editor);
|
||||
commit.insertBefore(MethodDecl->getLocEnd(), " NS_CONSUMES_SELF");
|
||||
Editor->commit(commit);
|
||||
|
@ -1729,7 +1725,7 @@ void ObjCMigrateASTConsumer::inferDesignatedInitializers(
|
|||
const ObjCInterfaceDecl *IFace = ImplD->getClassInterface();
|
||||
if (!IFace || IFace->hasDesignatedInitializers())
|
||||
return;
|
||||
if (!Ctx.Idents.get("NS_DESIGNATED_INITIALIZER").hasMacroDefinition())
|
||||
if (!NSAPIObj->isMacroDefined("NS_DESIGNATED_INITIALIZER"))
|
||||
return;
|
||||
|
||||
for (const auto *MD : ImplD->instance_methods()) {
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
Pass.TA.clearDiagnostic(diag::err_unavailable,
|
||||
diag::err_unavailable_message,
|
||||
E->getSelectorLoc(0));
|
||||
Pass.TA.replace(E->getSourceRange(), getNilString(Pass.Ctx));
|
||||
Pass.TA.replace(E->getSourceRange(), getNilString(Pass));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ public:
|
|||
// when an exception is thrown.
|
||||
Pass.TA.replace(RecContainer->getSourceRange(), RecRange);
|
||||
std::string str = " = ";
|
||||
str += getNilString(Pass.Ctx);
|
||||
str += getNilString(Pass);
|
||||
Pass.TA.insertAfterToken(RecRange.getEnd(), str);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
SourceRange ExprRange = ME->getSourceRange();
|
||||
Pass.TA.insert(ExprRange.getBegin(), "if (!(self = ");
|
||||
std::string retStr = ")) return ";
|
||||
retStr += getNilString(Pass.Ctx);
|
||||
retStr += getNilString(Pass);
|
||||
Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Sema/Sema.h"
|
||||
#include "clang/Sema/SemaDiagnostic.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
|
@ -212,11 +213,8 @@ bool trans::isGlobalVar(Expr *E) {
|
|||
return false;
|
||||
}
|
||||
|
||||
StringRef trans::getNilString(ASTContext &Ctx) {
|
||||
if (Ctx.Idents.get("nil").hasMacroDefinition())
|
||||
return "nil";
|
||||
else
|
||||
return "0";
|
||||
StringRef trans::getNilString(MigrationPass &Pass) {
|
||||
return Pass.SemaRef.PP.isMacroDefined("nil") ? "nil" : "0";
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -180,7 +180,7 @@ SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx,
|
|||
bool hasSideEffects(Expr *E, ASTContext &Ctx);
|
||||
bool isGlobalVar(Expr *E);
|
||||
/// \brief Returns "nil" or "0" if 'nil' macro is not actually defined.
|
||||
StringRef getNilString(ASTContext &Ctx);
|
||||
StringRef getNilString(MigrationPass &Pass);
|
||||
|
||||
template <typename BODY_TRANS>
|
||||
class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
|
||||
|
|
|
@ -505,6 +505,11 @@ StringRef NSAPI::GetNSIntegralKind(QualType T) const {
|
|||
return StringRef();
|
||||
}
|
||||
|
||||
bool NSAPI::isMacroDefined(StringRef Id) const {
|
||||
// FIXME: Check whether the relevant module macros are visible.
|
||||
return Ctx.Idents.get(Id).hasMacroDefinition();
|
||||
}
|
||||
|
||||
bool NSAPI::isObjCTypedef(QualType T,
|
||||
StringRef name, IdentifierInfo *&II) const {
|
||||
if (!Ctx.getLangOpts().ObjC1)
|
||||
|
|
|
@ -1084,79 +1084,51 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
|
|||
// not have changed.
|
||||
if (!Id->hadMacroDefinition())
|
||||
return;
|
||||
auto *LatestLocalMD = PP.getLocalMacroDirectiveHistory(Id);
|
||||
|
||||
// If this identifier does not currently have a macro definition,
|
||||
// check whether it had one on the command line.
|
||||
if (!Id->hasMacroDefinition()) {
|
||||
MacroDirective::DefInfo LatestDef =
|
||||
PP.getMacroDirectiveHistory(Id)->getDefinition();
|
||||
for (MacroDirective::DefInfo Def = LatestDef; Def;
|
||||
Def = Def.getPreviousDefinition()) {
|
||||
FileID FID = SourceMgr.getFileID(Def.getLocation());
|
||||
if (FID.isInvalid())
|
||||
continue;
|
||||
|
||||
// We only care about the predefines buffer.
|
||||
if (FID != PP.getPredefinesFileID())
|
||||
continue;
|
||||
|
||||
// This macro was defined on the command line, then #undef'd later.
|
||||
// Complain.
|
||||
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
|
||||
<< true << ConfigMacro << Mod->getFullModuleName();
|
||||
if (LatestDef.isUndefined())
|
||||
PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
|
||||
<< true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Okay: no definition in the predefines buffer.
|
||||
return;
|
||||
}
|
||||
|
||||
// This identifier has a macro definition. Check whether we had a definition
|
||||
// on the command line.
|
||||
MacroDirective::DefInfo LatestDef =
|
||||
PP.getMacroDirectiveHistory(Id)->getDefinition();
|
||||
MacroDirective::DefInfo PredefinedDef;
|
||||
for (MacroDirective::DefInfo Def = LatestDef; Def;
|
||||
Def = Def.getPreviousDefinition()) {
|
||||
FileID FID = SourceMgr.getFileID(Def.getLocation());
|
||||
if (FID.isInvalid())
|
||||
continue;
|
||||
|
||||
// Find the macro definition from the command line.
|
||||
MacroInfo *CmdLineDefinition = nullptr;
|
||||
for (auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {
|
||||
// We only care about the predefines buffer.
|
||||
if (FID != PP.getPredefinesFileID())
|
||||
FileID FID = SourceMgr.getFileID(MD->getLocation());
|
||||
if (FID.isInvalid() || FID != PP.getPredefinesFileID())
|
||||
continue;
|
||||
|
||||
PredefinedDef = Def;
|
||||
if (auto *DMD = dyn_cast<DefMacroDirective>(MD))
|
||||
CmdLineDefinition = DMD->getMacroInfo();
|
||||
break;
|
||||
}
|
||||
|
||||
// If there was no definition for this macro in the predefines buffer,
|
||||
// complain.
|
||||
if (!PredefinedDef ||
|
||||
(!PredefinedDef.getLocation().isValid() &&
|
||||
PredefinedDef.getUndefLocation().isValid())) {
|
||||
auto *CurrentDefinition = PP.getMacroInfo(Id);
|
||||
if (CurrentDefinition == CmdLineDefinition) {
|
||||
// Macro matches. Nothing to do.
|
||||
} else if (!CurrentDefinition) {
|
||||
// This macro was defined on the command line, then #undef'd later.
|
||||
// Complain.
|
||||
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
|
||||
<< true << ConfigMacro << Mod->getFullModuleName();
|
||||
auto LatestDef = LatestLocalMD->getDefinition();
|
||||
assert(LatestDef.isUndefined() &&
|
||||
"predefined macro went away with no #undef?");
|
||||
PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
|
||||
<< true;
|
||||
return;
|
||||
} else if (!CmdLineDefinition) {
|
||||
// There was no definition for this macro in the predefines buffer,
|
||||
// but there was a local definition. Complain.
|
||||
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
|
||||
<< false << ConfigMacro << Mod->getFullModuleName();
|
||||
PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
|
||||
PP.Diag(CurrentDefinition->getDefinitionLoc(),
|
||||
diag::note_module_def_undef_here)
|
||||
<< false;
|
||||
} else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
|
||||
/*Syntactically=*/true)) {
|
||||
// The macro definitions differ.
|
||||
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
|
||||
<< false << ConfigMacro << Mod->getFullModuleName();
|
||||
PP.Diag(CurrentDefinition->getDefinitionLoc(),
|
||||
diag::note_module_def_undef_here)
|
||||
<< false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the current macro definition is the same as the predefined macro
|
||||
// definition, it's okay.
|
||||
if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() ||
|
||||
LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP,
|
||||
/*Syntactically=*/true))
|
||||
return;
|
||||
|
||||
// The macro definitions differ.
|
||||
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
|
||||
<< false << ConfigMacro << Mod->getFullModuleName();
|
||||
PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
|
||||
<< false;
|
||||
}
|
||||
|
||||
/// \brief Write a new timestamp file with the given path.
|
||||
|
|
|
@ -686,9 +686,9 @@ static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) {
|
|||
SmallVector<id_macro_pair, 128> MacrosByID;
|
||||
for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
|
||||
I != E; ++I) {
|
||||
if (I->first->hasMacroDefinition())
|
||||
MacrosByID.push_back(
|
||||
id_macro_pair(I->first, I->second.getLatest()->getMacroInfo()));
|
||||
auto *MD = I->second.getLatest();
|
||||
if (MD && MD->isDefined())
|
||||
MacrosByID.push_back(id_macro_pair(I->first, MD->getMacroInfo()));
|
||||
}
|
||||
llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "clang/Lex/HeaderSearchOptions.h"
|
||||
#include "clang/Lex/LexDiagnostic.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
|
@ -1016,7 +1017,9 @@ void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
|
|||
HFI.setHeaderRole(Role);
|
||||
}
|
||||
|
||||
bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
|
||||
bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
|
||||
const FileEntry *File,
|
||||
bool isImport) {
|
||||
++NumIncluded; // Count # of attempted #includes.
|
||||
|
||||
// Get information about this file.
|
||||
|
@ -1041,7 +1044,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
|
|||
// if the macro that guards it is defined, we know the #include has no effect.
|
||||
if (const IdentifierInfo *ControllingMacro
|
||||
= FileInfo.getControllingMacro(ExternalLookup))
|
||||
if (ControllingMacro->hasMacroDefinition()) {
|
||||
if (PP.isMacroDefined(ControllingMacro)) {
|
||||
++NumMultiIncludeFileOptzn;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -133,12 +133,11 @@ bool MacroArgs::ArgNeedsPreexpansion(const Token *ArgTok,
|
|||
// If there are no identifiers in the argument list, or if the identifiers are
|
||||
// known to not be macros, pre-expansion won't modify it.
|
||||
for (; ArgTok->isNot(tok::eof); ++ArgTok)
|
||||
if (IdentifierInfo *II = ArgTok->getIdentifierInfo()) {
|
||||
if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled())
|
||||
if (IdentifierInfo *II = ArgTok->getIdentifierInfo())
|
||||
if (II->hasMacroDefinition())
|
||||
// Return true even though the macro could be a function-like macro
|
||||
// without a following '(' token.
|
||||
// without a following '(' token, or could be disabled, or not visible.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -179,11 +179,13 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
|
|||
return Diag(MacroNameTok, diag::err_defined_macro_name);
|
||||
}
|
||||
|
||||
if (isDefineUndef == MU_Undef && II->hasMacroDefinition() &&
|
||||
getMacroInfo(II)->isBuiltinMacro()) {
|
||||
// Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4
|
||||
// and C++ [cpp.predefined]p4], but allow it as an extension.
|
||||
Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
|
||||
if (isDefineUndef == MU_Undef) {
|
||||
auto *MI = getMacroInfo(II);
|
||||
if (MI && MI->isBuiltinMacro()) {
|
||||
// Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4
|
||||
// and C++ [cpp.predefined]p4], but allow it as an extension.
|
||||
Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
|
||||
}
|
||||
}
|
||||
|
||||
// If defining/undefining reserved identifier or a keyword, we need to issue
|
||||
|
@ -1292,7 +1294,7 @@ void Preprocessor::HandleMacroPublicDirective(Token &Tok) {
|
|||
|
||||
IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
|
||||
// Okay, we finally have a valid identifier to undef.
|
||||
MacroDirective *MD = getMacroDirective(II);
|
||||
MacroDirective *MD = getLocalMacroDirective(II);
|
||||
|
||||
// If the macro is not defined, this is an error.
|
||||
if (!MD) {
|
||||
|
@ -1319,7 +1321,7 @@ void Preprocessor::HandleMacroPrivateDirective(Token &Tok) {
|
|||
|
||||
IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
|
||||
// Okay, we finally have a valid identifier to undef.
|
||||
MacroDirective *MD = getMacroDirective(II);
|
||||
MacroDirective *MD = getLocalMacroDirective(II);
|
||||
|
||||
// If the macro is not defined, this is an error.
|
||||
if (!MD) {
|
||||
|
@ -1757,7 +1759,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
|||
|
||||
// Ask HeaderInfo if we should enter this #include file. If not, #including
|
||||
// this file will have no effect.
|
||||
if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) {
|
||||
if (!HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport)) {
|
||||
if (Callbacks)
|
||||
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
|
||||
return;
|
||||
|
@ -2295,16 +2297,19 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) {
|
|||
// Check to see if this is the last token on the #undef line.
|
||||
CheckEndOfDirective("undef");
|
||||
|
||||
// Okay, we finally have a valid identifier to undef.
|
||||
MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo());
|
||||
const MacroInfo *MI = MD ? MD->getMacroInfo() : nullptr;
|
||||
// Okay, we have a valid identifier to undef.
|
||||
auto *II = MacroNameTok.getIdentifierInfo();
|
||||
|
||||
// If the callbacks want to know, tell them about the macro #undef.
|
||||
// Note: no matter if the macro was defined or not.
|
||||
if (Callbacks)
|
||||
if (Callbacks) {
|
||||
// FIXME: Tell callbacks about module macros.
|
||||
MacroDirective *MD = getLocalMacroDirective(II);
|
||||
Callbacks->MacroUndefined(MacroNameTok, MD);
|
||||
}
|
||||
|
||||
// If the macro is not defined, this is a noop undef, just return.
|
||||
const MacroInfo *MI = getMacroInfo(II);
|
||||
if (!MI)
|
||||
return;
|
||||
|
||||
|
@ -2349,8 +2354,7 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
|
|||
CheckEndOfDirective(isIfndef ? "ifndef" : "ifdef");
|
||||
|
||||
IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
|
||||
MacroDirective *MD = getMacroDirective(MII);
|
||||
MacroInfo *MI = MD ? MD->getMacroInfo() : nullptr;
|
||||
MacroInfo *MI = getMacroInfo(MII);
|
||||
|
||||
if (CurPPLexer->getConditionalStackDepth() == 0) {
|
||||
// If the start of a top-level #ifdef and if the macro is not defined,
|
||||
|
@ -2369,6 +2373,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
|
|||
markMacroAsUsed(MI);
|
||||
|
||||
if (Callbacks) {
|
||||
// FIXME: Tell callbacks about module macros.
|
||||
MacroDirective *MD = getLocalMacroDirective(MII);
|
||||
if (isIfndef)
|
||||
Callbacks->Ifndef(DirectiveTok.getLocation(), MacroNameTok, MD);
|
||||
else
|
||||
|
|
|
@ -108,15 +108,13 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
|
|||
|
||||
// Otherwise, we got an identifier, is it defined to something?
|
||||
IdentifierInfo *II = PeekTok.getIdentifierInfo();
|
||||
Result.Val = II->hasMacroDefinition();
|
||||
Preprocessor::MacroDefinition Macro = PP.getMacroDefinition(II);
|
||||
Result.Val = !!Macro;
|
||||
Result.Val.setIsUnsigned(false); // Result is signed intmax_t.
|
||||
|
||||
MacroDirective *Macro = nullptr;
|
||||
// If there is a macro, mark it used.
|
||||
if (Result.Val != 0 && ValueLive) {
|
||||
Macro = PP.getMacroDirective(II);
|
||||
PP.markMacroAsUsed(Macro->getMacroInfo());
|
||||
}
|
||||
if (Result.Val != 0 && ValueLive)
|
||||
PP.markMacroAsUsed(Macro.getMacroInfo());
|
||||
|
||||
// Save macro token for callback.
|
||||
Token macroToken(PeekTok);
|
||||
|
@ -144,10 +142,8 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
|
|||
|
||||
// Invoke the 'defined' callback.
|
||||
if (PPCallbacks *Callbacks = PP.getPPCallbacks()) {
|
||||
MacroDirective *MD = Macro;
|
||||
// Pass the MacroInfo for the macro name even if the value is dead.
|
||||
if (!MD && Result.Val != 0)
|
||||
MD = PP.getMacroDirective(II);
|
||||
// FIXME: Tell callbacks about module macros.
|
||||
MacroDirective *MD = Macro.getLocalDirective();
|
||||
Callbacks->Defined(macroToken, MD,
|
||||
SourceRange(beginLoc, PeekTok.getLocation()));
|
||||
}
|
||||
|
|
|
@ -309,7 +309,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
|
|||
}
|
||||
if (const IdentifierInfo *DefinedMacro =
|
||||
CurPPLexer->MIOpt.GetDefinedMacro()) {
|
||||
if (!ControllingMacro->hasMacroDefinition() &&
|
||||
if (!isMacroDefined(ControllingMacro) &&
|
||||
DefinedMacro != ControllingMacro &&
|
||||
HeaderInfo.FirstTimeLexingFile(FE)) {
|
||||
|
||||
|
|
|
@ -34,12 +34,11 @@
|
|||
using namespace clang;
|
||||
|
||||
MacroDirective *
|
||||
Preprocessor::getMacroDirectiveHistory(const IdentifierInfo *II) const {
|
||||
assert(II->hadMacroDefinition() && "Identifier has not been not a macro!");
|
||||
|
||||
Preprocessor::getLocalMacroDirectiveHistory(const IdentifierInfo *II) const {
|
||||
if (!II->hadMacroDefinition())
|
||||
return nullptr;
|
||||
auto Pos = Macros.find(II);
|
||||
assert(Pos != Macros.end() && "Identifier macro info is missing!");
|
||||
return Pos->second.getLatest();
|
||||
return Pos == Macros.end() ? nullptr : Pos->second.getLatest();
|
||||
}
|
||||
|
||||
void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
|
||||
|
@ -54,7 +53,7 @@ void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
|
|||
|
||||
// Set up the identifier as having associated macro history.
|
||||
II->setHasMacroDefinition(true);
|
||||
if (!MD->isDefined())
|
||||
if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
|
||||
II->setHasMacroDefinition(false);
|
||||
if (II->isFromAST() && !MD->isImported())
|
||||
II->setChangedSinceDeserialization();
|
||||
|
@ -69,7 +68,7 @@ void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
|
|||
StoredMD = MD;
|
||||
// Setup the identifier as having associated macro history.
|
||||
II->setHasMacroDefinition(true);
|
||||
if (!MD->isDefined())
|
||||
if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
|
||||
II->setHasMacroDefinition(false);
|
||||
}
|
||||
|
||||
|
@ -108,6 +107,8 @@ ModuleMacro *Preprocessor::addModuleMacro(Module *Mod, IdentifierInfo *II,
|
|||
|
||||
// The new macro is always a leaf macro.
|
||||
LeafMacros.push_back(MM);
|
||||
// The identifier now has defined macros (that may or may not be visible).
|
||||
II->setHasMacroDefinition(true);
|
||||
|
||||
New = true;
|
||||
return MM;
|
||||
|
@ -121,7 +122,7 @@ ModuleMacro *Preprocessor::getModuleMacro(Module *Mod, IdentifierInfo *II) {
|
|||
return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);
|
||||
}
|
||||
|
||||
void Preprocessor::updateModuleMacroInfo(IdentifierInfo *II,
|
||||
void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II,
|
||||
ModuleMacroInfo &Info) {
|
||||
assert(Info.ActiveModuleMacrosGeneration != MacroVisibilityGeneration &&
|
||||
"don't need to update this macro name info");
|
||||
|
@ -156,14 +157,20 @@ void Preprocessor::updateModuleMacroInfo(IdentifierInfo *II,
|
|||
Worklist.push_back(O);
|
||||
}
|
||||
}
|
||||
// Our reverse postorder walk found the macros in reverse order.
|
||||
std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end());
|
||||
|
||||
// Determine whether the macro name is ambiguous.
|
||||
Info.IsAmbiguous = false;
|
||||
MacroInfo *MI = nullptr;
|
||||
bool IsSystemMacro = false;
|
||||
if (auto *DMD = dyn_cast<DefMacroDirective>(Info.MD)) {
|
||||
MI = DMD->getInfo();
|
||||
IsSystemMacro = SourceMgr.isInSystemHeader(DMD->getLocation());
|
||||
bool IsSystemMacro = true;
|
||||
bool IsAmbiguous = false;
|
||||
if (auto *MD = Info.MD) {
|
||||
while (MD && isa<VisibilityMacroDirective>(MD))
|
||||
MD = MD->getPrevious();
|
||||
if (auto *DMD = dyn_cast_or_null<DefMacroDirective>(MD)) {
|
||||
MI = DMD->getInfo();
|
||||
IsSystemMacro &= SourceMgr.isInSystemHeader(DMD->getLocation());
|
||||
}
|
||||
}
|
||||
for (auto *Active : Info.ActiveModuleMacros) {
|
||||
auto *NewMI = Active->getMacroInfo();
|
||||
|
@ -177,13 +184,14 @@ void Preprocessor::updateModuleMacroInfo(IdentifierInfo *II,
|
|||
//
|
||||
// FIXME: Remove the defined-in-system-headers check. clang's limits.h
|
||||
// overrides the system limits.h's macros, so there's no conflict here.
|
||||
IsSystemMacro &= Active->getOwningModule()->IsSystem;
|
||||
if (MI && NewMI != MI && !IsSystemMacro &&
|
||||
!MI->isIdenticalTo(*NewMI, *this, /*Syntactically=*/true)) {
|
||||
Info.IsAmbiguous = true;
|
||||
break;
|
||||
}
|
||||
if (MI && NewMI != MI &&
|
||||
!MI->isIdenticalTo(*NewMI, *this, /*Syntactically=*/true))
|
||||
IsAmbiguous = true;
|
||||
IsSystemMacro &= Active->getOwningModule()->IsSystem ||
|
||||
SourceMgr.isInSystemHeader(NewMI->getDefinitionLoc());
|
||||
MI = NewMI;
|
||||
}
|
||||
Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro;
|
||||
}
|
||||
|
||||
/// RegisterBuiltinMacro - Register the specified identifier in the identifier
|
||||
|
@ -270,10 +278,11 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
|
|||
|
||||
// If the identifier is a macro, and if that macro is enabled, it may be
|
||||
// expanded so it's not a trivial expansion.
|
||||
if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() &&
|
||||
// Fast expanding "#define X X" is ok, because X would be disabled.
|
||||
II != MacroIdent)
|
||||
return false;
|
||||
if (auto *ExpansionMI = PP.getMacroInfo(II))
|
||||
if (PP.getMacroInfo(II)->isEnabled() &&
|
||||
// Fast expanding "#define X X" is ok, because X would be disabled.
|
||||
II != MacroIdent)
|
||||
return false;
|
||||
|
||||
// If this is an object-like macro invocation, it is safe to trivially expand
|
||||
// it.
|
||||
|
@ -336,10 +345,8 @@ bool Preprocessor::isNextPPTokenLParen() {
|
|||
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
|
||||
/// expanded as a macro, handle it and return the next token as 'Identifier'.
|
||||
bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
|
||||
MacroDirective *MD) {
|
||||
MacroDirective::DefInfo Def = MD->getDefinition();
|
||||
assert(Def.isValid());
|
||||
MacroInfo *MI = Def.getMacroInfo();
|
||||
const MacroDefinition &M) {
|
||||
MacroInfo *MI = M.getMacroInfo();
|
||||
|
||||
// If this is a macro expansion in the "#if !defined(x)" line for the file,
|
||||
// then the macro could expand to different things in other contexts, we need
|
||||
|
@ -348,7 +355,8 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
|
|||
|
||||
// If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
|
||||
if (MI->isBuiltinMacro()) {
|
||||
if (Callbacks) Callbacks->MacroExpands(Identifier, MD,
|
||||
// FIXME: Tell callbacks about module macros.
|
||||
if (Callbacks) Callbacks->MacroExpands(Identifier, M.getLocalDirective(),
|
||||
Identifier.getLocation(),
|
||||
/*Args=*/nullptr);
|
||||
ExpandBuiltinMacro(Identifier);
|
||||
|
@ -396,10 +404,13 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
|
|||
// reading the function macro arguments. To ensure, in that case, that
|
||||
// MacroExpands callbacks still happen in source order, queue this
|
||||
// callback to have it happen after the function macro callback.
|
||||
// FIXME: Tell callbacks about module macros.
|
||||
DelayedMacroExpandsCallbacks.push_back(
|
||||
MacroExpandsInfo(Identifier, MD, ExpansionRange));
|
||||
MacroExpandsInfo(Identifier, M.getLocalDirective(), ExpansionRange));
|
||||
} else {
|
||||
Callbacks->MacroExpands(Identifier, MD, ExpansionRange, Args);
|
||||
// FIXME: Tell callbacks about module macros.
|
||||
Callbacks->MacroExpands(Identifier, M.getLocalDirective(), ExpansionRange,
|
||||
Args);
|
||||
if (!DelayedMacroExpandsCallbacks.empty()) {
|
||||
for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
|
||||
MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
|
||||
|
@ -413,20 +424,16 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
|
|||
}
|
||||
|
||||
// If the macro definition is ambiguous, complain.
|
||||
if (Def.getDirective()->isAmbiguous()) {
|
||||
if (M.isAmbiguous()) {
|
||||
Diag(Identifier, diag::warn_pp_ambiguous_macro)
|
||||
<< Identifier.getIdentifierInfo();
|
||||
Diag(MI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_chosen)
|
||||
<< Identifier.getIdentifierInfo();
|
||||
for (MacroDirective::DefInfo PrevDef = Def.getPreviousDefinition();
|
||||
PrevDef && !PrevDef.isUndefined();
|
||||
PrevDef = PrevDef.getPreviousDefinition()) {
|
||||
Diag(PrevDef.getMacroInfo()->getDefinitionLoc(),
|
||||
diag::note_pp_ambiguous_macro_other)
|
||||
<< Identifier.getIdentifierInfo();
|
||||
if (!PrevDef.getDirective()->isAmbiguous())
|
||||
break;
|
||||
}
|
||||
M.forAllDefinitions([&](const MacroInfo *OtherMI) {
|
||||
if (OtherMI != MI)
|
||||
Diag(OtherMI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_other)
|
||||
<< Identifier.getIdentifierInfo();
|
||||
});
|
||||
}
|
||||
|
||||
// If we started lexing a macro, enter the macro expansion body.
|
||||
|
|
|
@ -400,7 +400,7 @@ void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
|
|||
if (II->isPoisoned()) continue;
|
||||
|
||||
// If this is a macro identifier, emit a warning.
|
||||
if (II->hasMacroDefinition())
|
||||
if (isMacroDefined(II))
|
||||
Diag(Tok, diag::pp_poisoning_existing_macro);
|
||||
|
||||
// Finally, poison it!
|
||||
|
@ -590,8 +590,7 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
|
|||
PragmaPushMacroInfo.find(IdentInfo);
|
||||
if (iter != PragmaPushMacroInfo.end()) {
|
||||
// Forget the MacroInfo currently associated with IdentInfo.
|
||||
if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) {
|
||||
MacroInfo *MI = CurrentMD->getMacroInfo();
|
||||
if (MacroInfo *MI = getMacroInfo(IdentInfo)) {
|
||||
if (MI->isWarnIfUnused())
|
||||
WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
|
||||
appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
|
||||
|
|
|
@ -73,8 +73,7 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
|
|||
ModuleImportExpectsIdentifier(false), CodeCompletionReached(0),
|
||||
MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr),
|
||||
CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr),
|
||||
Callbacks(nullptr), MacroVisibilityGeneration(0),
|
||||
MacroArgCache(nullptr), Record(nullptr),
|
||||
Callbacks(nullptr), MacroArgCache(nullptr), Record(nullptr),
|
||||
MIChainHead(nullptr), DeserialMIChainHead(nullptr) {
|
||||
OwnsHeaderSearch = OwnsHeaders;
|
||||
|
||||
|
@ -108,6 +107,9 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
|
|||
|
||||
// We haven't read anything from the external source.
|
||||
ReadMacrosFromExternalSource = false;
|
||||
// We might already have some macros from an imported module (via a PCH or
|
||||
// preamble) if modules is enabled.
|
||||
MacroVisibilityGeneration = LangOpts.Modules ? 1 : 0;
|
||||
|
||||
// "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
|
||||
// This gets unpoisoned where it is allowed.
|
||||
|
@ -623,8 +625,8 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
|
|||
}
|
||||
|
||||
// If this is a macro to be expanded, do it.
|
||||
if (MacroDirective *MD = getMacroDirective(&II)) {
|
||||
MacroInfo *MI = MD->getMacroInfo();
|
||||
if (MacroDefinition MD = getMacroDefinition(&II)) {
|
||||
auto *MI = MD.getMacroInfo();
|
||||
if (!DisableMacroExpansion) {
|
||||
if (!Identifier.isExpandDisabled() && MI->isEnabled()) {
|
||||
// C99 6.10.3p10: If the preprocessing token immediately after the
|
||||
|
|
|
@ -2017,7 +2017,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
|
|||
if (SemaRef.getLangOpts().C11) {
|
||||
// _Alignof
|
||||
Builder.AddResultTypeChunk("size_t");
|
||||
if (SemaRef.getASTContext().Idents.get("alignof").hasMacroDefinition())
|
||||
if (SemaRef.PP.isMacroDefined("alignof"))
|
||||
Builder.AddTypedTextChunk("alignof");
|
||||
else
|
||||
Builder.AddTypedTextChunk("_Alignof");
|
||||
|
@ -2085,15 +2085,14 @@ static void AddResultTypeChunk(ASTContext &Context,
|
|||
Result.getAllocator()));
|
||||
}
|
||||
|
||||
static void MaybeAddSentinel(ASTContext &Context,
|
||||
static void MaybeAddSentinel(Preprocessor &PP,
|
||||
const NamedDecl *FunctionOrMethod,
|
||||
CodeCompletionBuilder &Result) {
|
||||
if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
|
||||
if (Sentinel->getSentinel() == 0) {
|
||||
if (Context.getLangOpts().ObjC1 &&
|
||||
Context.Idents.get("nil").hasMacroDefinition())
|
||||
if (PP.getLangOpts().ObjC1 && PP.isMacroDefined("nil"))
|
||||
Result.AddTextChunk(", nil");
|
||||
else if (Context.Idents.get("NULL").hasMacroDefinition())
|
||||
else if (PP.isMacroDefined("NULL"))
|
||||
Result.AddTextChunk(", NULL");
|
||||
else
|
||||
Result.AddTextChunk(", (void*)0");
|
||||
|
@ -2117,8 +2116,7 @@ static std::string formatObjCParamQualifiers(unsigned ObjCQuals) {
|
|||
return Result;
|
||||
}
|
||||
|
||||
static std::string FormatFunctionParameter(ASTContext &Context,
|
||||
const PrintingPolicy &Policy,
|
||||
static std::string FormatFunctionParameter(const PrintingPolicy &Policy,
|
||||
const ParmVarDecl *Param,
|
||||
bool SuppressName = false,
|
||||
bool SuppressBlock = false) {
|
||||
|
@ -2217,7 +2215,7 @@ static std::string FormatFunctionParameter(ASTContext &Context,
|
|||
for (unsigned I = 0, N = Block.getNumParams(); I != N; ++I) {
|
||||
if (I)
|
||||
Params += ", ";
|
||||
Params += FormatFunctionParameter(Context, Policy, Block.getParam(I),
|
||||
Params += FormatFunctionParameter(Policy, Block.getParam(I),
|
||||
/*SuppressName=*/false,
|
||||
/*SuppressBlock=*/true);
|
||||
|
||||
|
@ -2247,7 +2245,7 @@ static std::string FormatFunctionParameter(ASTContext &Context,
|
|||
}
|
||||
|
||||
/// \brief Add function parameter chunks to the given code completion string.
|
||||
static void AddFunctionParameterChunks(ASTContext &Context,
|
||||
static void AddFunctionParameterChunks(Preprocessor &PP,
|
||||
const PrintingPolicy &Policy,
|
||||
const FunctionDecl *Function,
|
||||
CodeCompletionBuilder &Result,
|
||||
|
@ -2265,7 +2263,7 @@ static void AddFunctionParameterChunks(ASTContext &Context,
|
|||
Result.getCodeCompletionTUInfo());
|
||||
if (!FirstParameter)
|
||||
Opt.AddChunk(CodeCompletionString::CK_Comma);
|
||||
AddFunctionParameterChunks(Context, Policy, Function, Opt, P, true);
|
||||
AddFunctionParameterChunks(PP, Policy, Function, Opt, P, true);
|
||||
Result.AddOptionalChunk(Opt.TakeString());
|
||||
break;
|
||||
}
|
||||
|
@ -2278,9 +2276,8 @@ static void AddFunctionParameterChunks(ASTContext &Context,
|
|||
InOptional = false;
|
||||
|
||||
// Format the placeholder string.
|
||||
std::string PlaceholderStr = FormatFunctionParameter(Context, Policy,
|
||||
Param);
|
||||
|
||||
std::string PlaceholderStr = FormatFunctionParameter(Policy, Param);
|
||||
|
||||
if (Function->isVariadic() && P == N - 1)
|
||||
PlaceholderStr += ", ...";
|
||||
|
||||
|
@ -2295,7 +2292,7 @@ static void AddFunctionParameterChunks(ASTContext &Context,
|
|||
if (Proto->getNumParams() == 0)
|
||||
Result.AddPlaceholderChunk("...");
|
||||
|
||||
MaybeAddSentinel(Context, Function, Result);
|
||||
MaybeAddSentinel(PP, Function, Result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2575,11 +2572,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|||
}
|
||||
|
||||
if (Kind == RK_Macro) {
|
||||
const MacroDirective *MD = PP.getMacroDirectiveHistory(Macro);
|
||||
assert(MD && "Not a macro?");
|
||||
const MacroInfo *MI = MD->getMacroInfo();
|
||||
assert((!MD->isDefined() || MI) && "missing MacroInfo for define");
|
||||
|
||||
const MacroInfo *MI = PP.getMacroInfo(Macro);
|
||||
Result.AddTypedTextChunk(
|
||||
Result.getAllocator().CopyString(Macro->getName()));
|
||||
|
||||
|
@ -2654,7 +2647,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|||
Ctx, Policy);
|
||||
AddTypedNameChunk(Ctx, Policy, ND, Result);
|
||||
Result.AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
AddFunctionParameterChunks(Ctx, Policy, Function, Result);
|
||||
AddFunctionParameterChunks(PP, Policy, Function, Result);
|
||||
Result.AddChunk(CodeCompletionString::CK_RightParen);
|
||||
AddFunctionTypeQualsToCompletionString(Result, Function);
|
||||
return Result.TakeString();
|
||||
|
@ -2708,7 +2701,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|||
|
||||
// Add the function parameters
|
||||
Result.AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
AddFunctionParameterChunks(Ctx, Policy, Function, Result);
|
||||
AddFunctionParameterChunks(PP, Policy, Function, Result);
|
||||
Result.AddChunk(CodeCompletionString::CK_RightParen);
|
||||
AddFunctionTypeQualsToCompletionString(Result, Function);
|
||||
return Result.TakeString();
|
||||
|
@ -2769,7 +2762,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|||
std::string Arg;
|
||||
|
||||
if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
|
||||
Arg = FormatFunctionParameter(Ctx, Policy, *P, true);
|
||||
Arg = FormatFunctionParameter(Policy, *P, true);
|
||||
else {
|
||||
(*P)->getType().getAsStringInternal(Arg, Policy);
|
||||
Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier())
|
||||
|
@ -2800,7 +2793,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
|
|||
Result.AddPlaceholderChunk(", ...");
|
||||
}
|
||||
|
||||
MaybeAddSentinel(Ctx, Method, Result);
|
||||
MaybeAddSentinel(PP, Method, Result);
|
||||
}
|
||||
|
||||
return Result.TakeString();
|
||||
|
@ -2854,8 +2847,7 @@ static void AddOverloadParameterChunks(ASTContext &Context,
|
|||
// Format the placeholder string.
|
||||
std::string Placeholder;
|
||||
if (Function)
|
||||
Placeholder = FormatFunctionParameter(Context, Policy,
|
||||
Function->getParamDecl(P));
|
||||
Placeholder = FormatFunctionParameter(Policy, Function->getParamDecl(P));
|
||||
else
|
||||
Placeholder = Prototype->getParamType(P).getAsString(Policy);
|
||||
|
||||
|
@ -3036,8 +3028,9 @@ static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
|
|||
for (Preprocessor::macro_iterator M = PP.macro_begin(),
|
||||
MEnd = PP.macro_end();
|
||||
M != MEnd; ++M) {
|
||||
if (IncludeUndefined || M->first->hasMacroDefinition()) {
|
||||
if (MacroInfo *MI = M->second.getLatest()->getMacroInfo())
|
||||
auto MD = PP.getMacroDefinition(M->first);
|
||||
if (IncludeUndefined || MD) {
|
||||
if (MacroInfo *MI = MD.getMacroInfo())
|
||||
if (MI->isUsedForHeaderGuard())
|
||||
continue;
|
||||
|
||||
|
@ -5122,7 +5115,7 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
|
|||
// an action, e.g.,
|
||||
// IBAction)<#selector#>:(id)sender
|
||||
if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
|
||||
Context.Idents.get("IBAction").hasMacroDefinition()) {
|
||||
PP.isMacroDefined("IBAction")) {
|
||||
CodeCompletionBuilder Builder(Results.getAllocator(),
|
||||
Results.getCodeCompletionTUInfo(),
|
||||
CCP_CodePattern, CXAvailability_Available);
|
||||
|
|
|
@ -450,12 +450,11 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
|
|||
SourceLocation MissingNilLoc
|
||||
= PP.getLocForEndOfToken(sentinelExpr->getLocEnd());
|
||||
std::string NullValue;
|
||||
if (calleeType == CT_Method &&
|
||||
PP.getIdentifierInfo("nil")->hasMacroDefinition())
|
||||
if (calleeType == CT_Method && PP.isMacroDefined("nil"))
|
||||
NullValue = "nil";
|
||||
else if (getLangOpts().CPlusPlus11)
|
||||
NullValue = "nullptr";
|
||||
else if (PP.getIdentifierInfo("NULL")->hasMacroDefinition())
|
||||
else if (PP.isMacroDefined("NULL"))
|
||||
NullValue = "NULL";
|
||||
else
|
||||
NullValue = "(void*) 0";
|
||||
|
|
|
@ -161,11 +161,8 @@ bool ConversionFixItGenerator::tryToFixConversion(const Expr *FullExpr,
|
|||
}
|
||||
|
||||
static bool isMacroDefined(const Sema &S, SourceLocation Loc, StringRef Name) {
|
||||
const IdentifierInfo *II = &S.getASTContext().Idents.get(Name);
|
||||
if (!II->hadMacroDefinition()) return false;
|
||||
|
||||
MacroDirective *Macro = S.PP.getMacroDirectiveHistory(II);
|
||||
return Macro && Macro->findDirectiveAtLoc(Loc, S.getSourceManager());
|
||||
return (bool)S.PP.getMacroDefinitionAtLoc(&S.getASTContext().Idents.get(Name),
|
||||
Loc);
|
||||
}
|
||||
|
||||
static std::string getScalarZeroExpressionForType(
|
||||
|
|
|
@ -1723,22 +1723,6 @@ void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) {
|
|||
IdentifierGeneration[II] = getGeneration();
|
||||
}
|
||||
|
||||
struct ASTReader::ModuleMacroInfo {
|
||||
ModuleMacro *MM;
|
||||
// FIXME: Remove this.
|
||||
ModuleFile *F;
|
||||
|
||||
bool isDefine() const { return MM->getMacroInfo(); }
|
||||
|
||||
ArrayRef<ModuleMacro *> getOverriddenMacros() const {
|
||||
return MM->overrides();
|
||||
}
|
||||
|
||||
MacroDirective *import(Preprocessor &PP, SourceLocation ImportLoc) const {
|
||||
return PP.AllocateImportedMacroDirective(MM, ImportLoc);
|
||||
}
|
||||
};
|
||||
|
||||
void ASTReader::resolvePendingMacro(IdentifierInfo *II,
|
||||
const PendingMacroInfo &PMInfo) {
|
||||
ModuleFile &M = *PMInfo.M;
|
||||
|
@ -1806,19 +1790,7 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
|
|||
|
||||
bool Inserted = false;
|
||||
Module *Owner = getSubmodule(MMR.SubModID);
|
||||
auto *MM = PP.addModuleMacro(Owner, II, MMR.MI, Overrides, Inserted);
|
||||
if (!Inserted)
|
||||
continue;
|
||||
|
||||
ModuleMacroInfo MMI = { MM, &M };
|
||||
if (Owner->NameVisibility == Module::Hidden) {
|
||||
// Macros in the owning module are hidden. Just remember this macro to
|
||||
// install if we make this module visible.
|
||||
HiddenNamesMap[Owner].HiddenMacros.insert(
|
||||
std::make_pair(II, new (Context) ModuleMacroInfo(MMI)));
|
||||
} else {
|
||||
installImportedMacro(II, MMI, Owner);
|
||||
}
|
||||
PP.addModuleMacro(Owner, II, MMR.MI, Overrides, Inserted);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1870,164 +1842,6 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
|
|||
PP.setLoadedMacroDirective(II, Latest);
|
||||
}
|
||||
|
||||
/// \brief For the given macro definitions, check if they are both in system
|
||||
/// modules.
|
||||
static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI,
|
||||
Module *NewOwner, ASTReader &Reader) {
|
||||
assert(PrevMI && NewMI);
|
||||
Module *PrevOwner = nullptr;
|
||||
if (SubmoduleID PrevModID = PrevMI->getOwningModuleID())
|
||||
PrevOwner = Reader.getSubmodule(PrevModID);
|
||||
if (PrevOwner && PrevOwner == NewOwner)
|
||||
return false;
|
||||
SourceManager &SrcMgr = Reader.getSourceManager();
|
||||
bool PrevInSystem = (PrevOwner && PrevOwner->IsSystem) ||
|
||||
SrcMgr.isInSystemHeader(PrevMI->getDefinitionLoc());
|
||||
bool NewInSystem = (NewOwner && NewOwner->IsSystem) ||
|
||||
SrcMgr.isInSystemHeader(NewMI->getDefinitionLoc());
|
||||
return PrevInSystem && NewInSystem;
|
||||
}
|
||||
|
||||
void ASTReader::removeOverriddenMacros(IdentifierInfo *II,
|
||||
SourceLocation ImportLoc,
|
||||
AmbiguousMacros &Ambig,
|
||||
ArrayRef<ModuleMacro *> Overrides) {
|
||||
for (ModuleMacro *Overridden : Overrides) {
|
||||
Module *Owner = Overridden->getOwningModule();
|
||||
// If this macro is not yet visible, remove it from the hidden names list.
|
||||
// It won't be there if we're in the middle of making the owner visible.
|
||||
auto HiddenIt = HiddenNamesMap.find(Owner);
|
||||
if (HiddenIt != HiddenNamesMap.end()) {
|
||||
HiddenNames &Hidden = HiddenIt->second;
|
||||
HiddenMacrosMap::iterator HI = Hidden.HiddenMacros.find(II);
|
||||
if (HI != Hidden.HiddenMacros.end()) {
|
||||
// Register the macro now so we don't lose it when we re-export.
|
||||
PP.appendMacroDirective(II, HI->second->import(PP, ImportLoc));
|
||||
|
||||
auto SubOverrides = HI->second->getOverriddenMacros();
|
||||
Hidden.HiddenMacros.erase(HI);
|
||||
removeOverriddenMacros(II, ImportLoc, Ambig, SubOverrides);
|
||||
}
|
||||
}
|
||||
|
||||
// If this macro is already in our list of conflicts, remove it from there.
|
||||
Ambig.erase(
|
||||
std::remove_if(Ambig.begin(), Ambig.end(), [&](DefMacroDirective *MD) {
|
||||
return getSubmodule(MD->getInfo()->getOwningModuleID()) == Owner;
|
||||
}),
|
||||
Ambig.end());
|
||||
}
|
||||
}
|
||||
|
||||
ASTReader::AmbiguousMacros *
|
||||
ASTReader::removeOverriddenMacros(IdentifierInfo *II,
|
||||
SourceLocation ImportLoc,
|
||||
ArrayRef<ModuleMacro *> Overrides) {
|
||||
MacroDirective *Prev = PP.getMacroDirective(II);
|
||||
if (!Prev && Overrides.empty())
|
||||
return nullptr;
|
||||
|
||||
DefMacroDirective *PrevDef = Prev ? Prev->getDefinition().getDirective()
|
||||
: nullptr;
|
||||
if (PrevDef && PrevDef->isAmbiguous()) {
|
||||
// We had a prior ambiguity. Check whether we resolve it (or make it worse).
|
||||
AmbiguousMacros &Ambig = AmbiguousMacroDefs[II];
|
||||
Ambig.push_back(PrevDef);
|
||||
|
||||
removeOverriddenMacros(II, ImportLoc, Ambig, Overrides);
|
||||
|
||||
if (!Ambig.empty())
|
||||
return &Ambig;
|
||||
|
||||
AmbiguousMacroDefs.erase(II);
|
||||
} else {
|
||||
// There's no ambiguity yet. Maybe we're introducing one.
|
||||
AmbiguousMacros Ambig;
|
||||
if (PrevDef)
|
||||
Ambig.push_back(PrevDef);
|
||||
|
||||
removeOverriddenMacros(II, ImportLoc, Ambig, Overrides);
|
||||
|
||||
if (!Ambig.empty()) {
|
||||
AmbiguousMacros &Result = AmbiguousMacroDefs[II];
|
||||
std::swap(Result, Ambig);
|
||||
return &Result;
|
||||
}
|
||||
}
|
||||
|
||||
// We ended up with no ambiguity.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo &MMI,
|
||||
Module *Owner) {
|
||||
assert(II && Owner);
|
||||
|
||||
SourceLocation ImportLoc = Owner->MacroVisibilityLoc;
|
||||
|
||||
AmbiguousMacros *Prev =
|
||||
removeOverriddenMacros(II, ImportLoc, MMI.getOverriddenMacros());
|
||||
|
||||
// Create a synthetic macro definition corresponding to the import (or null
|
||||
// if this was an undefinition of the macro).
|
||||
MacroDirective *Imported = MMI.import(PP, ImportLoc);
|
||||
DefMacroDirective *MD = dyn_cast<DefMacroDirective>(Imported);
|
||||
|
||||
// If there's no ambiguity, just install the macro.
|
||||
if (!Prev) {
|
||||
PP.appendMacroDirective(II, Imported);
|
||||
return;
|
||||
}
|
||||
assert(!Prev->empty());
|
||||
|
||||
if (!MD) {
|
||||
// We imported a #undef that didn't remove all prior definitions. The most
|
||||
// recent prior definition remains, and we install it in the place of the
|
||||
// imported directive, as if by a local #pragma pop_macro.
|
||||
MacroInfo *NewMI = Prev->back()->getInfo();
|
||||
Prev->pop_back();
|
||||
MD = PP.AllocateDefMacroDirective(NewMI, ImportLoc);
|
||||
|
||||
// Install our #undef first so that we don't lose track of it. We'll replace
|
||||
// this with whichever macro definition ends up winning.
|
||||
PP.appendMacroDirective(II, Imported);
|
||||
}
|
||||
|
||||
// We're introducing a macro definition that creates or adds to an ambiguity.
|
||||
// We can resolve that ambiguity if this macro is token-for-token identical to
|
||||
// all of the existing definitions.
|
||||
MacroInfo *NewMI = MD->getInfo();
|
||||
assert(NewMI && "macro definition with no MacroInfo?");
|
||||
while (!Prev->empty()) {
|
||||
MacroInfo *PrevMI = Prev->back()->getInfo();
|
||||
assert(PrevMI && "macro definition with no MacroInfo?");
|
||||
|
||||
// Before marking the macros as ambiguous, check if this is a case where
|
||||
// both macros are in system headers. If so, we trust that the system
|
||||
// did not get it wrong. This also handles cases where Clang's own
|
||||
// headers have a different spelling of certain system macros:
|
||||
// #define LONG_MAX __LONG_MAX__ (clang's limits.h)
|
||||
// #define LONG_MAX 0x7fffffffffffffffL (system's limits.h)
|
||||
//
|
||||
// FIXME: Remove the defined-in-system-headers check. clang's limits.h
|
||||
// overrides the system limits.h's macros, so there's no conflict here.
|
||||
if (NewMI != PrevMI &&
|
||||
!PrevMI->isIdenticalTo(*NewMI, PP, /*Syntactically=*/true) &&
|
||||
!areDefinedInSystemModules(PrevMI, NewMI, Owner, *this))
|
||||
break;
|
||||
|
||||
// The previous definition is the same as this one (or both are defined in
|
||||
// system modules so we can assume they're equivalent); we don't need to
|
||||
// track it any more.
|
||||
Prev->pop_back();
|
||||
}
|
||||
|
||||
if (!Prev->empty())
|
||||
MD->setAmbiguous(true);
|
||||
|
||||
PP.appendMacroDirective(II, MD);
|
||||
}
|
||||
|
||||
ASTReader::InputFileInfo
|
||||
ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) {
|
||||
// Go find this input file.
|
||||
|
@ -3422,7 +3236,7 @@ void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner) {
|
|||
"nothing to make visible?");
|
||||
|
||||
// FIXME: Only do this if Owner->NameVisibility == AllVisible.
|
||||
for (Decl *D : Names.HiddenDecls) {
|
||||
for (Decl *D : Names) {
|
||||
bool wasHidden = D->Hidden;
|
||||
D->Hidden = false;
|
||||
|
||||
|
@ -3432,9 +3246,6 @@ void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &Macro : Names.HiddenMacros)
|
||||
installImportedMacro(Macro.first, *Macro.second, Owner);
|
||||
}
|
||||
|
||||
void ASTReader::makeModuleVisible(Module *Mod,
|
||||
|
|
|
@ -474,7 +474,7 @@ void ASTDeclReader::VisitDecl(Decl *D) {
|
|||
|
||||
// Note that this declaration was hidden because its owning module is
|
||||
// not yet visible.
|
||||
Reader.HiddenNamesMap[Owner].HiddenDecls.push_back(D);
|
||||
Reader.HiddenNamesMap[Owner].push_back(D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1402,8 +1402,8 @@ void ASTDeclReader::MergeDefinitionData(
|
|||
else {
|
||||
auto SubmoduleID = MergeDD.Definition->getOwningModuleID();
|
||||
assert(SubmoduleID && "hidden definition in no module");
|
||||
Reader.HiddenNamesMap[Reader.getSubmodule(SubmoduleID)]
|
||||
.HiddenDecls.push_back(DD.Definition);
|
||||
Reader.HiddenNamesMap[Reader.getSubmodule(SubmoduleID)].push_back(
|
||||
DD.Definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3816,7 +3816,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
|
|||
if (Owner && Owner->NameVisibility != Module::AllVisible) {
|
||||
// If Owner is made visible at some later point, make this declaration
|
||||
// visible too.
|
||||
Reader.HiddenNamesMap[Owner].HiddenDecls.push_back(D);
|
||||
Reader.HiddenNamesMap[Owner].push_back(D);
|
||||
} else {
|
||||
// The declaration is now visible.
|
||||
D->Hidden = false;
|
||||
|
|
|
@ -2050,7 +2050,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
|
|||
// If the macro or identifier need no updates, don't write the macro history
|
||||
// for this one.
|
||||
// FIXME: Chain the macro history instead of re-writing it.
|
||||
if (MD->isFromPCH() &&
|
||||
if (MD && MD->isFromPCH() &&
|
||||
Name->isFromAST() && !Name->hasChangedSinceDeserialization())
|
||||
continue;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ void test_variadic() {
|
|||
// RUN: c-index-test -code-completion-at=%s:7:1 %s -I%S | FileCheck -check-prefix=CHECK-CC0 %s
|
||||
// CHECK-CC0-NOT: FOO
|
||||
// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:1 %s -I%S | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: macro definition:{TypedText FOO}{LeftParen (}{Placeholder Arg1}{Comma , }{Placeholder Arg2}{RightParen )}
|
||||
// CHECK-CC1: macro definition:{TypedText FOO} (70)
|
||||
// RUN: c-index-test -code-completion-at=%s:13:13 %s -I%S | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// RUN: c-index-test -code-completion-at=%s:14:8 %s -I%S | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:8 %s -I%S | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// expected-note@Inputs/macros_right.h:12{{expanding this definition of 'LEFT_RIGHT_DIFFERENT'}}
|
||||
// expected-note@Inputs/macros_right.h:13{{expanding this definition of 'LEFT_RIGHT_DIFFERENT2'}}
|
||||
// expected-note@Inputs/macros_left.h:14{{other definition of 'LEFT_RIGHT_DIFFERENT'}}
|
||||
// expected-note@Inputs/macros_left.h:11{{other definition of 'LEFT_RIGHT_DIFFERENT2'}}
|
||||
|
||||
@import macros;
|
||||
|
||||
|
|
|
@ -7144,7 +7144,7 @@ MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
|
|||
|
||||
ASTUnit *Unit = cxtu::getASTUnit(TU);
|
||||
Preprocessor &PP = Unit->getPreprocessor();
|
||||
MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
|
||||
MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
|
||||
if (MD) {
|
||||
for (MacroDirective::DefInfo
|
||||
Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
|
||||
|
@ -7201,7 +7201,7 @@ MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
|
|||
if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
|
||||
return nullptr;
|
||||
|
||||
MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
|
||||
MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
|
||||
if (!InnerMD)
|
||||
return nullptr;
|
||||
|
||||
|
|
Loading…
Reference in New Issue