Modified DeclGroupRef to always load/store the internal pointer value as Decl*. This hopefully will obviate any concerns with violating strict type-aliasing issues.

llvm-svn: 57213
This commit is contained in:
Ted Kremenek 2008-10-06 22:17:16 +00:00
parent 292b3842a0
commit 6d60a4ec19
2 changed files with 25 additions and 20 deletions

View File

@ -42,31 +42,35 @@ public:
}
};
class DeclGroupRef {
protected:
enum Kind { DeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
union { Decl* D; uintptr_t Raw; };
Kind getKind() const { return (Kind) (Raw & Mask); }
enum Kind { DeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
Decl* D;
Kind getKind() const {
return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
}
public:
DeclGroupRef() : Raw(0) {}
DeclGroupRef() : D(0) {}
explicit DeclGroupRef(Decl* d) : D(d) {}
explicit DeclGroupRef(DeclGroup* dg)
: Raw(reinterpret_cast<uintptr_t>(dg) | DeclGroupKind) {}
: D((Decl*) (reinterpret_cast<uintptr_t>(D) | DeclGroupKind)) {}
typedef Decl** iterator;
iterator begin() {
if (getKind() == DeclKind) return Raw ? &D : 0;
DeclGroup* G = reinterpret_cast<DeclGroup*>(Raw & ~Mask);
return &(*G)[0];
if (getKind() == DeclKind) return D ? &D : 0;
DeclGroup& G = *((DeclGroup*) (reinterpret_cast<uintptr_t>(D) & ~Mask));
return &G[0];
}
iterator end() {
if (getKind() == DeclKind) return Raw ? &D + 1 : 0;
DeclGroup* G = reinterpret_cast<DeclGroup*>(Raw & ~Mask);
return &(*G)[0] + G->size();
if (getKind() == DeclKind) return D ? &D + 1 : 0;
DeclGroup& G = *((DeclGroup*) (reinterpret_cast<uintptr_t>(D) & ~Mask));
return &G[0] + G.size();
}
};
@ -76,11 +80,11 @@ public:
void Destroy(ASTContext& C);
explicit DeclGroupOwningRef(DeclGroupOwningRef& R)
: DeclGroupRef(R) { R.Raw = 0; }
: DeclGroupRef(R) { R.D = 0; }
DeclGroupOwningRef& operator=(DeclGroupOwningRef& R) {
Raw = R.Raw;
R.Raw = 0;
D = R.D;
R.D = 0;
return *this;
}
};

View File

@ -43,17 +43,18 @@ void DeclGroup::Destroy(ASTContext& C) {
}
DeclGroupOwningRef::~DeclGroupOwningRef() {
assert (Raw == 0 && "Destroy method not called.");
assert (D == 0 && "Destroy method not called.");
}
void DeclGroupOwningRef::Destroy(ASTContext& C) {
if (!Raw)
if (!D)
return;
if (getKind() == DeclKind)
reinterpret_cast<Decl*>(Raw)->Destroy(C);
else
reinterpret_cast<DeclGroup*>(Raw & ~Mask)->Destroy(C);
D->Destroy(C);
else
reinterpret_cast<DeclGroup*>(reinterpret_cast<uintptr_t>(D) &
~Mask)->Destroy(C);
Raw = 0;
D = 0;
}