Sema::Sema(llvm::BumpPtrAllocator &Allocator,
const SourceManager&SourceMgr,
30Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits),
31PP(PP), ThisDeclInfo(nullptr), BriefCommand(nullptr),
32HeaderfileCommand(nullptr) {
39ThisDeclInfo =
new(Allocator)
DeclInfo;
57checkContainerDecl(BC);
69checkBlockCommandEmptyParagraph(Command);
70checkBlockCommandDuplicate(Command);
74checkReturnsCommand(Command);
75checkDeprecatedCommand(Command);
88 if(!involvesFunctionType())
90diag::warn_doc_param_not_attached_to_a_function_decl)
103 switch(
Comment->getCommandID()) {
104 caseCommandTraits::KCI_function:
105DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 1 : 0;
107 caseCommandTraits::KCI_functiongroup:
108DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 2 : 0;
110 caseCommandTraits::KCI_method:
111DiagSelect = !isObjCMethodDecl() ? 3 : 0;
113 caseCommandTraits::KCI_methodgroup:
114DiagSelect = !isObjCMethodDecl() ? 4 : 0;
116 caseCommandTraits::KCI_callback:
117DiagSelect = !isFunctionPointerVarDecl() ? 5 : 0;
124Diag(Comment->
getLocation(), diag::warn_doc_function_method_decl_mismatch)
126<< (DiagSelect-1) << (DiagSelect-1)
130voidSema::checkContainerDeclVerbatimLine(
constBlockCommandComment *Comment) {
131 constCommandInfo *Info = Traits.
getCommandInfo(Comment->getCommandID());
132 if(!Info->IsRecordLikeDeclarationCommand)
135 switch(Comment->getCommandID()) {
136 caseCommandTraits::KCI_class:
138(!isClassOrStructOrTagTypedefDecl() && !isClassTemplateDecl()) ? 1
143 if(DiagSelect && Comment->getCommandMarker() && isObjCInterfaceDecl())
146 caseCommandTraits::KCI_interface:
147DiagSelect = !isObjCInterfaceDecl() ? 2 : 0;
149 caseCommandTraits::KCI_protocol:
150DiagSelect = !isObjCProtocolDecl() ? 3 : 0;
152 caseCommandTraits::KCI_struct:
153DiagSelect = !isClassOrStructOrTagTypedefDecl() ? 4 : 0;
155 caseCommandTraits::KCI_union:
156DiagSelect = !isUnionDecl() ? 5 : 0;
163Diag(Comment->getLocation(), diag::warn_doc_api_container_decl_mismatch)
164<< Comment->getCommandMarker()
165<< (DiagSelect-1) << (DiagSelect-1)
166<< Comment->getSourceRange();
169voidSema::checkContainerDecl(
constBlockCommandComment *Comment) {
170 constCommandInfo *Info = Traits.
getCommandInfo(Comment->getCommandID());
171 if(!Info->IsRecordLikeDetailCommand || isRecordLikeDecl())
174 switch(Comment->getCommandID()) {
175 caseCommandTraits::KCI_classdesign:
178 caseCommandTraits::KCI_coclass:
181 caseCommandTraits::KCI_dependency:
184 caseCommandTraits::KCI_helper:
187 caseCommandTraits::KCI_helperclass:
190 caseCommandTraits::KCI_helps:
193 caseCommandTraits::KCI_instancesize:
196 caseCommandTraits::KCI_ownership:
199 caseCommandTraits::KCI_performance:
202 caseCommandTraits::KCI_security:
205 caseCommandTraits::KCI_superclass:
213Diag(Comment->getLocation(), diag::warn_doc_container_decl_mismatch)
214<< Comment->getCommandMarker()
216<< Comment->getSourceRange();
222 returnllvm::StringSwitch<ParamCommandPassDirection>(Arg)
233std::string ArgLower = Arg.lower();
243 const char*FixedName =
245Diag(ArgLocBegin, diag::warn_doc_param_spaces_in_direction)
248Diag(ArgLocBegin, diag::warn_doc_param_invalid_direction) << ArgRange;
268 auto*A =
new(Allocator)
276checkBlockCommandEmptyParagraph(Command);
288 if(!isTemplateOrSpecialization())
290diag::warn_doc_tparam_not_attached_to_a_template_decl)
304 auto*A =
new(Allocator)
308 if(!isTemplateOrSpecialization()) {
316 if(resolveTParamReference(Arg, TemplateParameters, &Position)) {
321Diag(ArgLocBegin, diag::warn_doc_tparam_duplicate)
323Diag(PrevCommand->
getLocation(), diag::note_doc_tparam_previous)
326PrevCommand = Command;
331Diag(ArgLocBegin, diag::warn_doc_tparam_not_found)
334 if(!TemplateParameters || TemplateParameters->
size() == 0)
337StringRef CorrectedName;
338 if(TemplateParameters->
size() == 1) {
342CorrectedName = II->
getName();
344CorrectedName = correctTypoInTParamReference(Arg, TemplateParameters);
347 if(!CorrectedName.empty()) {
348Diag(ArgLocBegin, diag::note_doc_tparam_name_suggestion)
357checkBlockCommandEmptyParagraph(Command);
366 return new(Allocator)
368getInlineCommandRenderKind(CommandName), Args);
373StringRef CommandName) {
380 unsignedCommandID) {
393 unsignedCommandID) {
397 Loc.getLocWithOffset(1 + CommandName.size()),
411 Block->setCloseName(CloseName, CloseNameLocBegin);
412 Block->setLines(Lines);
425checkFunctionDeclVerbatimLine(VL);
426checkContainerDeclVerbatimLine(VL);
439 boolIsSelfClosing) {
440Tag->setAttrs(Attrs);
441Tag->setGreaterLoc(GreaterLoc);
443Tag->setSelfClosing();
444 else if(!isHTMLEndTagForbidden(Tag->getTagName()))
445HTMLOpenTags.push_back(Tag);
453 if(isHTMLEndTagForbidden(TagName)) {
454Diag(HET->
getLocation(), diag::warn_doc_html_end_forbidden)
460 boolFoundOpen =
false;
462I = HTMLOpenTags.rbegin(),
E= HTMLOpenTags.rend();
464 if((*I)->getTagName() == TagName) {
470Diag(HET->
getLocation(), diag::warn_doc_html_end_unbalanced)
476 while(!HTMLOpenTags.empty()) {
478StringRef LastNotClosedTagName = HST->
getTagName();
479 if(LastNotClosedTagName == TagName) {
486 if(isHTMLEndTagOptional(LastNotClosedTagName))
489 boolOpenLineInvalid;
493 boolCloseLineInvalid;
498 if(OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine) {
499Diag(HST->
getLocation(), diag::warn_doc_html_start_end_mismatch)
504Diag(HST->
getLocation(), diag::warn_doc_html_start_end_mismatch)
507Diag(HET->
getLocation(), diag::note_doc_html_end_tag)
519resolveParamCommandIndexes(FC);
522 while(!HTMLOpenTags.empty()) {
524 if(isHTMLEndTagOptional(HST->
getTagName()))
527Diag(HST->
getLocation(), diag::warn_doc_html_missing_end_tag)
546Diag(DiagLoc, diag::warn_doc_block_command_empty_paragraph)
553voidSema::checkReturnsCommand(
constBlockCommandComment *Command) {
557assert(ThisDeclInfo &&
"should not call this check on a bare comment");
561 if(isObjCPropertyDecl())
563 if(involvesFunctionType()) {
565 "should have a valid return type");
575 caseDecl::CXXConstructor:
578 caseDecl::CXXDestructor:
582Diag(Command->getLocation(),
583diag::warn_doc_returns_attached_to_a_void_function)
584<< Command->getCommandMarker()
585<< Command->getCommandName(Traits)
587<< Command->getSourceRange();
592Diag(Command->getLocation(),
593diag::warn_doc_returns_not_attached_to_a_function_decl)
594<< Command->getCommandMarker()
595<< Command->getCommandName(Traits)
596<< Command->getSourceRange();
599voidSema::checkBlockCommandDuplicate(
constBlockCommandComment *Command) {
600 constCommandInfo *Info = Traits.
getCommandInfo(Command->getCommandID());
601 constBlockCommandComment *PrevCommand =
nullptr;
602 if(Info->IsBriefCommand) {
604BriefCommand = Command;
607PrevCommand = BriefCommand;
608}
else if(Info->IsHeaderfileCommand) {
609 if(!HeaderfileCommand) {
610HeaderfileCommand = Command;
613PrevCommand = HeaderfileCommand;
619StringRef PrevCommandName = PrevCommand->getCommandName(Traits);
620Diag(Command->getLocation(), diag::warn_doc_block_command_duplicate)
621<< Command->getCommandMarker()
623<< Command->getSourceRange();
624 if(CommandName == PrevCommandName)
625Diag(PrevCommand->getLocation(), diag::note_doc_block_command_previous)
626<< PrevCommand->getCommandMarker()
628<< PrevCommand->getSourceRange();
630Diag(PrevCommand->getLocation(),
631diag::note_doc_block_command_previous_alias)
632<< PrevCommand->getCommandMarker()
637voidSema::checkDeprecatedCommand(
constBlockCommandComment *Command) {
641assert(ThisDeclInfo &&
"should not call this check on a bare comment");
647 if(
D->hasAttr<DeprecatedAttr>() ||
648 D->hasAttr<AvailabilityAttr>() ||
649 D->hasAttr<UnavailableAttr>())
652Diag(Command->getLocation(), diag::warn_doc_deprecated_not_sync)
653<< Command->getSourceRange() << Command->getCommandMarker();
656 if(
constFunctionDecl *FD = dyn_cast<FunctionDecl>(
D)) {
659 constDeclContext *Ctx = FD->getDeclContext();
660 if((!Ctx || !Ctx->isRecord()) &&
661FD->doesThisDeclarationHaveABody())
664 constLangOptions &LO = FD->getLangOpts();
665 const boolDoubleSquareBracket = LO.CPlusPlus14 || LO.C23;
666StringRef AttributeSpelling =
667DoubleSquareBracket ?
"[[deprecated]]":
"__attribute__((deprecated))";
673 if(DoubleSquareBracket) {
674TokenValue Tokens[] = {tok::l_square, tok::l_square,
676tok::r_square, tok::r_square};
678 if(!MacroName.empty())
679AttributeSpelling = MacroName;
682 if(MacroName.empty()) {
683TokenValue Tokens[] = {
684tok::kw___attribute, tok::l_paren,
686tok::r_paren, tok::r_paren};
687StringRef MacroName =
689 if(!MacroName.empty())
690AttributeSpelling = MacroName;
694SmallString<64> TextToInsert = AttributeSpelling;
695TextToInsert +=
" ";
696SourceLocation
Loc= FD->getSourceRange().getBegin();
697Diag(
Loc, diag::note_add_deprecation_attr)
702voidSema::resolveParamCommandIndexes(
constFullComment *FC) {
703 if(!involvesFunctionType()) {
709SmallVector<ParamCommandComment *, 8> UnresolvedParamCommands;
713SmallVector<ParamCommandComment *, 8> ParamVarDocs;
715ArrayRef<const ParmVarDecl *> ParamVars = getParamVars();
716ParamVarDocs.resize(ParamVars.size(),
nullptr);
721ParamCommandComment *PCC = dyn_cast<ParamCommandComment>(*I);
722 if(!PCC || !PCC->hasParamName())
724StringRef ParamName = PCC->getParamNameAsWritten();
727 const unsignedResolvedParamIndex = resolveParmVarReference(ParamName,
730PCC->setIsVarArgParam();
734UnresolvedParamCommands.push_back(PCC);
737PCC->setParamIndex(ResolvedParamIndex);
738 if(ParamVarDocs[ResolvedParamIndex]) {
739SourceRange ArgRange = PCC->getParamNameRange();
740Diag(ArgRange.getBegin(), diag::warn_doc_param_duplicate)
741<< ParamName << ArgRange;
742ParamCommandComment *PrevCommand = ParamVarDocs[ResolvedParamIndex];
743Diag(PrevCommand->getLocation(), diag::note_doc_param_previous)
744<< PrevCommand->getParamNameRange();
746ParamVarDocs[ResolvedParamIndex] = PCC;
750SmallVector<const ParmVarDecl *, 8> OrphanedParamDecls;
751 for(
unsignedi = 0, e = ParamVarDocs.size(); i != e; ++i) {
752 if(!ParamVarDocs[i])
753OrphanedParamDecls.push_back(ParamVars[i]);
759 for(
unsignedi = 0, e = UnresolvedParamCommands.size(); i != e; ++i) {
760 constParamCommandComment *PCC = UnresolvedParamCommands[i];
762SourceRange ArgRange = PCC->getParamNameRange();
763StringRef ParamName = PCC->getParamNameAsWritten();
764Diag(ArgRange.getBegin(), diag::warn_doc_param_not_found)
765<< ParamName << ArgRange;
768 if(OrphanedParamDecls.size() == 0)
772 if(OrphanedParamDecls.size() == 1) {
775CorrectedParamIndex = 0;
778CorrectedParamIndex = correctTypoInParmVarReference(ParamName,
782 constParmVarDecl *CorrectedPVD = OrphanedParamDecls[CorrectedParamIndex];
783 if(
constIdentifierInfo *CorrectedII = CorrectedPVD->getIdentifier())
784Diag(ArgRange.getBegin(), diag::note_doc_param_name_suggestion)
785<< CorrectedII->getName()
791boolSema::involvesFunctionType() {
799boolSema::isFunctionDecl() {
807boolSema::isAnyFunctionDecl() {
808 returnisFunctionDecl() && ThisDeclInfo->
CurrentDecl&&
812boolSema::isFunctionOrMethodVariadic() {
820boolSema::isObjCMethodDecl() {
821 returnisFunctionDecl() && ThisDeclInfo->
CurrentDecl&&
825boolSema::isFunctionPointerVarDecl() {
831 if(
constVarDecl *VD = dyn_cast_or_null<VarDecl>(ThisDeclInfo->
CurrentDecl)) {
832QualType QT = VD->getType();
833 returnQT->isFunctionPointerType();
839boolSema::isObjCPropertyDecl() {
847boolSema::isTemplateOrSpecialization() {
855boolSema::isRecordLikeDecl() {
860 returnisUnionDecl() || isClassOrStructDecl() || isObjCInterfaceDecl() ||
861isObjCProtocolDecl();
864boolSema::isUnionDecl() {
869 if(
constRecordDecl *RD =
870dyn_cast_or_null<RecordDecl>(ThisDeclInfo->
CurrentDecl))
871 returnRD->isUnion();
875 if(
auto*record = dyn_cast_or_null<RecordDecl>(
D))
876 return!record->isUnion();
881boolSema::isClassOrStructDecl() {
893boolSema::isClassOrStructOrTagTypedefDecl() {
905 if(
auto*ThisTypedefDecl = dyn_cast<TypedefDecl>(ThisDeclInfo->
CurrentDecl)) {
906 autoUnderlyingType = ThisTypedefDecl->getUnderlyingType();
907 if(
autoThisElaboratedType = dyn_cast<ElaboratedType>(UnderlyingType)) {
908 autoDesugaredType = ThisElaboratedType->desugar();
909 if(
auto*DesugaredTypePtr = DesugaredType.getTypePtrOrNull()) {
910 if(
auto*ThisRecordType = dyn_cast<RecordType>(DesugaredTypePtr)) {
920boolSema::isClassTemplateDecl() {
926(isa<ClassTemplateDecl>(ThisDeclInfo->
CurrentDecl));
929boolSema::isFunctionTemplateDecl() {
935(isa<FunctionTemplateDecl>(ThisDeclInfo->
CurrentDecl));
938boolSema::isObjCInterfaceDecl() {
944isa<ObjCInterfaceDecl>(ThisDeclInfo->
CurrentDecl);
947boolSema::isObjCProtocolDecl() {
953isa<ObjCProtocolDecl>(ThisDeclInfo->
CurrentDecl);
956ArrayRef<const ParmVarDecl *> Sema::getParamVars() {
962voidSema::inspectThisDecl() {
963ThisDeclInfo->
fill();
966unsignedSema::resolveParmVarReference(StringRef Name,
967ArrayRef<const ParmVarDecl *> ParamVars) {
968 for(
unsignedi = 0, e = ParamVars.size(); i != e; ++i) {
969 constIdentifierInfo *II = ParamVars[i]->getIdentifier();
970 if(II && II->getName() == Name)
973 if(Name ==
"..."&& isFunctionOrMethodVariadic())
979classSimpleTypoCorrector {
980 constNamedDecl *BestDecl;
983 const unsignedMaxEditDistance;
985 unsignedBestEditDistance;
990 explicitSimpleTypoCorrector(StringRef Typo)
991: BestDecl(nullptr), Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3),
992BestEditDistance(MaxEditDistance + 1), BestIndex(0), NextIndex(0) {}
994 voidaddDecl(
constNamedDecl *ND);
996 constNamedDecl *getBestDecl()
const{
997 if(BestEditDistance > MaxEditDistance)
1003 unsignedgetBestDeclIndex()
const{
1004assert(getBestDecl());
1009voidSimpleTypoCorrector::addDecl(
constNamedDecl *ND) {
1010 unsignedCurrIndex = NextIndex++;
1012 constIdentifierInfo *II = ND->getIdentifier();
1016StringRef Name = II->getName();
1017 unsignedMinPossibleEditDistance =
abs((
int)Name.size() - (
int)Typo.size());
1018 if(MinPossibleEditDistance > 0 &&
1019Typo.size() / MinPossibleEditDistance < 3)
1022 unsignedEditDistance = Typo.edit_distance(Name,
true, MaxEditDistance);
1023 if(EditDistance < BestEditDistance) {
1024BestEditDistance = EditDistance;
1026BestIndex = CurrIndex;
1031unsignedSema::correctTypoInParmVarReference(
1033ArrayRef<const ParmVarDecl *> ParamVars) {
1034SimpleTypoCorrector Corrector(Typo);
1035 for(
unsignedi = 0, e = ParamVars.size(); i != e; ++i)
1036Corrector.addDecl(ParamVars[i]);
1037 if(Corrector.getBestDecl())
1038 returnCorrector.getBestDeclIndex();
1044boolResolveTParamReferenceHelper(
1046 constTemplateParameterList *TemplateParameters,
1047SmallVectorImpl<unsigned> *Position) {
1048 for(
unsignedi = 0, e = TemplateParameters->size(); i != e; ++i) {
1049 constNamedDecl *Param = TemplateParameters->getParam(i);
1050 constIdentifierInfo *II = Param->getIdentifier();
1051 if(II && II->getName() == Name) {
1052Position->push_back(i);
1056 if(
constTemplateTemplateParmDecl *TTP =
1057dyn_cast<TemplateTemplateParmDecl>(Param)) {
1058Position->push_back(i);
1059 if(ResolveTParamReferenceHelper(Name, TTP->getTemplateParameters(),
1062Position->pop_back();
1069boolSema::resolveTParamReference(
1071 constTemplateParameterList *TemplateParameters,
1072SmallVectorImpl<unsigned> *Position) {
1074 if(!TemplateParameters)
1077 returnResolveTParamReferenceHelper(Name, TemplateParameters, Position);
1081voidCorrectTypoInTParamReferenceHelper(
1082 constTemplateParameterList *TemplateParameters,
1083SimpleTypoCorrector &Corrector) {
1084 for(
unsignedi = 0, e = TemplateParameters->size(); i != e; ++i) {
1085 constNamedDecl *Param = TemplateParameters->getParam(i);
1086Corrector.addDecl(Param);
1088 if(
constTemplateTemplateParmDecl *TTP =
1089dyn_cast<TemplateTemplateParmDecl>(Param))
1090CorrectTypoInTParamReferenceHelper(TTP->getTemplateParameters(),
1096StringRef Sema::correctTypoInTParamReference(
1098 constTemplateParameterList *TemplateParameters) {
1099SimpleTypoCorrector Corrector(Typo);
1100CorrectTypoInTParamReferenceHelper(TemplateParameters, Corrector);
1101 if(
constNamedDecl *ND = Corrector.getBestDecl()) {
1102 constIdentifierInfo *II = ND->getIdentifier();
1103assert(II &&
"SimpleTypoCorrector should not return this decl");
1104 returnII->getName();
1112 returnllvm::StringSwitch<InlineCommandRenderKind>(Name)
Defines the C++ template declaration subclasses.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::Preprocessor interface.
Defines the SourceManager interface.
__DEVICE__ long long abs(long long __n)
Decl - This represents one declaration (or definition), e.g.
Concrete class used by the front-end to report problems and issues.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const
Return the name of the macro defined before Loc that has spelling Tokens.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READONLY bool isWhitespace(unsigned char c)
Return true if this character is horizontal or vertical ASCII whitespace: ' ', '\t',...
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4