Skip to content

Commit 6a1c51f

Browse files
committed
[clang] Avoid re-evaluating field bitwidth
1 parent 6f16a8b commit 6a1c51f

17 files changed

+259
-256
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3089,17 +3089,27 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
30893089
// Active member if ISK is ISK_CapturedVLAType.
30903090
const VariableArrayType *CapturedVLAType;
30913091
};
3092+
unsigned BitWidthValue = 0;
30923093

30933094
protected:
30943095
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
30953096
SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
3096-
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
3097-
InClassInitStyle InitStyle)
3097+
TypeSourceInfo *TInfo, bool Mutable, InClassInitStyle InitStyle)
3098+
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
3099+
Mutable(Mutable), StorageKind((InitStorageKind)InitStyle),
3100+
CachedFieldIndex(0), Init() {}
3101+
3102+
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
3103+
SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
3104+
TypeSourceInfo *TInfo, Expr *BW, unsigned BitWidthValue,
3105+
bool Mutable, InClassInitStyle InitStyle)
30983106
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
30993107
Mutable(Mutable), StorageKind((InitStorageKind)InitStyle),
31003108
CachedFieldIndex(0), Init() {
3101-
if (BW)
3109+
if (BW) {
31023110
setBitWidth(BW);
3111+
this->BitWidthValue = BitWidthValue;
3112+
}
31033113
}
31043114

31053115
public:
@@ -3109,7 +3119,15 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
31093119
static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
31103120
SourceLocation StartLoc, SourceLocation IdLoc,
31113121
const IdentifierInfo *Id, QualType T,
3112-
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
3122+
TypeSourceInfo *TInfo, Expr *BW,
3123+
unsigned BitWidthValue, bool Mutable,
3124+
InClassInitStyle InitStyle);
3125+
3126+
/// For non-bit-fields.
3127+
static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
3128+
SourceLocation StartLoc, SourceLocation IdLoc,
3129+
const IdentifierInfo *Id, QualType T,
3130+
TypeSourceInfo *TInfo, bool Mutable,
31133131
InClassInitStyle InitStyle);
31143132

31153133
static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);

clang/include/clang/AST/DeclObjC.h

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,8 +1960,15 @@ class ObjCIvarDecl : public FieldDecl {
19601960
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
19611961
SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
19621962
TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
1963-
bool synthesized)
1964-
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
1963+
unsigned BWValue, bool synthesized)
1964+
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, BWValue,
1965+
/*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
1966+
DeclAccess(ac), Synthesized(synthesized) {}
1967+
1968+
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
1969+
SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
1970+
TypeSourceInfo *TInfo, AccessControl ac, bool synthesized)
1971+
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo,
19651972
/*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
19661973
DeclAccess(ac), Synthesized(synthesized) {}
19671974

@@ -1970,7 +1977,8 @@ class ObjCIvarDecl : public FieldDecl {
19701977
SourceLocation StartLoc, SourceLocation IdLoc,
19711978
const IdentifierInfo *Id, QualType T,
19721979
TypeSourceInfo *TInfo, AccessControl ac,
1973-
Expr *BW = nullptr, bool synthesized = false);
1980+
Expr *BW = nullptr, unsigned BWValue = 0,
1981+
bool synthesized = false);
19741982

19751983
static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
19761984

@@ -2028,19 +2036,31 @@ class ObjCIvarDecl : public FieldDecl {
20282036
/// Represents a field declaration created by an \@defs(...).
20292037
class ObjCAtDefsFieldDecl : public FieldDecl {
20302038
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
2031-
SourceLocation IdLoc, IdentifierInfo *Id,
2032-
QualType T, Expr *BW)
2039+
SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
2040+
Expr *BW, unsigned BWValue)
2041+
: FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
2042+
/*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
2043+
BW, BWValue, /*Mutable=*/false,
2044+
/*HasInit=*/ICIS_NoInit) {}
2045+
2046+
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
2047+
SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
20332048
: FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
20342049
/*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
2035-
BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
2050+
/*Mutable=*/false,
2051+
/*HasInit=*/ICIS_NoInit) {}
20362052

20372053
void anchor() override;
20382054

20392055
public:
20402056
static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
20412057
SourceLocation StartLoc,
20422058
SourceLocation IdLoc, IdentifierInfo *Id,
2043-
QualType T, Expr *BW);
2059+
QualType T, Expr *BW, unsigned BWValue);
2060+
static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
2061+
SourceLocation StartLoc,
2062+
SourceLocation IdLoc, IdentifierInfo *Id,
2063+
QualType T);
20442064

20452065
static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C,
20462066
GlobalDeclID ID);

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4277,7 +4277,7 @@ class Sema final : public SemaBase {
42774277
/// Returns false on success.
42784278
ExprResult VerifyBitField(SourceLocation FieldLoc,
42794279
const IdentifierInfo *FieldName, QualType FieldTy,
4280-
bool IsMsStruct, Expr *BitWidth);
4280+
bool IsMsStruct, Expr *BitWidth, unsigned &BWV);
42814281

42824282
/// IsValueInFlagEnum - Determine if a value is allowed as part of a flag
42834283
/// enum. If AllowMask is true, then we also allow the complement of a valid

clang/lib/AST/ASTContext.cpp

Lines changed: 30 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7969,11 +7969,10 @@ TypedefDecl *ASTContext::getCFConstantStringDecl() const {
79697969

79707970
// Create fields
79717971
for (unsigned i = 0; i < Count; ++i) {
7972-
FieldDecl *Field =
7973-
FieldDecl::Create(*this, CFConstantStringTagDecl, SourceLocation(),
7974-
SourceLocation(), &Idents.get(Fields[i].Name),
7975-
Fields[i].Type, /*TInfo=*/nullptr,
7976-
/*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
7972+
FieldDecl *Field = FieldDecl::Create(
7973+
*this, CFConstantStringTagDecl, SourceLocation(), SourceLocation(),
7974+
&Idents.get(Fields[i].Name), Fields[i].Type, /*TInfo=*/nullptr,
7975+
/*Mutable=*/false, ICIS_NoInit);
79777976
Field->setAccess(AS_public);
79787977
CFConstantStringTagDecl->addDecl(Field);
79797978
}
@@ -8039,7 +8038,7 @@ QualType ASTContext::getBlockDescriptorType() const {
80398038
FieldDecl *Field = FieldDecl::Create(
80408039
*this, RD, SourceLocation(), SourceLocation(),
80418040
&Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
8042-
/*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
8041+
/*Mutable=*/false, ICIS_NoInit);
80438042
Field->setAccess(AS_public);
80448043
RD->addDecl(Field);
80458044
}
@@ -8078,7 +8077,6 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
80788077
FieldDecl *Field = FieldDecl::Create(
80798078
*this, RD, SourceLocation(), SourceLocation(),
80808079
&Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
8081-
/*BitWidth=*/nullptr,
80828080
/*Mutable=*/false, ICIS_NoInit);
80838081
Field->setAccess(AS_public);
80848082
RD->addDecl(Field);
@@ -9436,15 +9434,11 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
94369434

94379435
// Create fields
94389436
for (unsigned i = 0; i < NumFields; ++i) {
9439-
FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
9440-
VaListTagDecl,
9441-
SourceLocation(),
9442-
SourceLocation(),
9443-
&Context->Idents.get(FieldNames[i]),
9444-
FieldTypes[i], /*TInfo=*/nullptr,
9445-
/*BitWidth=*/nullptr,
9446-
/*Mutable=*/false,
9447-
ICIS_NoInit);
9437+
FieldDecl *Field = FieldDecl::Create(
9438+
const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
9439+
SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
9440+
/*TInfo=*/nullptr,
9441+
/*Mutable=*/false, ICIS_NoInit);
94489442
Field->setAccess(AS_public);
94499443
VaListTagDecl->addDecl(Field);
94509444
}
@@ -9489,14 +9483,10 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
94899483

94909484
// Create fields
94919485
for (unsigned i = 0; i < NumFields; ++i) {
9492-
FieldDecl *Field = FieldDecl::Create(*Context, VaListTagDecl,
9493-
SourceLocation(),
9494-
SourceLocation(),
9495-
&Context->Idents.get(FieldNames[i]),
9496-
FieldTypes[i], /*TInfo=*/nullptr,
9497-
/*BitWidth=*/nullptr,
9498-
/*Mutable=*/false,
9499-
ICIS_NoInit);
9486+
FieldDecl *Field = FieldDecl::Create(
9487+
*Context, VaListTagDecl, SourceLocation(), SourceLocation(),
9488+
&Context->Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
9489+
/*Mutable=*/false, ICIS_NoInit);
95009490
Field->setAccess(AS_public);
95019491
VaListTagDecl->addDecl(Field);
95029492
}
@@ -9547,15 +9537,11 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
95479537

95489538
// Create fields
95499539
for (unsigned i = 0; i < NumFields; ++i) {
9550-
FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
9551-
VaListTagDecl,
9552-
SourceLocation(),
9553-
SourceLocation(),
9554-
&Context->Idents.get(FieldNames[i]),
9555-
FieldTypes[i], /*TInfo=*/nullptr,
9556-
/*BitWidth=*/nullptr,
9557-
/*Mutable=*/false,
9558-
ICIS_NoInit);
9540+
FieldDecl *Field = FieldDecl::Create(
9541+
const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
9542+
SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
9543+
/*TInfo=*/nullptr,
9544+
/*Mutable=*/false, ICIS_NoInit);
95599545
Field->setAccess(AS_public);
95609546
VaListTagDecl->addDecl(Field);
95619547
}
@@ -9599,16 +9585,12 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
95999585
VaListDecl->startDefinition();
96009586

96019587
// void * __ap;
9602-
FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
9603-
VaListDecl,
9604-
SourceLocation(),
9605-
SourceLocation(),
9606-
&Context->Idents.get("__ap"),
9607-
Context->getPointerType(Context->VoidTy),
9608-
/*TInfo=*/nullptr,
9609-
/*BitWidth=*/nullptr,
9610-
/*Mutable=*/false,
9611-
ICIS_NoInit);
9588+
FieldDecl *Field = FieldDecl::Create(
9589+
const_cast<ASTContext &>(*Context), VaListDecl, SourceLocation(),
9590+
SourceLocation(), &Context->Idents.get("__ap"),
9591+
Context->getPointerType(Context->VoidTy),
9592+
/*TInfo=*/nullptr,
9593+
/*Mutable=*/false, ICIS_NoInit);
96129594
Field->setAccess(AS_public);
96139595
VaListDecl->addDecl(Field);
96149596

@@ -9650,15 +9632,11 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
96509632

96519633
// Create fields
96529634
for (unsigned i = 0; i < NumFields; ++i) {
9653-
FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
9654-
VaListTagDecl,
9655-
SourceLocation(),
9656-
SourceLocation(),
9657-
&Context->Idents.get(FieldNames[i]),
9658-
FieldTypes[i], /*TInfo=*/nullptr,
9659-
/*BitWidth=*/nullptr,
9660-
/*Mutable=*/false,
9661-
ICIS_NoInit);
9635+
FieldDecl *Field = FieldDecl::Create(
9636+
const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
9637+
SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
9638+
/*TInfo=*/nullptr,
9639+
/*Mutable=*/false, ICIS_NoInit);
96629640
Field->setAccess(AS_public);
96639641
VaListTagDecl->addDecl(Field);
96649642
}
@@ -9704,7 +9682,6 @@ static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) {
97049682
const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
97059683
SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
97069684
/*TInfo=*/nullptr,
9707-
/*BitWidth=*/nullptr,
97089685
/*Mutable=*/false, ICIS_NoInit);
97099686
Field->setAccess(AS_public);
97109687
VaListTagDecl->addDecl(Field);

clang/lib/AST/ASTImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4231,7 +4231,7 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
42314231
FieldDecl *ToField;
42324232
if (GetImportedOrCreateDecl(ToField, D, Importer.getToContext(), DC,
42334233
ToInnerLocStart, Loc, Name.getAsIdentifierInfo(),
4234-
ToType, ToTInfo, ToBitWidth, D->isMutable(),
4234+
ToType, ToTInfo, ToBitWidth, 0, D->isMutable(),
42354235
D->getInClassInitStyle()))
42364236
return ToField;
42374237

clang/lib/AST/Decl.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4555,16 +4555,26 @@ unsigned FunctionDecl::getODRHash() {
45554555
FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
45564556
SourceLocation StartLoc, SourceLocation IdLoc,
45574557
const IdentifierInfo *Id, QualType T,
4558-
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
4558+
TypeSourceInfo *TInfo, Expr *BW,
4559+
unsigned BitWidthValue, bool Mutable,
45594560
InClassInitStyle InitStyle) {
45604561
return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
4561-
BW, Mutable, InitStyle);
4562+
BW, BitWidthValue, Mutable, InitStyle);
4563+
}
4564+
4565+
FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
4566+
SourceLocation StartLoc, SourceLocation IdLoc,
4567+
const IdentifierInfo *Id, QualType T,
4568+
TypeSourceInfo *TInfo, bool Mutable,
4569+
InClassInitStyle InitStyle) {
4570+
return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
4571+
nullptr, 0, Mutable, InitStyle);
45624572
}
45634573

45644574
FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
4565-
return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(),
4566-
SourceLocation(), nullptr, QualType(), nullptr,
4567-
nullptr, false, ICIS_NoInit);
4575+
return new (C, ID)
4576+
FieldDecl(Field, nullptr, SourceLocation(), SourceLocation(), nullptr,
4577+
QualType(), nullptr, false, ICIS_NoInit);
45684578
}
45694579

45704580
bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -4601,6 +4611,9 @@ void FieldDecl::setLazyInClassInitializer(LazyDeclStmtPtr NewInit) {
46014611

46024612
unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
46034613
assert(isBitField() && "not a bitfield");
4614+
// FIXME: 0 might be the actual value of the bitwidth.
4615+
if (BitWidthValue != 0)
4616+
return BitWidthValue;
46044617
return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue();
46054618
}
46064619

clang/lib/AST/DeclObjC.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,7 +1833,8 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
18331833
SourceLocation IdLoc,
18341834
const IdentifierInfo *Id, QualType T,
18351835
TypeSourceInfo *TInfo, AccessControl ac,
1836-
Expr *BW, bool synthesized) {
1836+
Expr *BW, unsigned BWValue,
1837+
bool synthesized) {
18371838
if (DC) {
18381839
// Ivar's can only appear in interfaces, implementations (via synthesized
18391840
// properties), and class extensions (via direct declaration, or synthesized
@@ -1861,13 +1862,13 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
18611862
}
18621863

18631864
return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
1864-
synthesized);
1865+
BWValue, synthesized);
18651866
}
18661867

18671868
ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1868-
return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
1869-
nullptr, QualType(), nullptr,
1870-
ObjCIvarDecl::None, nullptr, false);
1869+
return new (C, ID)
1870+
ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
1871+
QualType(), nullptr, ObjCIvarDecl::None, false);
18711872
}
18721873

18731874
ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() {
@@ -1905,18 +1906,27 @@ QualType ObjCIvarDecl::getUsageType(QualType objectType) const {
19051906

19061907
void ObjCAtDefsFieldDecl::anchor() {}
19071908

1908-
ObjCAtDefsFieldDecl
1909-
*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1910-
SourceLocation StartLoc, SourceLocation IdLoc,
1911-
IdentifierInfo *Id, QualType T, Expr *BW) {
1912-
return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
1909+
ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1910+
SourceLocation StartLoc,
1911+
SourceLocation IdLoc,
1912+
IdentifierInfo *Id, QualType T,
1913+
Expr *BW, unsigned BWValue) {
1914+
return new (C, DC)
1915+
ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW, BWValue);
1916+
}
1917+
1918+
ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1919+
SourceLocation StartLoc,
1920+
SourceLocation IdLoc,
1921+
IdentifierInfo *Id,
1922+
QualType T) {
1923+
return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T);
19131924
}
19141925

19151926
ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
19161927
GlobalDeclID ID) {
19171928
return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
1918-
SourceLocation(), nullptr, QualType(),
1919-
nullptr);
1929+
SourceLocation(), nullptr, QualType());
19201930
}
19211931

19221932
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)