@@ -110,13 +110,26 @@ struct ParsedAttrInfo {
110110 unsigned IsKnownToGCC : 1 ;
111111 unsigned IsSupportedByPragmaAttribute : 1 ;
112112
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+ }
120133};
121134
122135namespace {
@@ -126,7 +139,13 @@ namespace {
126139} // namespace
127140
128141static 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;
130149}
131150
132151unsigned ParsedAttr::getMinArgs () const { return getInfo (*this ).NumArgs ; }
@@ -140,7 +159,7 @@ bool ParsedAttr::hasCustomParsing() const {
140159}
141160
142161bool ParsedAttr::diagnoseAppertainsTo (Sema &S, const Decl *D) const {
143- return getInfo (*this ).DiagAppertainsToDecl (S, *this , D);
162+ return getInfo (*this ).diagAppertainsToDecl (S, *this , D);
144163}
145164
146165bool ParsedAttr::appliesToDecl (const Decl *D,
@@ -152,11 +171,11 @@ void ParsedAttr::getMatchRules(
152171 const LangOptions &LangOpts,
153172 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool >> &MatchRules)
154173 const {
155- return getInfo (*this ).GetPragmaAttributeMatchRules (MatchRules, LangOpts);
174+ return getInfo (*this ).getPragmaAttributeMatchRules (MatchRules, LangOpts);
156175}
157176
158177bool ParsedAttr::diagnoseLangOpts (Sema &S) const {
159- return getInfo (*this ).DiagLangOpts (S, *this );
178+ return getInfo (*this ).diagLangOpts (S, *this );
160179}
161180
162181bool ParsedAttr::isTargetSpecificAttr () const {
@@ -168,7 +187,7 @@ bool ParsedAttr::isTypeAttr() const { return getInfo(*this).IsType; }
168187bool ParsedAttr::isStmtAttr () const { return getInfo (*this ).IsStmt ; }
169188
170189bool ParsedAttr::existsInTarget (const TargetInfo &Target) const {
171- return getInfo (*this ).ExistsInTarget (Target);
190+ return getInfo (*this ).existsInTarget (Target);
172191}
173192
174193bool ParsedAttr::isKnownToGCC () const { return getInfo (*this ).IsKnownToGCC ; }
@@ -178,7 +197,7 @@ bool ParsedAttr::isSupportedByPragmaAttribute() const {
178197}
179198
180199unsigned ParsedAttr::getSemanticSpelling () const {
181- return getInfo (*this ).SpellingIndexToSemanticSpelling (*this );
200+ return getInfo (*this ).spellingIndexToSemanticSpelling (*this );
182201}
183202
184203bool ParsedAttr::hasVariadicArg () const {
0 commit comments