@@ -110,13 +110,26 @@ struct ParsedAttrInfo {
110
110
unsigned IsKnownToGCC : 1 ;
111
111
unsigned IsSupportedByPragmaAttribute : 1 ;
112
112
113
- bool (*DiagAppertainsToDecl)(Sema &S, const ParsedAttr &Attr, const Decl *);
114
- bool (*DiagLangOpts)(Sema &S, const ParsedAttr &Attr);
115
- bool (*ExistsInTarget)(const TargetInfo &Target);
116
- unsigned (*SpellingIndexToSemanticSpelling)(const ParsedAttr &Attr);
117
- void (*GetPragmaAttributeMatchRules)(
118
- llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool >> &Rules,
119
- const LangOptions &LangOpts);
113
+ virtual ~ParsedAttrInfo () = default ;
114
+
115
+ virtual bool diagAppertainsToDecl (Sema &S, const ParsedAttr &Attr,
116
+ const Decl *) const {
117
+ return true ;
118
+ }
119
+ virtual bool diagLangOpts (Sema &S, const ParsedAttr &Attr) const {
120
+ return true ;
121
+ }
122
+ virtual bool existsInTarget (const TargetInfo &Target) const {
123
+ return true ;
124
+ }
125
+ virtual unsigned
126
+ spellingIndexToSemanticSpelling (const ParsedAttr &Attr) const {
127
+ return UINT_MAX;
128
+ }
129
+ virtual void getPragmaAttributeMatchRules (
130
+ llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool >> &Rules,
131
+ const LangOptions &LangOpts) const {
132
+ }
120
133
};
121
134
122
135
namespace {
@@ -126,7 +139,13 @@ namespace {
126
139
} // namespace
127
140
128
141
static const ParsedAttrInfo &getInfo (const ParsedAttr &A) {
129
- return AttrInfoMap[A.getKind ()];
142
+ // If we have a ParsedAttrInfo for this ParsedAttr then return that,
143
+ // otherwise return a default ParsedAttrInfo.
144
+ if (A.getKind () < llvm::array_lengthof (AttrInfoMap))
145
+ return *AttrInfoMap[A.getKind ()];
146
+
147
+ static ParsedAttrInfo DefaultParsedAttrInfo;
148
+ return DefaultParsedAttrInfo;
130
149
}
131
150
132
151
unsigned ParsedAttr::getMinArgs () const { return getInfo (*this ).NumArgs ; }
@@ -140,7 +159,7 @@ bool ParsedAttr::hasCustomParsing() const {
140
159
}
141
160
142
161
bool ParsedAttr::diagnoseAppertainsTo (Sema &S, const Decl *D) const {
143
- return getInfo (*this ).DiagAppertainsToDecl (S, *this , D);
162
+ return getInfo (*this ).diagAppertainsToDecl (S, *this , D);
144
163
}
145
164
146
165
bool ParsedAttr::appliesToDecl (const Decl *D,
@@ -152,11 +171,11 @@ void ParsedAttr::getMatchRules(
152
171
const LangOptions &LangOpts,
153
172
SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool >> &MatchRules)
154
173
const {
155
- return getInfo (*this ).GetPragmaAttributeMatchRules (MatchRules, LangOpts);
174
+ return getInfo (*this ).getPragmaAttributeMatchRules (MatchRules, LangOpts);
156
175
}
157
176
158
177
bool ParsedAttr::diagnoseLangOpts (Sema &S) const {
159
- return getInfo (*this ).DiagLangOpts (S, *this );
178
+ return getInfo (*this ).diagLangOpts (S, *this );
160
179
}
161
180
162
181
bool ParsedAttr::isTargetSpecificAttr () const {
@@ -168,7 +187,7 @@ bool ParsedAttr::isTypeAttr() const { return getInfo(*this).IsType; }
168
187
bool ParsedAttr::isStmtAttr () const { return getInfo (*this ).IsStmt ; }
169
188
170
189
bool ParsedAttr::existsInTarget (const TargetInfo &Target) const {
171
- return getInfo (*this ).ExistsInTarget (Target);
190
+ return getInfo (*this ).existsInTarget (Target);
172
191
}
173
192
174
193
bool ParsedAttr::isKnownToGCC () const { return getInfo (*this ).IsKnownToGCC ; }
@@ -178,7 +197,7 @@ bool ParsedAttr::isSupportedByPragmaAttribute() const {
178
197
}
179
198
180
199
unsigned ParsedAttr::getSemanticSpelling () const {
181
- return getInfo (*this ).SpellingIndexToSemanticSpelling (*this );
200
+ return getInfo (*this ).spellingIndexToSemanticSpelling (*this );
182
201
}
183
202
184
203
bool ParsedAttr::hasVariadicArg () const {
0 commit comments