zahiraam updated this revision to Diff 142516.
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/AttributeList.h
include/clang/Sema/Sema.h
lib/AST/Decl.cpp
lib/AST/DeclBase.cpp
lib/AST/DeclCXX.cpp
lib/Parse/ParseDecl.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
utils/TableGen/ClangAttrEmitter.cpp
Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -322,12 +322,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 *") {
@@ -1280,6 +1283,8 @@
Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "ParamIdx");
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: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -535,6 +535,15 @@
return Inst;
}
+Decl *
+TemplateDeclInstantiator::VisitDeclSpecUuidDecl(DeclSpecUuidDecl *D) {
+ DeclSpecUuidDecl *Inst = DeclSpecUuidDecl::Create(SemaRef.Context, Owner,
+ D->getLocation(),
+ D->getStrUuid());
+ Owner->addDecl(Inst);
+ return Inst;
+}
+
Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
bool IsTypeAlias) {
bool Invalid = false;
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -573,7 +573,7 @@
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()->getStrUuid();
}
return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UuidStr,
@@ -596,7 +596,8 @@
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()->getStrUuid();
+
}
}
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -4930,14 +4930,10 @@
//===----------------------------------------------------------------------===//
UuidAttr *Sema::mergeUuidAttr(Decl *D, SourceRange Range,
- unsigned AttrSpellingListIndex, StringRef Uuid) {
- if (const auto *UA = D->getAttr<UuidAttr>()) {
- if (UA->getGuid().equals_lower(Uuid))
- return nullptr;
- Diag(UA->getLocation(), diag::err_mismatched_uuid);
- Diag(Range.getBegin(), diag::note_previous_uuid);
- D->dropAttr<UuidAttr>();
- }
+ unsigned AttrSpellingListIndex,
+ DeclSpecUuidDecl *Uuid) {
+ if (D->getAttr<UuidAttr>())
+ return nullptr;
return ::new (Context) UuidAttr(Range, Context, Uuid, AttrSpellingListIndex);
}
@@ -4949,9 +4945,9 @@
return;
}
- StringRef StrRef;
- SourceLocation LiteralLoc;
- if (!S.checkStringLiteralArgumentAttr(AL, 0, StrRef, &LiteralLoc))
+ StringRef StrRef = AL.getUuidDecl()->getStrUuid();
+ SourceLocation LiteralLoc = AL.getLoc();
+ if (StrRef.empty())
return;
// GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
@@ -4987,7 +4983,9 @@
S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
UuidAttr *UA = S.mergeUuidAttr(D, AL.getRange(),
- AL.getAttributeSpellingListIndex(), StrRef);
+ AL.getAttributeSpellingListIndex(),
+ AL.getUuidDecl());
+
if (UA)
D->addAttr(UA);
}
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2495,7 +2495,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 (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -556,7 +556,32 @@
T.skipToEnd();
return !HasInvalidAccessor;
}
-
+ if (AttrName->getName() == "uuid") {
+ // Parse the uuid attribute and create a UuidDecl.
+ ConsumeParen();
+ assert(Tok.is(tok::string_literal) && "uuid not followed by string literal '('");
+ int sz = Tok.getLength();
+ SmallString<8> UuidBuffer;
+ bool Invalid = false;
+ StringRef UuidStr = PP.getSpelling(Tok, UuidBuffer, &Invalid);
+
+ // Clean up the string from the "\" at begining and at end.
+ StringRef UuidStr1 = UuidStr.ltrim('\"');
+ StringRef TrimmedUuidStr = UuidStr1.rtrim('\"');
+ DeclSpecUuidDecl *ArgDecl =
+ DeclSpecUuidDecl::Create(Actions.getASTContext(),
+ Actions.getFunctionLevelDeclContext(),
+ SourceLocation(),
+ TrimmedUuidStr);
+
+ // Advance to next token. Should be a r-paren.
+ PP.Lex(Tok);
+ SourceLocation RParen = Tok.getLocation();
+ SourceRange attrRange = SourceRange(AttrNameLoc, RParen);
+ if (!ExpectAndConsume(tok::r_paren))
+ Attrs.addNew(AttrName, attrRange, nullptr, AttrNameLoc, ArgDecl, AttributeList::AS_Declspec);
+ return true;
+ }
unsigned NumArgs =
ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,
SourceLocation(), AttributeList::AS_Declspec);
@@ -911,6 +936,7 @@
enum { Introduced, Deprecated, Obsoleted, Unknown };
AvailabilityChange Changes[Unknown];
ExprResult MessageExpr, ReplacementExpr;
+ Decl *DeclSpecUuidDecl = nullptr;
// Opening '('.
BalancedDelimiterTracker T(*this, tok::l_paren);
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -1724,9 +1724,9 @@
if (Uuid && isStruct() && !getDeclContext()->isExternCContext() &&
!isDeclContextInNamespace(getDeclContext()) &&
((getName() == "IUnknown" &&
- Uuid->getGuid() == "00000000-0000-0000-C000-000000000046") ||
+ Uuid->getDeclSpecUuidDecl()->getStrUuid() == "00000000-0000-0000-C000-000000000046") ||
(getName() == "IDispatch" &&
- Uuid->getGuid() == "00020400-0000-0000-C000-000000000046"))) {
+ Uuid->getDeclSpecUuidDecl()->getStrUuid() == "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
@@ -810,6 +810,7 @@
case OMPThreadPrivate:
case OMPCapturedExpr:
case Empty:
+ case DeclSpecUuid:
// Never looked up by name.
return 0;
}
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -4553,3 +4553,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,
+ StringRef UuidVal)
+{
+ return new (C, DC) DeclSpecUuidDecl(DeclSpecUuid, DC, IdLoc, UuidVal);
+}
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2417,7 +2417,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/AttributeList.h
===================================================================
--- include/clang/Sema/AttributeList.h
+++ include/clang/Sema/AttributeList.h
@@ -35,6 +35,7 @@
class Expr;
class IdentifierInfo;
class LangOptions;
+class DeclSpecUuidDecl;
/// \brief Represents information about a change in availability for
/// an entity, which is part of the encoding of the 'availability'
@@ -181,6 +182,8 @@
const Expr *MessageExpr;
+ DeclSpecUuidDecl *UuidDecl;
+
/// The next attribute in the current position.
AttributeList *NextInPosition = nullptr;
@@ -321,6 +324,16 @@
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
+ /// Constructor for __declspec(uuid) attribute.
+ AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ DeclSpecUuidDecl *uuid, AttributeList::Syntax syntaxUsed)
+ : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+ ScopeLoc(scopeLoc), Invalid(false), HasParsedType(false),
+ SyntaxUsed(syntaxUsed), NumArgs(1), UuidDecl(uuid) {
+ 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.
@@ -524,6 +537,11 @@
return getPropertyDataBuffer();
}
+ DeclSpecUuidDecl *getUuidDecl() const {
+ assert(getKind() == AT_Uuid && "Not an availability attribute");
+ return UuidDecl;
+ }
+
/// \brief Get an index into the attribute spelling list
/// defined in Attr.td. This index is used by an attribute
/// to pretty print itself.
@@ -577,6 +595,10 @@
PropertyAllocSize =
sizeof(AttributeList)
+ (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
+ / sizeof(void*) * sizeof(void*),
+ UuidDeclSpecSize =
+ sizeof(AttributeList)
+ + (sizeof(DeclSpecUuidDecl) + sizeof(void *) + sizeof(ArgsUnion) - 1)
/ sizeof(void*) * sizeof(void*)
};
@@ -744,6 +766,15 @@
getterId, setterId,
syntaxUsed));
}
+
+ AttributeList *
+ createUuidDeclSpecAttribute(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ DeclSpecUuidDecl *ArgDecl, AttributeList::Syntax syntaxUsed) {
+ void *memory = allocate(sizeof(AttributeList));
+ return add(new (memory) AttributeList(attrName, attrRange,
+ scopeName, scopeLoc, ArgDecl, syntaxUsed));
+ }
};
/// ParsedAttributes - A collection of parsed attributes. Currently
@@ -898,6 +929,18 @@
return attr;
}
+ /// Add microsoft __delspec(uuid) attribute.
+ AttributeList *
+ addNew(IdentifierInfo *attrName, SourceRange attrRange,
+ IdentifierInfo *scopeName, SourceLocation scopeLoc,
+ DeclSpecUuidDecl *ArgDecl, AttributeList::Syntax syntaxUsed) {
+ AttributeList *attr =
+ pool.createUuidDeclSpecAttribute(attrName, attrRange, scopeName,
+ scopeLoc, ArgDecl, syntaxUsed);
+ add(attr);
+ return attr;
+ }
+
private:
mutable AttributePool pool;
AttributeList *list = nullptr;
Index: include/clang/Basic/DeclNodes.td
===================================================================
--- include/clang/Basic/DeclNodes.td
+++ include/clang/Basic/DeclNodes.td
@@ -98,4 +98,5 @@
def Import : Decl;
def OMPThreadPrivate : Decl;
def Empty : Decl;
+def DeclSpecUuid : Decl;
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -172,6 +172,8 @@
// Like VariadicUnsignedArgument except values are ParamIdx.
class VariadicParamIdxArgument<string name> : Argument<name, 1>;
+class DeclSpecUuidDeclArgument<string name, bit opt = 0> : Argument<name,opt>;
+
// Like VariadicParamIdxArgument but for a single function parameter index.
class ParamIdxArgument<string name, bit opt = 0> : Argument<name, opt>;
@@ -2016,7 +2018,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
@@ -1416,6 +1416,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.
///
@@ -4238,6 +4239,22 @@
static bool classofKind(Kind K) { return K == Empty; }
};
+class DeclSpecUuidDecl : public Decl {
+ StringRef StrUuid;
+public:
+ static DeclSpecUuidDecl *Create(const ASTContext &C, DeclContext *DC,
+ SourceLocation IdLoc,
+ StringRef UuidVal);
+
+ 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, StringRef UuidVal)
+ : Decl (DK, DC, IdLoc), StrUuid(UuidVal) {}
+
+ StringRef getStrUuid() { return StrUuid; }
+};
+
/// 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]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits