From ddc2a53584f91b1fdcc466f1ea1345d97c428802 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 31 Oct 2013 21:23:20 +0000 Subject: [PATCH] Store a TypeArgument on an attribute as a TypeSourceInfo*, rather than as a QualType with a SourceLocation stashed alongside. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193803 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Attr.h | 1 + include/clang/Basic/Attr.td | 6 ++--- lib/Sema/SemaDecl.cpp | 3 --- lib/Sema/SemaDeclAttr.cpp | 40 +++++++++++++++++------------ tools/libclang/CIndex.cpp | 5 ++-- tools/libclang/IndexingContext.cpp | 8 +++--- utils/TableGen/ClangAttrEmitter.cpp | 38 ++++++++++++++++++++++----- 7 files changed, 65 insertions(+), 36 deletions(-) diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index e07e84a783..7dbf41350a 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_ATTR_H #include "clang/AST/AttrIterator.h" +#include "clang/AST/Decl.h" #include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/LLVM.h" diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 21c56c3520..8ff725b77a 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -435,8 +435,7 @@ def IBOutlet : InheritableAttr { def IBOutletCollection : InheritableAttr { let Spellings = [GNU<"iboutletcollection">]; - let Args = [TypeArgument<"Interface", 1>, SourceLocArgument<"InterfaceLoc">]; - let HasCustomParsing = 1; + let Args = [TypeArgument<"Interface", 1>]; } def Malloc : InheritableAttr { @@ -751,8 +750,7 @@ def VectorSize : TypeAttr { def VecTypeHint : InheritableAttr { let Spellings = [GNU<"vec_type_hint">]; - let Args = [TypeArgument<"TypeHint">, SourceLocArgument<"TypeLoc">]; - let HasCustomParsing = 1; + let Args = [TypeArgument<"TypeHint">]; } def Visibility : InheritableAttr { diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 35bb3a3168..c1cfd36fd1 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -128,9 +128,6 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const { /// determine whether the name refers to a type. If so, returns an /// opaque pointer (actually a QualType) corresponding to that /// type. Otherwise, returns NULL. -/// -/// If name lookup results in an ambiguity, this routine will complain -/// and then return NULL. ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS, bool isClassName, bool HasTrailingDot, diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index bfdf26aabd..09cc8becca 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -207,11 +207,16 @@ static inline bool isCFStringType(QualType T, ASTContext &Ctx) { return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); } +static unsigned getNumAttributeArgs(const AttributeList &Attr) { + // FIXME: Include the type in the argument list. + return Attr.getNumArgs() + Attr.hasParsedType(); +} + /// \brief Check if the attribute has exactly as many args as Num. May /// output an error. static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, - unsigned int Num) { - if (Attr.getNumArgs() != Num) { + unsigned Num) { + if (getNumAttributeArgs(Attr) != Num) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr.getName() << Num; return false; @@ -224,8 +229,8 @@ static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, /// \brief Check if the attribute has at least as many args as Num. May /// output an error. static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, - unsigned int Num) { - if (Attr.getNumArgs() < Num) { + unsigned Num) { + if (getNumAttributeArgs(Attr) < Num) { S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num; return false; } @@ -1352,10 +1357,10 @@ static void handleIBOutletCollection(Sema &S, Decl *D, } } - TypeSourceInfo *TSI = 0; - QualType QT = S.GetTypeFromParser(PT, &TSI); - SourceLocation QTLoc = - TSI ? TSI->getTypeLoc().getLocStart() : SourceLocation(); + TypeSourceInfo *QTLoc = 0; + QualType QT = S.GetTypeFromParser(PT, &QTLoc); + if (!QTLoc) + QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc()); // Diagnose use of non-object type in iboutletcollection attribute. // FIXME. Gnu attribute extension ignores use of builtin types in @@ -1369,7 +1374,7 @@ static void handleIBOutletCollection(Sema &S, Decl *D, } D->addAttr(::new (S.Context) - IBOutletCollectionAttr(Attr.getRange(), S.Context, QT, QTLoc, + IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc, Attr.getAttributeSpellingListIndex())); } @@ -2773,16 +2778,15 @@ static void handleWorkGroupSize(Sema &S, Decl *D, static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) { assert(Attr.getKind() == AttributeList::AT_VecTypeHint); - if (!checkAttributeNumArgs(S, Attr, 0)) - return; - if (!Attr.hasParsedType()) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr.getName() << 1; return; } - QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg()); + TypeSourceInfo *ParmTSI = 0; + QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI); + assert(ParmTSI && "no type source info for attribute argument"); if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() && (ParmType->isBooleanType() || @@ -2795,14 +2799,14 @@ static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) { if (Attr.getKind() == AttributeList::AT_VecTypeHint && D->hasAttr()) { VecTypeHintAttr *A = D->getAttr(); - if (A->getTypeHint() != ParmType) { + if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) { S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName(); return; } } D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context, - ParmType, Attr.getLoc())); + ParmTSI)); } SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range, @@ -4101,11 +4105,13 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, return; IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident; - QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL); + TypeSourceInfo *MatchingCTypeLoc = 0; + S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc); + assert(MatchingCTypeLoc && "no type source info for attribute argument"); D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind, - MatchingCType, + MatchingCTypeLoc, Attr.getLayoutCompatible(), Attr.getMustBeNull(), Attr.getAttributeSpellingListIndex())); diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 48c2ee3536..c30f937e1a 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -533,8 +533,9 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) { const IBOutletCollectionAttr *A = cast(cxcursor::getCursorAttr(Cursor)); if (const ObjCObjectType *ObjT = A->getInterface()->getAs()) - return Visit(cxcursor::MakeCursorObjCClassRef(ObjT->getInterface(), - A->getInterfaceLoc(), TU)); + return Visit(cxcursor::MakeCursorObjCClassRef( + ObjT->getInterface(), + A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU)); } // If pointing inside a macro definition, check if the token is an identifier diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp index 6dadd7291f..41ed6ea182 100644 --- a/tools/libclang/IndexingContext.cpp +++ b/tools/libclang/IndexingContext.cpp @@ -94,8 +94,10 @@ AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx) const IBOutletCollectionAttr * IBAttr = cast(IBInfo.A); + SourceLocation InterfaceLocStart = + IBAttr->getInterfaceLoc()->getTypeLoc().getLocStart(); IBInfo.IBCollInfo.attrInfo = &IBInfo; - IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(IBAttr->getInterfaceLoc()); + IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(InterfaceLocStart); IBInfo.IBCollInfo.objcClass = 0; IBInfo.IBCollInfo.classCursor = clang_getNullCursor(); QualType Ty = IBAttr->getInterface(); @@ -103,8 +105,8 @@ AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx) if (const ObjCInterfaceDecl *InterD = ObjectTy->getInterface()) { IdxCtx.getEntityInfo(InterD, IBInfo.ClassInfo, SA); IBInfo.IBCollInfo.objcClass = &IBInfo.ClassInfo; - IBInfo.IBCollInfo.classCursor = MakeCursorObjCClassRef(InterD, - IBAttr->getInterfaceLoc(), IdxCtx.CXTU); + IBInfo.IBCollInfo.classCursor = + MakeCursorObjCClassRef(InterD, InterfaceLocStart, IdxCtx.CXTU); } } } diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 40b113fb76..2f758f2a0c 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -47,7 +47,7 @@ static std::string ReadPCHRecord(StringRef type) { return StringSwitch(type) .EndsWith("Decl *", "GetLocalDeclAs<" + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])") - .Case("QualType", "getLocalType(F, Record[Idx++])") + .Case("TypeSourceInfo *", "GetTypeSourceInfo(F, Record, Idx)") .Case("Expr *", "ReadExpr(F)") .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)") .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)") @@ -59,7 +59,8 @@ static std::string WritePCHRecord(StringRef type, StringRef name) { return StringSwitch(type) .EndsWith("Decl *", "AddDeclRef(" + std::string(name) + ", Record);\n") - .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n") + .Case("TypeSourceInfo *", + "AddTypeSourceInfo(" + std::string(name) + ", Record);\n") .Case("Expr *", "AddStmt(" + std::string(name) + ");\n") .Case("IdentifierInfo *", "AddIdentifierRef(" + std::string(name) + ", Record);\n") @@ -185,10 +186,11 @@ namespace { } void writeValue(raw_ostream &OS) const { if (type == "FunctionDecl *") { - OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \""; + OS << "\" << get" << getUpperName() + << "()->getNameInfo().getAsString() << \""; } else if (type == "IdentifierInfo *") { OS << "\" << get" << getUpperName() << "()->getName() << \""; - } else if (type == "QualType") { + } else if (type == "TypeSourceInfo *") { OS << "\" << get" << getUpperName() << "().getAsString() << \""; } else if (type == "SourceLocation") { OS << "\" << get" << getUpperName() << "().getRawEncoding() << \""; @@ -203,7 +205,7 @@ namespace { } else if (type == "IdentifierInfo *") { OS << " OS << \" \" << SA->get" << getUpperName() << "()->getName();\n"; - } else if (type == "QualType") { + } else if (type == "TypeSourceInfo *") { OS << " OS << \" \" << SA->get" << getUpperName() << "().getAsString();\n"; } else if (type == "SourceLocation") { @@ -827,6 +829,29 @@ namespace { << "SA->" << getLowerName() << "_end()"; } }; + + class TypeArgument : public SimpleArgument { + public: + TypeArgument(Record &Arg, StringRef Attr) + : SimpleArgument(Arg, Attr, "TypeSourceInfo *") + {} + + void writeAccessors(raw_ostream &OS) const { + OS << " QualType get" << getUpperName() << "() const {\n"; + OS << " return " << getLowerName() << "->getType();\n"; + OS << " }"; + OS << " " << getType() << " get" << getUpperName() << "Loc() const {\n"; + OS << " return " << getLowerName() << ";\n"; + OS << " }"; + } + void writeTemplateInstantiationArgs(raw_ostream &OS) const { + OS << "A->get" << getUpperName() << "Loc()"; + } + void writePCHWrite(raw_ostream &OS) const { + OS << " " << WritePCHRecord( + getType(), "SA->get" + std::string(getUpperName()) + "Loc()"); + } + }; } static Argument *createArgument(Record &Arg, StringRef Attr, @@ -848,8 +873,7 @@ static Argument *createArgument(Record &Arg, StringRef Attr, "bool"); else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int"); else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr); - else if (ArgName == "TypeArgument") - Ptr = new SimpleArgument(Arg, Attr, "QualType"); + else if (ArgName == "TypeArgument") Ptr = new TypeArgument(Arg, Attr); else if (ArgName == "UnsignedArgument") Ptr = new SimpleArgument(Arg, Attr, "unsigned"); else if (ArgName == "SourceLocArgument") -- 2.40.0