aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
authorJoao Matos <ripzonetriton@gmail.com>2012-09-02 00:13:48 +0000
committerJoao Matos <ripzonetriton@gmail.com>2012-09-02 00:13:48 +0000
commitf712c48ce80763f3c0bbc2e1b0afe6ed3b5b88cb (patch)
tree402ee14c69810f4558de22d65bb80d064f53e572 /lib/Sema/SemaDeclAttr.cpp
parentc4f0f463fef75884063da5bde615f1f8a9d45b57 (diff)
Added a diagnostic for mismatched MS inheritance attributes. Also fixed the incomplete type member pointer size calculation under the MS ABI.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163078 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--lib/Sema/SemaDeclAttr.cpp54
1 files changed, 42 insertions, 12 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 50d1117599..bf1c14338d 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -4149,20 +4149,50 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
}
+static bool hasOtherInheritanceAttr(Decl *D, AttributeList::Kind Kind,
+ int& Existing) {
+ if (Kind != AttributeList::AT_SingleInheritance &&
+ D->hasAttr<SingleInheritanceAttr>()) {
+ Existing = 0;
+ return true;
+ }
+ else if (Kind != AttributeList::AT_MultipleInheritance &&
+ D->hasAttr<MultipleInheritanceAttr>()) {
+ Existing = 1;
+ return true;
+ }
+ else if (Kind != AttributeList::AT_VirtualInheritance &&
+ D->hasAttr<VirtualInheritanceAttr>()) {
+ Existing = 2;
+ return true;
+ }
+ return false;
+}
+
static void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
- if (S.LangOpts.MicrosoftExt) {
- AttributeList::Kind Kind = Attr.getKind();
- if (Kind == AttributeList::AT_SingleInheritance)
- D->addAttr(
- ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context));
- else if (Kind == AttributeList::AT_MultipleInheritance)
- D->addAttr(
- ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context));
- else if (Kind == AttributeList::AT_VirtualInheritance)
- D->addAttr(
- ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context));
- } else
+ if (!S.LangOpts.MicrosoftExt) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+ return;
+ }
+
+ AttributeList::Kind Kind = Attr.getKind();
+
+ int Existing;
+ if (hasOtherInheritanceAttr(D->getCanonicalDecl(), Kind, Existing)) {
+ S.Diag(Attr.getLoc(), diag::warn_ms_inheritance_already_declared) << Existing;
+ return;
+ }
+
+ if (Kind == AttributeList::AT_SingleInheritance) {
+ D->addAttr(
+ ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context));
+ } else if (Kind == AttributeList::AT_MultipleInheritance) {
+ D->addAttr(
+ ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context));
+ } else if (Kind == AttributeList::AT_VirtualInheritance) {
+ D->addAttr(
+ ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context));
+ }
}
static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {