Skip to content

Commit

Permalink
[NFC] [Serialization] Unify how LocalDeclID can be created
Browse files Browse the repository at this point in the history
Now we can create a LocalDeclID directly with an integer without
verifying. It may be hard to refactor if we want to change the way we
serialize DeclIDs (See #95897).
Also it is hard for us to debug if someday someone construct a
LocalDeclID with an incorrect value.

So in this patch, I tried to unify the way we can construct a
LocalDeclID in ASTReader, where we will construct the LocalDeclID from
the serialized data. Also, now we can verify the constructed LocalDeclID
sooner in the new interface.
  • Loading branch information
ChuanqiXu9 committed Jun 19, 2024
1 parent 891ec2a commit 8af8602
Show file tree
Hide file tree
Showing 13 changed files with 193 additions and 137 deletions.
2 changes: 1 addition & 1 deletion clang/include/clang/AST/ASTUnresolvedSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ASTUnresolvedSet {
}

void addLazyDecl(ASTContext &C, GlobalDeclID ID, AccessSpecifier AS) {
Decls.push_back(DeclAccessPair::makeLazy(ID.get(), AS), C);
Decls.push_back(DeclAccessPair::makeLazy(ID.getRawValue(), AS), C);
}

/// Replaces the given declaration with the new one, once.
Expand Down
52 changes: 40 additions & 12 deletions clang/include/clang/AST/DeclID.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,8 @@ class DeclIDBase {
DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {}
explicit DeclIDBase(DeclID ID) : ID(ID) {}

explicit DeclIDBase(unsigned LocalID, unsigned ModuleFileIndex) {
ID = (DeclID)LocalID | ((DeclID)ModuleFileIndex << 32);
}

public:
DeclID get() const { return ID; }
DeclID getRawValue() const { return ID; }

explicit operator DeclID() const { return ID; }

Expand All @@ -135,12 +131,33 @@ class DeclIDBase {

unsigned getLocalDeclIndex() const;

// The DeclID may be compared with predefined decl ID.
friend bool operator==(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID == RHS;
}
friend bool operator!=(const DeclIDBase &LHS, const DeclID &RHS) {
return !operator==(LHS, RHS);
}
friend bool operator<(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID < RHS;
}
friend bool operator<=(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID <= RHS;
}
friend bool operator>(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID > RHS;
}
friend bool operator>=(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID >= RHS;
}

friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID == RHS.ID;
}
friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID != RHS.ID;
}

// We may sort the decl ID.
friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID < RHS.ID;
Expand All @@ -159,16 +176,27 @@ class DeclIDBase {
DeclID ID;
};

class ASTWriter;
class ASTReader;
namespace serialization {
class ModuleFile;
} // namespace serialization

class LocalDeclID : public DeclIDBase {
using Base = DeclIDBase;

public:
LocalDeclID() : Base() {}
LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {}
explicit LocalDeclID(DeclID ID) : Base(ID) {}

explicit LocalDeclID(unsigned LocalID, unsigned ModuleFileIndex)
: Base(LocalID, ModuleFileIndex) {}
// Every Decl ID is a local decl ID to the module being writing in ASTWriter.
friend class ASTWriter;
friend class GlobalDeclID;

public:
LocalDeclID() : Base() {}

static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF,
DeclID ID);

LocalDeclID &operator++() {
++ID;
Expand All @@ -189,8 +217,8 @@ class GlobalDeclID : public DeclIDBase {
GlobalDeclID() : Base() {}
explicit GlobalDeclID(DeclID ID) : Base(ID) {}

explicit GlobalDeclID(unsigned LocalID, unsigned ModuleFileIndex)
: Base(LocalID, ModuleFileIndex) {}
explicit GlobalDeclID(unsigned ModuleFileIndex, unsigned LocalID)
: Base((DeclID)ModuleFileIndex << 32 | (DeclID)LocalID) {}

// For DeclIDIterator<GlobalDeclID> to be able to convert a GlobalDeclID
// to a LocalDeclID.
Expand Down Expand Up @@ -235,7 +263,7 @@ template <> struct DenseMapInfo<clang::GlobalDeclID> {
// In GlobalDeclID's case, it is pretty common that the lower 32 bits can
// be same.
// FIXME: Remove this when we fix the underlying issue.
return llvm::hash_value(Key.get());
return llvm::hash_value(Key.getRawValue());
}

static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) {
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2004,9 +2004,9 @@ struct ObjCCategoriesInfo {

ObjCCategoriesInfo() = default;
ObjCCategoriesInfo(LocalDeclID ID, unsigned Offset)
: DefinitionID(ID.get()), Offset(Offset) {}
: DefinitionID(ID.getRawValue()), Offset(Offset) {}

LocalDeclID getDefinitionID() const { return LocalDeclID(DefinitionID); }
DeclID getDefinitionID() const { return DefinitionID; }

friend bool operator<(const ObjCCategoriesInfo &X,
const ObjCCategoriesInfo &Y) {
Expand Down
12 changes: 7 additions & 5 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ class ASTReader
friend class serialization::reader::ASTIdentifierLookupTrait;
friend class serialization::ReadMethodPoolVisitor;
friend class TypeLocReader;
friend class LocalDeclID;

using RecordData = SmallVector<uint64_t, 64>;
using RecordDataImpl = SmallVectorImpl<uint64_t>;
Expand Down Expand Up @@ -1501,7 +1502,8 @@ class ASTReader
: iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {}

value_type operator*() const {
return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, (LocalDeclID)*I));
LocalDeclID ID = LocalDeclID::get(*Reader, *Mod, *I);
return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, ID));
}

value_type operator->() const { return **this; }
Expand Down Expand Up @@ -1955,12 +1957,12 @@ class ASTReader
/// given module.
///
/// \returns The declaration ID read from the record, adjusted to a global ID.
GlobalDeclID ReadDeclID(ModuleFile &F, const RecordData &Record,
GlobalDeclID ReadDeclID(ModuleFile &F, const RecordDataImpl &Record,
unsigned &Idx);

/// Reads a declaration from the given position in a record in the
/// given module.
Decl *ReadDecl(ModuleFile &F, const RecordData &R, unsigned &I) {
Decl *ReadDecl(ModuleFile &F, const RecordDataImpl &R, unsigned &I) {
return GetDecl(ReadDeclID(F, R, I));
}

Expand All @@ -1969,8 +1971,8 @@ class ASTReader
///
/// \returns The declaration read from this location, casted to the given
/// result type.
template<typename T>
T *ReadDeclAs(ModuleFile &F, const RecordData &R, unsigned &I) {
template <typename T>
T *ReadDeclAs(ModuleFile &F, const RecordDataImpl &R, unsigned &I) {
return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I)));
}

Expand Down
3 changes: 1 addition & 2 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -729,8 +729,7 @@ class ASTWriter : public ASTDeserializationListener,
if (D->isFromASTFile())
return false;
auto I = DeclIDs.find(D);
return (I == DeclIDs.end() ||
I->second.get() >= clang::NUM_PREDEF_DECL_IDS);
return (I == DeclIDs.end() || I->second >= clang::NUM_PREDEF_DECL_IDS);
};

/// Emit a reference to a declaration.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context,

uint64_t *PrefixPtr = (uint64_t *)Result - 1;

*PrefixPtr = ID.get();
*PrefixPtr = ID.getRawValue();

// We leave the upper 16 bits to store the module IDs. 48 bits should be
// sufficient to store a declaration ID.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
ASTContext &Context = getASTContext();
GlobalDeclID *Specs = CommonBasePtr->LazySpecializations;
CommonBasePtr->LazySpecializations = nullptr;
unsigned SpecSize = (*Specs++).get();
unsigned SpecSize = (*Specs++).getRawValue();
for (unsigned I = 0; I != SpecSize; ++I)
(void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Frontend/ASTUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1473,7 +1473,7 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
for (const auto TopLevelDecl : TopLevelDeclsInPreamble) {
// Resolve the declaration ID to an actual declaration, possibly
// deserializing the declaration in the process.
if (Decl *D = Reader->GetDecl(Reader->getGlobalDeclID(MF, TopLevelDecl)))
if (Decl *D = Reader->GetLocalDecl(MF, TopLevelDecl))
Resolved.push_back(D);
}
TopLevelDeclsInPreamble.clear();
Expand Down
Loading

0 comments on commit 8af8602

Please sign in to comment.