zahiraam updated this revision to Diff 200258.
zahiraam marked 2 inline comments as done.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D43576/new/
https://reviews.llvm.org/D43576
Files:
include/clang/AST/Decl.h
include/clang/AST/RecursiveASTVisitor.h
include/clang/Basic/Attr.td
include/clang/Basic/DeclNodes.td
include/clang/Sema/ParsedAttr.h
include/clang/Sema/Sema.h
lib/AST/Decl.cpp
lib/AST/DeclBase.cpp
lib/AST/DeclCXX.cpp
lib/CodeGen/CGDecl.cpp
lib/CodeGen/CodeGenModule.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
lib/Serialization/ASTCommon.cpp
test/Sema/ms-uuid-1.cpp
test/Sema/ms-uuid-2.cpp
utils/TableGen/ClangAttrEmitter.cpp
Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -321,12 +321,15 @@
OS << "\" << get" << getUpperName() << "().getAsString() << \"";
else if (type == "ParamIdx")
OS << "\" << get" << getUpperName() << "().getSourceIndex() << \"";
- else
+ else if (type == "DeclSpecUuidDecl *") {
+ OS << "\" << get" << getUpperName() << "() << \"";
+ } else
OS << "\" << get" << getUpperName() << "() << \"";
}
void writeDump(raw_ostream &OS) const override {
- if (type == "FunctionDecl *" || type == "NamedDecl *") {
+ if (type == "FunctionDecl *" || type == "NamedDecl *" ||
+ type == "DeclSpecUuidDecl *") {
OS << " OS << \" \";\n";
OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n";
} else if (type == "IdentifierInfo *") {
@@ -1296,6 +1299,9 @@
Ptr = llvm::make_unique<VariadicIdentifierArgument>(Arg, Attr);
else if (ArgName == "VersionArgument")
Ptr = llvm::make_unique<VersionArgument>(Arg, Attr);
+ else if (ArgName == "DeclSpecUuidDeclArgument")
+ Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "DeclSpecUuidDecl *");
+
if (!Ptr) {
// Search in reverse order so that the most-derived type is handled first.
Index: test/Sema/ms-uuid-2.cpp
===================================================================
--- /dev/null
+++ test/Sema/ms-uuid-2.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions -fms-compatibility -std=c++14 %s
+
+
+typedef struct _GUID
+{
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} GUID;
+
+// expected-error@+5 {{C++ requires a type specifier for all declarations}}
+// expected-error@+4 {{invalid digit 'a' in decimal constant}}
+// expected-error@+3 {{use of undeclared identifier 'def0'}}
+// expected-error@+2 {{invalid digit 'a' in decimal constant}}
+// expected-error@+1 {{expected ';' after top level declarator}}
+uuid(12345678-9abc-def0-1234-56789abcdef0) struct S2;
+
Index: test/Sema/ms-uuid-1.cpp
===================================================================
--- /dev/null
+++ test/Sema/ms-uuid-1.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions -fms-compatibility -std=c++14 %s
+// expected-no-diagnostics
+typedef struct _GUID {
+ int i;
+} IID;
+template <const IID *piid>
+class A {};
+
+struct
+ __declspec(uuid("{DDB47A6A-0F23-11D5-9109-00E0296B75D3}"))
+ S1 {};
+
+struct
+ __declspec(uuid("{DDB47A6A-0F23-11D5-9109-00E0296B75D3}"))
+ S2 {};
+
+struct __declspec(dllexport)
+ C1 : public A<&__uuidof(S1)> {};
+
+struct __declspec(dllexport)
+ C2 : public A<&__uuidof(S2)> {};
+int printf(const char *, ...);
+int main() {
+
+ if (&__uuidof(S1) == &__uuidof(S2))
+ printf("OK\n");
+ else
+ printf("ERROR\n");
+
+ return 0;
+}
Index: lib/Serialization/ASTCommon.cpp
===================================================================
--- lib/Serialization/ASTCommon.cpp
+++ lib/Serialization/ASTCommon.cpp
@@ -348,6 +348,7 @@
case Decl::ObjCProtocol:
case Decl::ObjCInterface:
case Decl::Empty:
+ case Decl::DeclSpecUuid:
return true;
// Never redeclarable.
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -630,6 +630,11 @@
return Inst;
}
+ Decl *
+ TemplateDeclInstantiator::VisitDeclSpecUuidDecl(DeclSpecUuidDecl *D) {
+ llvm_unreachable("DeclSpecUuidDecl cannot be instantiated");
+}
+
Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
bool IsTypeAlias) {
bool Invalid = false;
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -628,11 +628,12 @@
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
if (UuidAttrs.size() > 1)
return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
- UuidStr = UuidAttrs.back()->getGuid();
+ UuidStr = UuidAttrs.back()->getDeclSpecUuidDecl()->getSTLUuid()->getString();
}
return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UuidStr,
SourceRange(TypeidLoc, RParenLoc));
+
}
/// Build a Microsoft __uuidof expression with an expression operand.
@@ -651,7 +652,9 @@
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
if (UuidAttrs.size() > 1)
return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
- UuidStr = UuidAttrs.back()->getGuid();
+ UuidStr = UuidAttrs.back()->getDeclSpecUuidDecl()->getSTLUuid()->getString();
+ if (UuidStr.startswith("{") && UuidStr.endswith("}"))
+ UuidStr = UuidStr.drop_front().drop_back();
}
}
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -5399,9 +5399,12 @@
//===----------------------------------------------------------------------===//
UuidAttr *Sema::mergeUuidAttr(Decl *D, SourceRange Range,
- unsigned AttrSpellingListIndex, StringRef Uuid) {
- if (const auto *UA = D->getAttr<UuidAttr>()) {
- if (UA->getGuid().equals_lower(Uuid))
+ unsigned AttrSpellingListIndex,
+ DeclSpecUuidDecl *Uuid) {
+ if (auto *UA = D->getAttr<UuidAttr>()) {
+ if (UA->getDeclSpecUuidDecl()->getSTLUuid()->getString().equals_lower(
+ Uuid->getSTLUuid()->getString()) &&
+ declaresSameEntity(DeclToDeclSpecUuidDecl.find(D)->first, D))
return nullptr;
Diag(UA->getLocation(), diag::err_mismatched_uuid);
Diag(Range.getBegin(), diag::note_previous_uuid);
@@ -5446,6 +5449,16 @@
}
}
+ QualType ResTy;
+ StringLiteral *Stl = nullptr;
+ llvm::APInt Length(32, StrRef.size() + 1);
+ ResTy = S.getASTContext().adjustStringLiteralBaseType(
+ S.getASTContext().WideCharTy.withConst());
+ ResTy = S.getASTContext().getConstantArrayType(ResTy, Length,
+ ArrayType::Normal, 0);
+ Stl = StringLiteral::Create(S.getASTContext(), StrRef, StringLiteral::Ascii,
+ 0, ResTy, LiteralLoc);
+
// FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
// the only thing in the [] list, the [] too), and add an insertion of
// __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas
@@ -5455,8 +5468,15 @@
if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
+ DeclSpecUuidDecl *ArgDecl;
+
+ ArgDecl = DeclSpecUuidDecl::Create(S.getASTContext(), S.getFunctionLevelDeclContext(),
+ SourceLocation(), Stl);
+
+ S.DeclToDeclSpecUuidDecl[D] = ArgDecl;
+
UuidAttr *UA = S.mergeUuidAttr(D, AL.getRange(),
- AL.getAttributeSpellingListIndex(), StrRef);
+ AL.getAttributeSpellingListIndex(), ArgDecl);
if (UA)
D->addAttr(UA);
}
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2515,7 +2515,7 @@
NewAttr = nullptr;
else if (const auto *UA = dyn_cast<UuidAttr>(Attr))
NewAttr = S.mergeUuidAttr(D, UA->getRange(), AttrSpellingListIndex,
- UA->getGuid());
+ UA->getDeclSpecUuidDecl());
else if (const auto *SLHA = dyn_cast<SpeculativeLoadHardeningAttr>(Attr))
NewAttr = S.mergeSpeculativeLoadHardeningAttr(D, *SLHA);
else if (const auto *SLHA = dyn_cast<NoSpeculativeLoadHardeningAttr>(Attr))
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -2999,7 +2999,6 @@
Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
setDSOLocal(Entry);
}
-
// If there are two attempts to define the same mangled name, issue an
// error.
if (IsForDefinition && !Entry->isDeclaration()) {
Index: lib/CodeGen/CGDecl.cpp
===================================================================
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -108,6 +108,7 @@
case Decl::OMPCapturedExpr:
case Decl::OMPRequires:
case Decl::Empty:
+ case Decl::DeclSpecUuid:
// None of these decls require codegen support.
return;
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -1793,9 +1793,11 @@
if (Uuid && isStruct() && !getDeclContext()->isExternCContext() &&
!isDeclContextInNamespace(getDeclContext()) &&
((getName() == "IUnknown" &&
- Uuid->getGuid() == "00000000-0000-0000-C000-000000000046") ||
+ Uuid->getDeclSpecUuidDecl()->getSTLUuid()->getString() ==
+ "00000000-0000-0000-C000-000000000046") ||
(getName() == "IDispatch" &&
- Uuid->getGuid() == "00020400-0000-0000-C000-000000000046"))) {
+ Uuid->getDeclSpecUuidDecl()->getSTLUuid()->getString() ==
+ "00020400-0000-0000-C000-000000000046"))) {
if (getNumBases() > 0)
return false;
return true;
Index: lib/AST/DeclBase.cpp
===================================================================
--- lib/AST/DeclBase.cpp
+++ lib/AST/DeclBase.cpp
@@ -800,6 +800,7 @@
case OMPAllocate:
case OMPRequires:
case OMPCapturedExpr:
+ case DeclSpecUuid:
case Empty:
// Never looked up by name.
return 0;
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -4805,3 +4805,14 @@
ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) ExportDecl(nullptr, SourceLocation());
}
+
+ //===----------------------------------------------------------------------===//
+ // UuidDeclSpec Implementation
+ //===----------------------------------------------------------------------===//
+
+ DeclSpecUuidDecl *DeclSpecUuidDecl::Create(const ASTContext &C, DeclContext *DC,
+ SourceLocation IdLoc,
+ StringLiteral *stluuid) {
+ return new (C, DC) DeclSpecUuidDecl(DeclSpecUuid, DC, IdLoc, stluuid);
+ }
+
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -405,6 +405,8 @@
/// Source location for newly created implicit MSInheritanceAttrs
SourceLocation ImplicitMSInheritanceAttrLoc;
+ std::map<const Decl*, DeclSpecUuidDecl*> DeclToDeclSpecUuidDecl;
+
/// pragma clang section kind
enum PragmaClangSectionKind {
PCSK_Invalid = 0,
@@ -2578,7 +2580,7 @@
VisibilityAttr::VisibilityType Vis,
unsigned AttrSpellingListIndex);
UuidAttr *mergeUuidAttr(Decl *D, SourceRange Range,
- unsigned AttrSpellingListIndex, StringRef Uuid);
+ unsigned AttrSpellingListIndex, DeclSpecUuidDecl *Uuid);
DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range,
unsigned AttrSpellingListIndex);
DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
Index: include/clang/Sema/ParsedAttr.h
===================================================================
--- include/clang/Sema/ParsedAttr.h
+++ include/clang/Sema/ParsedAttr.h
@@ -36,6 +36,7 @@
class Expr;
class IdentifierInfo;
class LangOptions;
+class DeclSpecUuidDecl;
/// Represents information about a change in availability for
/// an entity, which is part of the encoding of the 'availability'
@@ -333,6 +334,16 @@
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
+ /// Constructor for __declspec(uuid) attribute.
+ ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ StringLiteral *stluuid, ParsedAttr::Syntax syntaxUsed)
+ : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+ ScopeLoc(scopeLoc), Invalid(false), HasParsedType(false),
+ SyntaxUsed(syntaxUsed), NumArgs(1) {
+ AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+ }
+
/// Type tag information is stored immediately following the arguments, if
/// any, at the end of the object. They are mutually exclusive with
/// availability slots.
@@ -806,6 +817,15 @@
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
getterId, setterId, syntaxUsed));
}
+
+ ParsedAttr *
+ createUuidDeclSpecAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ StringLiteral *stluuid, ParsedAttr::Syntax syntaxUsed) {
+ void *memory = allocate(sizeof(ParsedAttr));
+ return add(new (memory) ParsedAttr(attrName, attrRange, scopeName,
+ scopeLoc, stluuid, syntaxUsed));
+ }
};
class ParsedAttributesView {
@@ -905,6 +925,7 @@
/// is that this will become significantly more serious.
class ParsedAttributes : public ParsedAttributesView {
public:
+
ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
ParsedAttributes(const ParsedAttributes &) = delete;
@@ -1005,6 +1026,17 @@
return attr;
}
+ /// Add microsoft __delspec(uuid) attribute.
+ ParsedAttr *
+ addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName,
+ SourceLocation scopeLoc, StringLiteral *stluuid, ParsedAttr::Syntax syntaxUsed) {
+ ParsedAttr *attr =
+ pool.createUuidDeclSpecAttribute(attrName, attrRange, scopeName, scopeLoc,
+ stluuid, syntaxUsed);
+ addAtEnd(attr);
+ return attr;
+ }
+
private:
mutable AttributePool pool;
};
Index: include/clang/Basic/DeclNodes.td
===================================================================
--- include/clang/Basic/DeclNodes.td
+++ include/clang/Basic/DeclNodes.td
@@ -101,4 +101,5 @@
def OMPAllocate : Decl;
def OMPRequires : Decl;
def Empty : Decl;
+def DeclSpecUuid : Decl;
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -180,6 +180,7 @@
class VariadicExprArgument<string name> : Argument<name, 1>;
class VariadicStringArgument<string name> : Argument<name, 1>;
class VariadicIdentifierArgument<string name> : Argument<name, 1>;
+class DeclSpecUuidDeclArgument<string name, bit opt = 0> : Argument<name,opt>;
// Like VariadicUnsignedArgument except values are ParamIdx.
class VariadicParamIdxArgument<string name> : Argument<name, 1>;
@@ -2238,7 +2239,7 @@
def Uuid : InheritableAttr {
let Spellings = [Declspec<"uuid">, Microsoft<"uuid">];
- let Args = [StringArgument<"Guid">];
+ let Args = [DeclSpecUuidDeclArgument<"DeclSpecUuidDecl">];
let Subjects = SubjectList<[Record, Enum]>;
// FIXME: Allow expressing logical AND for LangOpts. Our condition should be:
// CPlusPlus && (MicrosoftExt || Borland)
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -1433,6 +1433,8 @@
DEF_TRAVERSE_DECL(EmptyDecl, {})
+DEF_TRAVERSE_DECL(DeclSpecUuidDecl, {})
+
DEF_TRAVERSE_DECL(FileScopeAsmDecl,
{ TRY_TO(TraverseStmt(D->getAsmString())); })
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -75,6 +75,7 @@
class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
+class DeclSpecUuidDecl;
/// A container of type source information.
///
@@ -4284,6 +4285,24 @@
static bool classofKind(Kind K) { return K == Empty; }
};
+class DeclSpecUuidDecl : public Decl {
+ StringLiteral *STLUuid;
+public:
+ static DeclSpecUuidDecl *Create(const ASTContext &C, DeclContext *DC,
+ SourceLocation IdLoc,
+ StringLiteral *stluuid);
+
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == DeclSpecUuid; }
+
+ DeclSpecUuidDecl(Kind DK, DeclContext *DC, SourceLocation IdLoc,
+ StringLiteral *stluuid)
+ : Decl (DK, DC, IdLoc), STLUuid(stluuid) {}
+
+ StringLiteral *getSTLUuid() { return STLUuid; }
+};
+
/// Insertion operator for diagnostics. This allows sending NamedDecl's
/// into a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits