[PATCH] D13330: Implement __attribute__((unique_instantiation))
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 1 08:08:55 PDT 2015
aaron.ballman added a subscriber: aaron.ballman.
aaron.ballman added reviewers: rsmith, aaron.ballman.
================
Comment at: include/clang/Basic/Attr.td:1462
@@ +1461,3 @@
+def UniqueInstantiation : InheritableAttr {
+ let Spellings = [GCC<"unique_instantiation">];
+ let Subjects = SubjectList<[CXXRecord]>;
----------------
This is not a GCC attribute, so it should not be spelled as such. Since this only applies to C++ code, I would recommend a C++11 spelling (in the clang namespace). If you think this is something C++03 and earlier code would really benefit from, then you could also add a GNU-style spelling.
================
Comment at: include/clang/Basic/Attr.td:1464
@@ +1463,3 @@
+ let Subjects = SubjectList<[CXXRecord]>;
+ let Documentation = [Undocumented];
+}
----------------
Please, no undocumented attributes.
================
Comment at: include/clang/Basic/DiagnosticSemaKinds.td:2443
@@ -2442,1 +2442,3 @@
":must be between 1 and %2}2">;
+def err_unique_instantiation_wrong_decl : Error<
+ "unique_instantiation attribute on something that is not a explicit template declaration or instantiation.">;
----------------
Would this make more sense as an option in warn_attribute_wrong_decl_type instead? (there's an err_ version as well if you wish to keep this an error).
Also, please ensure that the attribute is quoted in the diagnostic -- it makes things less confusing for the user.
================
Comment at: lib/AST/ASTContext.cpp:8244
@@ -8242,2 +8243,3 @@
case TSK_ExplicitInstantiationDefinition:
- return GVA_StrongODR;
+ CTSD = dyn_cast<ClassTemplateSpecializationDecl>(FD->getDeclContext());
+ if (!CTSD || !CTSD->hasAttr<UniqueInstantiationAttr>())
----------------
I think this would be easier to read (and not have to hoist a declaration out of the switch) as:
```
if (const auto *CTSD = dyn_cast<>()) {
if (CTSD->hasAttr<>())
return GVA_StrongExternal;
}
return GVA_StrongODR;
```
================
Comment at: lib/AST/ASTContext.cpp:8353
@@ -8342,2 +8352,3 @@
case TSK_ExplicitInstantiationDefinition:
- return GVA_StrongODR;
+ CTSD = dyn_cast<ClassTemplateSpecializationDecl>(VD->getDeclContext());
+ if (!CTSD || !CTSD->hasAttr<UniqueInstantiationAttr>())
----------------
Similar suggestion here.
================
Comment at: lib/Sema/SemaDeclAttr.cpp:4535
@@ +4534,3 @@
+ const AttributeList &Attr) {
+ ClassTemplateSpecializationDecl *CTSD;
+ if ((CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))) {
----------------
The declaration does not need to be hoisted here.
================
Comment at: lib/Sema/SemaDeclAttr.cpp:4539
@@ +4538,3 @@
+ // by an ExplicitInstantiationDeclaration.
+ if (CTSD->getSpecializationKind() == TSK_ExplicitInstantiationDefinition) {
+ if (!CTSD->getPreviousDecl())
----------------
Why is this required as part of the feature design? It seems restrictive.
================
Comment at: lib/Sema/SemaDeclAttr.cpp:4546
@@ +4545,3 @@
+ // have performed the same check on the previous declaration here.
+ CXXRecordDecl *Previous = CTSD->getPreviousDecl();
+ if (Previous) {
----------------
Is this something that can be handled by mergeDeclAttribute()? I'm not certain how that interplays with templates specifically, but usually we do this sort of logic within a Sema::mergeFooAttr() function.
Repository:
rL LLVM
http://reviews.llvm.org/D13330
More information about the cfe-commits
mailing list