On Sat, Mar 26, 2016 at 9:46 PM, David Majnemer via cfe-commits <cfe-commits@lists.llvm.org> wrote: > Author: majnemer > Date: Sat Mar 26 23:46:07 2016 > New Revision: 264529 > > URL: http://llvm.org/viewvc/llvm-project?rev=264529&view=rev > Log: > Improve the representation of CXXUuidofExpr > > Keep a pointer to the UuidAttr that the CXXUuidofExpr corresponds to. > This makes translating from __uuidof to the underlying constant a lot > more straightforward. > > Modified: > cfe/trunk/include/clang/AST/ExprCXX.h > cfe/trunk/lib/AST/ExprCXX.cpp > cfe/trunk/lib/AST/MicrosoftMangle.cpp > cfe/trunk/lib/CodeGen/CodeGenModule.cpp > cfe/trunk/lib/Sema/SemaExprCXX.cpp > > Modified: cfe/trunk/include/clang/AST/ExprCXX.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=264529&r1=264528&r2=264529&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/ExprCXX.h (original) > +++ cfe/trunk/include/clang/AST/ExprCXX.h Sat Mar 26 23:46:07 2016 > @@ -778,22 +778,23 @@ public: > class CXXUuidofExpr : public Expr { > private: > llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; > + const UuidAttr *UA; > SourceRange Range;
Looks like the serialization / deserialization code for this new member is missing? Does this correctly round-trip through AST files? > public: > - CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) > - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, > - false, Operand->getType()->isDependentType(), > - Operand->getType()->isInstantiationDependentType(), > - Operand->getType()->containsUnexpandedParameterPack()), > - Operand(Operand), Range(R) { } > - > - CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R) > - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, > - false, Operand->isTypeDependent(), > - Operand->isInstantiationDependent(), > - Operand->containsUnexpandedParameterPack()), > - Operand(Operand), Range(R) { } > + CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, const UuidAttr *UA, > + SourceRange R) > + : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, > + Operand->getType()->isDependentType(), > + Operand->getType()->isInstantiationDependentType(), > + Operand->getType()->containsUnexpandedParameterPack()), > + Operand(Operand), UA(UA), Range(R) {} > + > + CXXUuidofExpr(QualType Ty, Expr *Operand, const UuidAttr *UA, SourceRange > R) > + : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, > + Operand->isTypeDependent(), Operand->isInstantiationDependent(), > + Operand->containsUnexpandedParameterPack()), > + Operand(Operand), UA(UA), Range(R) {} > > CXXUuidofExpr(EmptyShell Empty, bool isExpr) > : Expr(CXXUuidofExprClass, Empty) { > @@ -830,7 +831,7 @@ public: > Operand = E; > } > > - StringRef getUuidAsStringRef(ASTContext &Context) const; > + StringRef getUuidAsStringRef() const; > > SourceLocation getLocStart() const LLVM_READONLY { return > Range.getBegin(); } > SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } > @@ -841,11 +842,6 @@ public: > return T->getStmtClass() == CXXUuidofExprClass; > } > > - /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve > to > - /// a single GUID. > - static const UuidAttr *GetUuidAttrOfType(QualType QT, > - bool *HasMultipleGUIDsPtr = > nullptr); > - > // Iterators > child_range children() { > if (isTypeOperand()) > > Modified: cfe/trunk/lib/AST/ExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=264529&r1=264528&r2=264529&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ExprCXX.cpp (original) > +++ cfe/trunk/lib/AST/ExprCXX.cpp Sat Mar 26 23:46:07 2016 > @@ -54,77 +54,8 @@ QualType CXXUuidofExpr::getTypeOperand(A > Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), > Quals); > } > > -// static > -const UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT, > - bool > *RDHasMultipleGUIDsPtr) { > - // Optionally remove one level of pointer, reference or array indirection. > - const Type *Ty = QT.getTypePtr(); > - if (QT->isPointerType() || QT->isReferenceType()) > - Ty = QT->getPointeeType().getTypePtr(); > - else if (QT->isArrayType()) > - Ty = Ty->getBaseElementTypeUnsafe(); > - > - const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); > - if (!RD) > - return nullptr; > - > - if (const UuidAttr *Uuid = RD->getMostRecentDecl()->getAttr<UuidAttr>()) > - return Uuid; > - > - // __uuidof can grab UUIDs from template arguments. > - if (const ClassTemplateSpecializationDecl *CTSD = > - dyn_cast<ClassTemplateSpecializationDecl>(RD)) { > - const TemplateArgumentList &TAL = CTSD->getTemplateArgs(); > - const UuidAttr *UuidForRD = nullptr; > - > - for (const TemplateArgument &TA : TAL.asArray()) { > - bool SeenMultipleGUIDs = false; > - > - const UuidAttr *UuidForTA = nullptr; > - if (TA.getKind() == TemplateArgument::Type) > - UuidForTA = GetUuidAttrOfType(TA.getAsType(), &SeenMultipleGUIDs); > - else if (TA.getKind() == TemplateArgument::Declaration) > - UuidForTA = > - GetUuidAttrOfType(TA.getAsDecl()->getType(), &SeenMultipleGUIDs); > - > - // If the template argument has a UUID, there are three cases: > - // - This is the first UUID seen for this RecordDecl. > - // - This is a different UUID than previously seen for this > RecordDecl. > - // - This is the same UUID than previously seen for this RecordDecl. > - if (UuidForTA) { > - if (!UuidForRD) > - UuidForRD = UuidForTA; > - else if (UuidForRD != UuidForTA) > - SeenMultipleGUIDs = true; > - } > - > - // Seeing multiple UUIDs means that we couldn't find a UUID > - if (SeenMultipleGUIDs) { > - if (RDHasMultipleGUIDsPtr) > - *RDHasMultipleGUIDsPtr = true; > - return nullptr; > - } > - } > - > - return UuidForRD; > - } > - > - return nullptr; > -} > - > -StringRef CXXUuidofExpr::getUuidAsStringRef(ASTContext &Context) const { > - StringRef Uuid; > - if (isTypeOperand()) > - Uuid = > CXXUuidofExpr::GetUuidAttrOfType(getTypeOperand(Context))->getGuid(); > - else { > - // Special case: __uuidof(0) means an all-zero GUID. > - Expr *Op = getExprOperand(); > - if (!Op->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) > - Uuid = CXXUuidofExpr::GetUuidAttrOfType(Op->getType())->getGuid(); > - else > - Uuid = "00000000-0000-0000-0000-000000000000"; > - } > - return Uuid; > +StringRef CXXUuidofExpr::getUuidAsStringRef() const { > + return UA ? UA->getGuid() : "00000000-0000-0000-0000-000000000000"; > } > > // CXXScalarValueInitExpr > > Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=264529&r1=264528&r2=264529&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original) > +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Sat Mar 26 23:46:07 2016 > @@ -1186,7 +1186,7 @@ void MicrosoftCXXNameMangler::mangleExpr > > // This CXXUuidofExpr is mangled as-if it were actually a VarDecl from > // const __s_GUID _GUID_{lower case UUID with underscores} > - StringRef Uuid = UE->getUuidAsStringRef(Context.getASTContext()); > + StringRef Uuid = UE->getUuidAsStringRef(); > std::string Name = "_GUID_" + Uuid.lower(); > std::replace(Name.begin(), Name.end(), '-', '_'); > > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=264529&r1=264528&r2=264529&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sat Mar 26 23:46:07 2016 > @@ -1454,7 +1454,7 @@ ConstantAddress CodeGenModule::GetAddrOf > const CXXUuidofExpr* E) { > // Sema has verified that IIDSource has a __declspec(uuid()), and that its > // well-formed. > - StringRef Uuid = E->getUuidAsStringRef(Context); > + StringRef Uuid = E->getUuidAsStringRef(); > std::string Name = "_GUID_" + Uuid.lower(); > std::replace(Name.begin(), Name.end(), '-', '_'); > > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=264529&r1=264528&r2=264529&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sat Mar 26 23:46:07 2016 > @@ -508,23 +508,60 @@ Sema::ActOnCXXTypeid(SourceLocation OpLo > return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc); > } > > +/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to > +/// a single GUID. > +static void > +getUuidAttrOfType(Sema &SemaRef, QualType QT, > + llvm::SmallSetVector<const UuidAttr *, 1> &UuidAttrs) { > + // Optionally remove one level of pointer, reference or array indirection. > + const Type *Ty = QT.getTypePtr(); > + if (QT->isPointerType() || QT->isReferenceType()) > + Ty = QT->getPointeeType().getTypePtr(); > + else if (QT->isArrayType()) > + Ty = Ty->getBaseElementTypeUnsafe(); > + > + const auto *RD = Ty->getAsCXXRecordDecl(); > + if (!RD) > + return; > + > + if (const auto *Uuid = RD->getMostRecentDecl()->getAttr<UuidAttr>()) { > + UuidAttrs.insert(Uuid); > + return; > + } > + > + // __uuidof can grab UUIDs from template arguments. > + if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) { > + const TemplateArgumentList &TAL = CTSD->getTemplateArgs(); > + for (const TemplateArgument &TA : TAL.asArray()) { > + const UuidAttr *UuidForTA = nullptr; > + if (TA.getKind() == TemplateArgument::Type) > + getUuidAttrOfType(SemaRef, TA.getAsType(), UuidAttrs); > + else if (TA.getKind() == TemplateArgument::Declaration) > + getUuidAttrOfType(SemaRef, TA.getAsDecl()->getType(), UuidAttrs); > + > + if (UuidForTA) > + UuidAttrs.insert(UuidForTA); > + } > + } > +} > + > /// \brief Build a Microsoft __uuidof expression with a type operand. > ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType, > SourceLocation TypeidLoc, > TypeSourceInfo *Operand, > SourceLocation RParenLoc) { > + const UuidAttr *UA = nullptr; > if (!Operand->getType()->isDependentType()) { > - bool HasMultipleGUIDs = false; > - if (!CXXUuidofExpr::GetUuidAttrOfType(Operand->getType(), > - &HasMultipleGUIDs)) { > - if (HasMultipleGUIDs) > - return ExprError(Diag(TypeidLoc, > diag::err_uuidof_with_multiple_guids)); > - else > - return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); > - } > + llvm::SmallSetVector<const UuidAttr *, 1> UuidAttrs; > + getUuidAttrOfType(*this, Operand->getType(), UuidAttrs); > + if (UuidAttrs.empty()) > + return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); > + if (UuidAttrs.size() > 1) > + return ExprError(Diag(TypeidLoc, > diag::err_uuidof_with_multiple_guids)); > + UA = UuidAttrs.back(); > } > > - return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, > + return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand, UA, > SourceRange(TypeidLoc, RParenLoc)); > } > > @@ -533,18 +570,20 @@ ExprResult Sema::BuildCXXUuidof(QualType > SourceLocation TypeidLoc, > Expr *E, > SourceLocation RParenLoc) { > + const UuidAttr *UA = nullptr; > if (!E->getType()->isDependentType()) { > - bool HasMultipleGUIDs = false; > - if (!CXXUuidofExpr::GetUuidAttrOfType(E->getType(), &HasMultipleGUIDs) && > - !E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { > - if (HasMultipleGUIDs) > - return ExprError(Diag(TypeidLoc, > diag::err_uuidof_with_multiple_guids)); > - else > + if (!E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) { > + llvm::SmallSetVector<const UuidAttr *, 1> UuidAttrs; > + getUuidAttrOfType(*this, E->getType(), UuidAttrs); > + if (UuidAttrs.empty()) > return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid)); > + if (UuidAttrs.size() > 1) > + return ExprError(Diag(TypeidLoc, > diag::err_uuidof_with_multiple_guids)); > + UA = UuidAttrs.back(); > } > } > > - return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E, > + return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E, UA, > SourceRange(TypeidLoc, RParenLoc)); > } > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits